一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java 單向隊列及環形隊列的實現原理

Java 單向隊列及環形隊列的實現原理

2022-03-08 00:30沐雨橙風~~ Java教程

本文主要介紹了Java 單向隊列及環形隊列的實現原理,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

隊列的特點

1.可以使用數組和鏈表兩種方式來實現。

2.遵循先入先出(FIFO)的規則,即先進入的數據先出。

3.屬于有序列表。

圖解實現過程:

Java 單向隊列及環形隊列的實現原理

?1.定義一個固定長度的數組,長度為maxSize。

?2.設置兩個指針first = -1(指向隊列第一個數據的前一位,這樣保證在添加第一個數據以后頭指針為0,和數組的下標一樣,且用于操作出隊)和last = -1(指向隊尾,用于操作入隊)。

?3.即first會因為出隊操作而增加,last會因為入隊操作而增加

代碼實現:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package 隊列;
 
public class ArrayQueueTest {
    public static void main(String[] args) {
        ArrayQueue arrayQueue = new ArrayQueue(3);
        arrayQueue.addQueue("瓊");
        arrayQueue.addQueue("赟");
        arrayQueue.addQueue("瓏");
        arrayQueue.showAllQueueData();
        System.out.println(arrayQueue.getQueue());  
    }
}
class ArrayQueue{
    private int maxSize;//定義隊列的最大長度
    private int first ;//指向隊列頭的前一個位置!!前一個位置!!出隊方向
    private int last ;//指向隊列尾部!!即最后一個數據!!!入隊方向
    private String[] arr; //先建一個空的數組,具體長度未知,需要maxSize來確定。
    
    //構造器初始化隊列信息
    public ArrayQueue(int maxSize){
        this.maxSize = maxSize;
        this.first = -1;
        this.last = -1;
        arr = new String[maxSize];
    }
    
    //判斷是否為空
    public boolean isEmpty(){
        if (first == last) {
            System.out.println("隊列為空~~");
            return true;
        }else {
            System.out.println("隊列不為空~~");
            return false;
        }
    }
    
    //判斷隊列是否滿
    public boolean isFull(){
        if (last == maxSize-1) {
            System.out.println("隊列已滿~~");
            return true;
        }else {
            System.out.println("隊列未滿~~");
            return false;
        }
    }
    
    //入隊
    public void addQueue(String data){
        if (last == maxSize-1){
            System.out.println("隊列已滿,不能再添加!!");
            return;
        }else {
            last++; //添加數據只和末尾下標有關
            arr[last] = data;
            return;
        }
    }
    
    //出隊
    public String getQueue(){
        if (isEmpty()) {
            //因為getQueue方法是int型,需要返回數據,如果無數據,也需要返回
            //如果返回-1或者其他數據,會讓人誤解獲取到的數就是-1或者其他
            //所以用拋出異常來處理
            throw new RuntimeException("隊列為空,無數據~~");
        }
        else {
            first++;
            return arr[first];
        }
    }
    
    //遍歷隊列所有信息
    public void showAllQueueData(){
        if (first == last){
            return;
        }
        for (int i = 0; i < arr.length; i++) {
            System.out.println("arr["+i+"]"+"="+arr[i]);
        }
    }
    
    //獲取隊列頭數據
    public String headQueueData(){
        if (isEmpty()){
            throw new RuntimeException("無數據~~~");
        }
        return arr[++first];
    }
}

隊列缺點:

由于出隊操作,使得first指針上移變大,導致數組前面空出來的位置就不能再繼續添加數據,即不能再被重復使用,這樣一個隊列只能使用一次,內存效率太低,所以需要使用環形隊列來優化解決。

優化解決——環形隊列實現思路

1.first指針初始默認設置為0,指向隊列頭部,則arr[first] 就是第一個數據。

2.last指針初始默認也為0,但是會隨著增加數據而后移。

3.隊列滿的條件:

(last + 1) % maxSize == first

?last+1是為了讓指針后移,而且如果不設置為 last+1 那么一開始的時候last為0 , last % maxSize == 0,且first也為0,還沒加數據就滿了。

4.隊列為空的條件:

first == last

5.由于判斷是否滿的時候: last+1 ,導致實際上可以裝的數據比數組長度少 1

環形隊列各步驟及各方法實現講解

1.隊列初始化 :

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class CircleArryQueue{
    private int maxSize ; //數組長度,即隊列最大容量
    private int first;    //頭指針,控制出隊操作
    private int last;     //尾指針,控制入隊操作
    private int[] arr;    //數組類型,可以換其他的。
 
    //構造器初始化信息
    public CircleArryQueue(int maxSize){
        this.maxSize = maxSize;
        this.arr = new int[maxSize];
        this.first = 0;     //這兩個可以不加,不叫也是默認為0
        this.last = 0;
    }
}

2.判斷隊列是否為空:

?
1
2
3
4
public boolean isEmpty(){
       //頭指針和尾指針一樣 則說明為空
       return last == first;
   }

3.判斷隊列是否滿:

?
1
2
3
4
5
6
7
/*
*這里的 last+1 主要是為了讓指針后移,特別是在隊列尾部添加數據的時候,本來用last也可以判斷,但
*是一開始還沒加數據的時候,如果直接用last % maxSize == first,結果是true,所以為了解決指針后*移和判斷是否滿,用來last+1。其次,因為last+1可能會導致數組指針越界,所以用取模來控制它的范  * 圍,同時保證他會在一個固定的范圍循環變換,也利于環形隊列的實現。
*/
public boolean isFull(){
    return (last + 1) % maxSize == first;
}

4.添加數據到隊列尾部:入隊

?
1
2
3
4
5
6
7
8
9
10
public void pushData(int data){
    //先判斷是否滿了
    if(isFull()){
        System.out.println("隊列已經滿啦~~");
        return;
    }
    arr[last] = data;
    //last+1是為了后移,取模是為了避免指針越界,同時可以讓指針循環
    last = (last + 1) % maxSize;
}

5.取出隊首數據:出隊

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public int popData(){
        if (isEmpty()) {
            //拋異常就可以不用返回數據了
            new RuntimeException("隊列為空,沒有獲取到數據~~");
        }
    
        //要先把first對應的數組數據保存——>first后移——>返回數據
        int value = arr[first];
        //first+1的操作和last+1是一樣的,取模也是
        first = (first+1) % maxSize;
        System.out.println(value);
        return value;
        //如果不保存first指針 那么返回的數據就不對了
        //如果直接返回數據,那first指針還沒后移 也不對,所以需要使用第三方變量
    }

6.展示隊列中所有數據:

?
1
2
3
4
5
6
7
8
9
10
public void showAllData(){
        if (isEmpty()) {
            System.out.println("隊列為空,沒有數據~~");
            return;
        }
        //此處i不為0,是因為有可能之前有過popData()操作,使得firs不為0,所以最好使用
        //first給i動態賦值,
        for (int i = first; i < first+size() ; i++) {
            System.out.println("arr["+i%maxSize+"]"+arr[i%maxSize]);
        }

7.獲取隊列中數據的總個數:

?
1
2
3
4
public int dataNum(){
    //韓順平老師的教程上是這樣寫,但是我理解不了..........。
    return (last+maxSize-first) % maxSize;  
}

8.查看隊首數據但不彈出:

?
1
2
3
public void seeFirstData(){
    return arr[first];
}

全部代碼整合:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package 練習;
 
import java.util.Scanner;
 
public class CircleArryQueue {
    public static void main(String[] args){
        CircleQueue circleQueue = new CircleQueue(4);
        System.out.println("--------測試環形隊列--------");
        char key = ' ';
        Scanner scanner = new Scanner(System.in);
 
        boolean flag = true;
        while (flag){
            System.out.println("s(showAllData):查看隊列數據");
            System.out.println("p(pushData):隊尾添加數據");
            System.out.println("g(popData):彈出隊頭數據");
            System.out.println("h(seefirstData):獲取隊頭數據");
            System.out.println("e(exit):退出程序");
            key = scanner.next().charAt(0);
 
            switch (key){
                case 's':
                    circleQueue.showAllData();
                    break;
                case 'p':
                    System.out.println("輸入一個數據:");
                    int obj = scanner.nextInt();
                    circleQueue.pushData(obj);
                    break;
                case 'g':
                    circleQueue.popData();
                    break;
                case 'h':
                    circleQueue.seeFirstData();
                    break;
                case 'e':
                    scanner.close();
                    flag = false;
                    break;
                default:
                    break;
            }
 
        }
 
        System.out.println("程序結束~~~");
 
    }
 
}
 
class CircleQueue {
    private int maxSize ; //數組長度,即隊列最大容量
    private int first;    //頭指針,控制出隊操作
    private int last;     //尾指針,控制入隊操作
    private int[] arr;    //數組類型,可以換其他的。
 
    //構造器初始化信息
    public CircleQueue(int maxSize){
        this.maxSize = maxSize;
        this.arr = new int[maxSize];
        this.first = 0;     //這兩個可以不加,不叫也是默認為0
        this.last = 0;
    }
 
    public boolean isEmpty(){
        //頭指針和尾指針一樣 則說明為空
        return last == first;
    }
 
/*
*這里的 last+1 主要是為了讓指針后移,特別是在隊列尾部添加數據的時候,本來用last也可以判斷但
*是一開始還沒加數據的時候,如果直接用last % maxSize == first,結果是true,所以為了解決指針
*后移和判斷是否滿,用來last+1。其次,因為last+1可能會導致數組指針越界,所以用取模來控制它
*的范圍,同時保證他會在一個固定的范圍循環變換,也利于環形隊列的實現。
*/
    public boolean isFull(){
        return (last + 1) % maxSize == first;
    }
 
    public void pushData(int data){
        //先判斷是否滿了
        if(isFull()){
            System.out.println("隊列已經滿啦~~");
            return;
        }
        arr[last] = data;
        //last+1是為了后移,取模是為了避免指針越界,同時可以讓指針循環
        last = (last + 1) % maxSize;
    }
 
    public int popData(){
        if (isEmpty()) {
            //拋異常就可以不用返回數據了
            throw new RuntimeException("隊列為空,沒有獲取到數據~~");
        }
 
        //要先把first對應的數組數據保存——>first后移——>返回數據
        int value = arr[first];
        //first+1的操作和last+1是一樣的,取模也是
        first = (first+1) % maxSize;
        System.out.println(value);
        return value;
        //如果不保存first指針 那么返回的數據就不對了
        //如果直接返回數據,那first指針還沒后移 也不對,所以需要使用第三方變量
    }
    
    //查看所有數據
    public void showAllData(){
        if (isEmpty()) {
            System.out.println("隊列為空,沒有數據~~");
        }
        //此處i不為0,是因為有可能之前有過popData()操作,使得firs不為0,所以最好使用
        //first給i動態賦值,
        for (int i = first; i < first+dataNum() ; i++) {
            System.out.println("arr["+i%maxSize+"]"+arr[i%maxSize]);
        }
    }
    //查看有效數據個數
    public int dataNum(){
        //韓順平老師的教程上是這樣寫,但是我理解不了..........。
        return (last+maxSize-first) % maxSize;
    }
    //查看隊列第一個數據
    public int seeFirstData(){   
        System.out.println(arr[first]);
        return arr[first];
        
    }
}

最后:

部分內容參考自B站韓順平老師java數據結構課程

到此這篇關于Java 單向隊列及環形隊列的實現原理的文章就介紹到這了,更多相關Java 單向隊列及環形隊列內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://www.cnblogs.com/coding-996/p/12246672.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 欧美伊人影院 | 色综七七久久成人影 | 4虎影院永久地址www | 暖暖的视频完整视频韩国免费 | 十大网站免费货源 | 亚洲va久久久噜噜噜久久狠狠 | 大片毛片女女女女女女女 | 日本男女视频 | 成人午夜剧场 | 色先锋影音资源 | 国产亚洲精aa在线观看不卡 | 欧美亚洲影院 | 欧美大片一区 | 91av免费| 国产高清一区二区三区免费视频 | 98在线视频噜噜噜国产 | 向日葵视频app下载18岁以下勿看 | 超级乱淫伦小说1女多男 | 精品国产成人 | 欧美综合国产精品日韩一 | 成人国产在线观看 | 青青青在线观看国产精品 | 国产国语videosex另类 | 亚洲欧美午夜 | 欧美一卡2卡三卡4卡5卡免费观看 | 美女脱了内裤张开腿亲吻男生 | 99re8在线精品视频免费播放 | 免费人成在线观看69式小视频 | 60老妇性xxxxhd | 秋霞一级 | porno日本大学生高清 | 91视频免费观看网站 | 国内精品免费一区二区三区 | 亚洲美色综合天天久久综合精品 | 大陆男同志gayxxx | 色老板在线免费观看 | 欧美亚洲高清日韩成人 | 香蕉91 | 国产亚洲精品一区二区在线观看 | 99草视频| 亚洲国产欧美在线人成 |