天天看點

資料結構學習篇之隊列

(一)介紹

資料結構學習篇之隊列
          隊列(queue)是一種線性資料結構。與同為線性資料結構的棧不同的是隊列中的元素遵循的是先進先出(First In First Out)的規則,和在現實中排隊一樣,講究的是先來後到的原則。隊列出口端叫做隊頭(front),隊列的入口端叫做隊尾(rear)。

(二)基本操作

 (1)入隊

     (2)出隊

  (3)判斷隊列是否已空

(4)判斷隊列是否已滿

(5)擷取隊頭元素

I .入隊

資料結構學習篇之隊列
說明:就是通過rear的移動來實作元素的入隊,rear始終指向棧頂

II.出隊

資料結構學習篇之隊列
說明:出隊是在隊尾進行,通過left的移動來進行的

(三)代碼實作

package arrayqueue;

import java.util.Scanner;

/**
 * @author Jin
 * @ Date 2022年06月2022/6/29日0:08
 * 通過數組來實作隊列
 */
public class ArrayQueueRealize {
    public static void main(String[] args) {
        //建立一個對象
        ArrayQueue t1=new ArrayQueue(3);
        char key=' ';
        Scanner scanner=new Scanner(System.in);
        boolean loop=true;
        while(loop){
            System.out.println("s(show):顯示隊列");
            System.out.println("e(exit):退出程式");
            System.out.println("a(add):添加資料到隊列");
            System.out.println("g(get):從隊列取出資料");
            System.out.println("h(head):檢視隊列頭的資料");
            System.out.println("請輸入具體操作:");
            key =scanner.next().charAt(0);
            //接收一個字元
            switch(key){
                case's':t1.show();break;
                case'a':
                    System.out.println("輸出一個數");
                    int value =scanner.nextInt();
                    t1.addQueue(value);break;
                case'g':try{
                    int res=t1.getQueue();
                    System.out.printf("取出的資料是%d\n ",res);
                }catch(Exception e){
                    System.out.println(e.getMessage());
                }
                break;
                case'h':
                    try{
                        int res=t1.headQueue();
                        System.out.printf("隊列頭的資料是%d",res);

                    }catch(Exception e){
                        System.out.println(e.getMessage());
                    }
                    break;
                case'e':scanner.close();
                       loop=false;
                     break;
                default:break;
            }
        }
        System.out.println("程式退出!!!");
    }
}
/**使用數組模拟隊列---編寫一個ArrayQueue類*/
class ArrayQueue{
    public int maxSize;
    private int front;
    /**隊列頭*/
    private int rear;
    /**隊列尾*/
    private int[]arr;
    /*該數組用于存放資料,模拟隊列*/
    /**建立隊列的構造器(資料進行初始化)*/
    public ArrayQueue(int maxSize){
        this.maxSize=maxSize;
        arr=new int[maxSize];
        /*表示數組的最大容量*/
        front = -1;
        //指向隊列頭部,分析出front是指向隊列頭的前一個位置
        rear  = -1;
        //指向隊列尾,指向隊列尾的資料(即就是隊列的最後一個資料)
    }
    /**(1)判斷隊列是否滿*/
    public boolean isFull(){
            return rear==maxSize-1;
    }
    /**(2)判斷隊列是否為空*/
    public boolean isEmpty(){
        return rear==front;
    }
    /**(3)添加資料到隊列*/
    public  void addQueue(int n){
        //判斷隊列是否已經滿
        if(isFull()){
            System.out.println("隊列滿,不能加入資料!!");
        }
        rear++;//rear後移
        arr[rear]=n;
    }
    /**(4)擷取隊列的資料(出隊列)*/
    public int getQueue() {
        //判斷隊列是否是空的
        if (isEmpty()) {
            throw new RuntimeException("隊列空,不能取資料");
            //通過抛出異常
        }else{
            front++;//front後移
            int middle=arr[front];
            arr[front]=0;
            //取出後空間值置為0
            return middle;

        }

    }
    /**(5)顯示隊列的資料*/
    public  void show(){
        if(isEmpty()){
            System.out.println("隊列為空,沒有資料");
            return;
        }
        for (int i = 0; i < arr.length; i++) {
            System.out.printf("arr[%d]=%d  ",i,arr[i]);
        }
    }
    /**(6)顯示隊列的頭資料(并不取資料)*/
    public int headQueue(){
        if(isEmpty()){
            throw new RuntimeException("隊列空的,沒有資料");
        }
        return arr[front+1];
    }
}      

存在的問題??

由于隊列隻能在隊頭入隊,隊尾出隊,是以就限定了數組空間隻能使用一次,而不能夠重複利用

改進方案

資料結構學習篇之隊列

分析:

package arrayqueue;

import java.util.Scanner;

/**
 * @author Jin
 * @ Date 2022年06月2022/6/29日10:13
 */
public class CircleArrayQueue {
    public static void main(String[] args) {
        System.out.println("測試數組模拟環形隊列的案例~~~~");
        //建立一個對象
        ArrayQueue1 t1=new ArrayQueue1(4);
        char key=' ';
        Scanner scanner=new Scanner(System.in);
        boolean loop=true;
        while(loop){
            System.out.println("s(show):顯示隊列");
            System.out.println("e(exit):退出程式");
            System.out.println("a(add):添加資料到隊列");
            System.out.println("g(get):從隊列取出資料");
            System.out.println("h(head):檢視隊列頭的資料");
            System.out.println("請輸入具體操作:");
            key =scanner.next().charAt(0);
            //接收一個字元
            switch(key){
                case's':t1.show();break;
                case'a':
                    System.out.println("輸出一個數");
                    int value =scanner.nextInt();
                    t1.addQueue(value);break;
                case'g':try{
                    int res=t1.getQueue();
                    System.out.printf("取出的資料是%d\n ",res);
                }catch(Exception e){
                    System.out.println(e.getMessage());
                }
                    break;
                case'h':
                    try{
                        int res=t1.headQueue();
                        System.out.printf("隊列頭的資料是%d",res);

                    }catch(Exception e){
                        System.out.println(e.getMessage());
                    }
                    break;
                case'e':scanner.close();
                    loop=false;
                    break;
                default:break;
            }
        }
        System.out.println("程式退出!!!");
    }
}
/**使用數組模拟隊列---編寫一個ArrayQueue類*/
class ArrayQueue1{
    public int maxSize;
    private int front;
    /**隊列頭*/
    private int rear;
    /**隊列尾*/
    private int[]arr;
    /*該數組用于存放資料,模拟隊列*/
    /**建立隊列的構造器(資料進行初始化)*/
    public ArrayQueue1(int maxSize){
        this.maxSize=maxSize;
        arr=new int[maxSize];
        /*表示數組的最大容量*/
        front = 0;
        //指向隊列頭部,分析出front是指向隊列頭的第一個位置
        rear  = 0;
        //指向隊列尾,指向隊列尾的資料的後一個位置
    }
    /**(1)判斷隊列是否滿*/
    public boolean isFull(){
        return (rear+1)%maxSize==front;
    }
    /**(2)判斷隊列是否為空*/
    public boolean isEmpty(){
        return rear==front;
    }
    /**(3)添加資料到隊列*/
    public  void addQueue(int n){
        //判斷隊列是否已經滿
        if(isFull()){
            System.out.println("隊列滿,不能加入資料!!");
        }
        arr[rear]=n;
        //先添加資料
        rear=(rear+1)%maxSize;
        //rear後移,防止rear越界
    }
    /**(4)擷取隊列的資料(出隊列)*/
    public int getQueue() {
        //判斷隊列是否是空的
        if (isEmpty()) {
            throw new RuntimeException("隊列空,不能取資料");
            //通過抛出異常
        }else{
            //這裡需要分析出front是指向隊列的第一個元素
            //(1)先把front對應的值保留到一個臨時變量
            //(2)将front後移,考慮取模
            //(3)将臨時儲存的變量傳回
            int value=arr[front];
            front=(front+1)%maxSize;
            return value;
        }

    }
    /**(5)顯示隊列的資料*/
    public  void show(){
        if(isEmpty()){
            System.out.println("隊列為空,沒有資料");
            return;
        }
        //從front開始周遊,周遊多少個元素
        for (int i = front; i < front+getMaxSize(); i++) {
            System.out.printf("arr[%d]=%d  ",i%maxSize,arr[i%maxSize]);
        }
    }
    //求出目前隊列的有效資料
    public int getMaxSize(){
        return (rear-front+maxSize)%maxSize;
    }

    /**(6)顯示隊列的頭資料(并不取資料)*/
    public int headQueue(){
        if(isEmpty()){
            throw new RuntimeException("隊列空的,沒有資料");
        }
        return arr[front];
    }
}      

繼續閱讀