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

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

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

服務(wù)器之家 - 編程語言 - Java教程 - Java 單向隊列及環(huán)形隊列的實現(xiàn)原理

Java 單向隊列及環(huán)形隊列的實現(xiàn)原理

2022-03-08 00:30沐雨橙風(fēng)~~ Java教程

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

隊列的特點(diǎn)

1.可以使用數(shù)組和鏈表兩種方式來實現(xiàn)。

2.遵循先入先出(FIFO)的規(guī)則,即先進(jìn)入的數(shù)據(jù)先出。

3.屬于有序列表。

圖解實現(xiàn)過程:

Java 單向隊列及環(huán)形隊列的實現(xiàn)原理

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

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

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

代碼實現(xiàn):

?
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 ;//指向隊列頭的前一個位置??!前一個位置?。〕鲫牱较?/code>
    private int last ;//指向隊列尾部!!即最后一個數(shù)據(jù)?。?!入隊方向
    private String[] arr; //先建一個空的數(shù)組,具體長度未知,需要maxSize來確定。
    
    //構(gòu)造器初始化隊列信息
    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++; //添加數(shù)據(jù)只和末尾下標(biāo)有關(guān)
            arr[last] = data;
            return;
        }
    }
    
    //出隊
    public String getQueue(){
        if (isEmpty()) {
            //因為getQueue方法是int型,需要返回數(shù)據(jù),如果無數(shù)據(jù),也需要返回
            //如果返回-1或者其他數(shù)據(jù),會讓人誤解獲取到的數(shù)就是-1或者其他
            //所以用拋出異常來處理
            throw new RuntimeException("隊列為空,無數(shù)據(jù)~~");
        }
        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]);
        }
    }
    
    //獲取隊列頭數(shù)據(jù)
    public String headQueueData(){
        if (isEmpty()){
            throw new RuntimeException("無數(shù)據(jù)~~~");
        }
        return arr[++first];
    }
}

隊列缺點(diǎn):

由于出隊操作,使得first指針上移變大,導(dǎo)致數(shù)組前面空出來的位置就不能再繼續(xù)添加數(shù)據(jù),即不能再被重復(fù)使用,這樣一個隊列只能使用一次,內(nèi)存效率太低,所以需要使用環(huán)形隊列來優(yōu)化解決。

優(yōu)化解決——環(huán)形隊列實現(xiàn)思路

1.first指針初始默認(rèn)設(shè)置為0,指向隊列頭部,則arr[first] 就是第一個數(shù)據(jù)。

2.last指針初始默認(rèn)也為0,但是會隨著增加數(shù)據(jù)而后移。

3.隊列滿的條件:

(last + 1) % maxSize == first

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

4.隊列為空的條件:

first == last

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

環(huán)形隊列各步驟及各方法實現(xiàn)講解

1.隊列初始化 :

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class CircleArryQueue{
    private int maxSize ; //數(shù)組長度,即隊列最大容量
    private int first;    //頭指針,控制出隊操作
    private int last;     //尾指針,控制入隊操作
    private int[] arr;    //數(shù)組類型,可以換其他的。
 
    //構(gòu)造器初始化信息
    public CircleArryQueue(int maxSize){
        this.maxSize = maxSize;
        this.arr = new int[maxSize];
        this.first = 0;     //這兩個可以不加,不叫也是默認(rèn)為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 主要是為了讓指針后移,特別是在隊列尾部添加數(shù)據(jù)的時候,本來用last也可以判斷,但
*是一開始還沒加數(shù)據(jù)的時候,如果直接用last % maxSize == first,結(jié)果是true,所以為了解決指針后*移和判斷是否滿,用來last+1。其次,因為last+1可能會導(dǎo)致數(shù)組指針越界,所以用取模來控制它的范  * 圍,同時保證他會在一個固定的范圍循環(huán)變換,也利于環(huán)形隊列的實現(xiàn)。
*/
public boolean isFull(){
    return (last + 1) % maxSize == first;
}

4.添加數(shù)據(jù)到隊列尾部:入隊

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

5.取出隊首數(shù)據(jù):出隊

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

6.展示隊列中所有數(shù)據(jù):

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

7.獲取隊列中數(shù)據(jù)的總個數(shù):

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

8.查看隊首數(shù)據(jù)但不彈出:

?
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 練習(xí);
 
import java.util.Scanner;
 
public class CircleArryQueue {
    public static void main(String[] args){
        CircleQueue circleQueue = new CircleQueue(4);
        System.out.println("--------測試環(huán)形隊列--------");
        char key = ' ';
        Scanner scanner = new Scanner(System.in);
 
        boolean flag = true;
        while (flag){
            System.out.println("s(showAllData):查看隊列數(shù)據(jù)");
            System.out.println("p(pushData):隊尾添加數(shù)據(jù)");
            System.out.println("g(popData):彈出隊頭數(shù)據(jù)");
            System.out.println("h(seefirstData):獲取隊頭數(shù)據(jù)");
            System.out.println("e(exit):退出程序");
            key = scanner.next().charAt(0);
 
            switch (key){
                case 's':
                    circleQueue.showAllData();
                    break;
                case 'p':
                    System.out.println("輸入一個數(shù)據(jù):");
                    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("程序結(jié)束~~~");
 
    }
 
}
 
class CircleQueue {
    private int maxSize ; //數(shù)組長度,即隊列最大容量
    private int first;    //頭指針,控制出隊操作
    private int last;     //尾指針,控制入隊操作
    private int[] arr;    //數(shù)組類型,可以換其他的。
 
    //構(gòu)造器初始化信息
    public CircleQueue(int maxSize){
        this.maxSize = maxSize;
        this.arr = new int[maxSize];
        this.first = 0;     //這兩個可以不加,不叫也是默認(rèn)為0
        this.last = 0;
    }
 
    public boolean isEmpty(){
        //頭指針和尾指針一樣 則說明為空
        return last == first;
    }
 
/*
*這里的 last+1 主要是為了讓指針后移,特別是在隊列尾部添加數(shù)據(jù)的時候,本來用last也可以判斷但
*是一開始還沒加數(shù)據(jù)的時候,如果直接用last % maxSize == first,結(jié)果是true,所以為了解決指針
*后移和判斷是否滿,用來last+1。其次,因為last+1可能會導(dǎo)致數(shù)組指針越界,所以用取模來控制它
*的范圍,同時保證他會在一個固定的范圍循環(huán)變換,也利于環(huán)形隊列的實現(xiàn)。
*/
    public boolean isFull(){
        return (last + 1) % maxSize == first;
    }
 
    public void pushData(int data){
        //先判斷是否滿了
        if(isFull()){
            System.out.println("隊列已經(jīng)滿啦~~");
            return;
        }
        arr[last] = data;
        //last+1是為了后移,取模是為了避免指針越界,同時可以讓指針循環(huán)
        last = (last + 1) % maxSize;
    }
 
    public int popData(){
        if (isEmpty()) {
            //拋異常就可以不用返回數(shù)據(jù)了
            throw new RuntimeException("隊列為空,沒有獲取到數(shù)據(jù)~~");
        }
 
        //要先把first對應(yīng)的數(shù)組數(shù)據(jù)保存——>first后移——>返回數(shù)據(jù)
        int value = arr[first];
        //first+1的操作和last+1是一樣的,取模也是
        first = (first+1) % maxSize;
        System.out.println(value);
        return value;
        //如果不保存first指針 那么返回的數(shù)據(jù)就不對了
        //如果直接返回數(shù)據(jù),那first指針還沒后移 也不對,所以需要使用第三方變量
    }
    
    //查看所有數(shù)據(jù)
    public void showAllData(){
        if (isEmpty()) {
            System.out.println("隊列為空,沒有數(shù)據(jù)~~");
        }
        //此處i不為0,是因為有可能之前有過popData()操作,使得firs不為0,所以最好使用
        //first給i動態(tài)賦值,
        for (int i = first; i < first+dataNum() ; i++) {
            System.out.println("arr["+i%maxSize+"]"+arr[i%maxSize]);
        }
    }
    //查看有效數(shù)據(jù)個數(shù)
    public int dataNum(){
        //韓順平老師的教程上是這樣寫,但是我理解不了..........。
        return (last+maxSize-first) % maxSize;
    }
    //查看隊列第一個數(shù)據(jù)
    public int seeFirstData(){   
        System.out.println(arr[first]);
        return arr[first];
        
    }
}

最后:

部分內(nèi)容參考自B站韓順平老師java數(shù)據(jù)結(jié)構(gòu)課程

到此這篇關(guān)于Java 單向隊列及環(huán)形隊列的實現(xiàn)原理的文章就介紹到這了,更多相關(guān)Java 單向隊列及環(huán)形隊列內(nèi)容請搜索服務(wù)器之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持服務(wù)器之家!

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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 强行扒开美女大腿挺进 | 91精品国产91热久久久久福利 | 亚洲国产第一区二区香蕉日日 | 热99re久久精品国产首页 | 加勒比京东热 | 日本加勒比在线播放 | 国产一级在线观看视频 | 欧美娇小性xxxx | 二次元美女扒开内裤露尿口 | 国产精品免费小视频 | 嫩草影院永久入口在线观看 | 成人18视频在线观看 | 国产成人一区二区三区小说 | 国产精品视频免费观看 | 水多多www视频在线观看高清 | 欧美不卡一区二区三区 | 范冰冰性xxxxhd | 精品精品国产自在久久高清 | 精品一成人岛国片在线观看 | 波多野结衣在线观看中文字幕 | av在线色| 91啦中文在线观看 | 亚洲国产视频网站 | 婷婷福利| 色悠久久久久综合网小说 | 夫妇交换小说全文阅读 | 国产成人影院一区二区 | 好男人好资源在线观看免费 | 日本xxxxx69hd日本 | 古代翁熄系小说辣文 | 成人午夜爽爽爽免费视频 | 亚洲国产精品二区久久 | 99精品国产自在现线观看 | 2018天天拍拍拍免费视频 | 日本免费一区二区三区四区五六区 | а天堂中文最新版在线 | 日本春菜花在线中文字幕 | 亚洲免费闲人蜜桃 | 色漫在线观看 | 精品一区二区三区在线成人 | 男生操女生的漫画 |