RM新时代网站-首页

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

你還會手寫棧和隊列嗎棧和隊列的基本實現(xiàn)程序說明

算法與數(shù)據(jù)結(jié)構(gòu) ? 來源:未知 ? 作者:易水寒 ? 2018-11-11 11:34 ? 次閱讀

昨天跟一個CSDN上的朋友聊天,他說現(xiàn)在如果讓他自己手寫一個?;蛘哧犃?,估計都要寫蠻久的,平時雖然都在用,但是都是別人封裝好的集合。

確實,經(jīng)典的數(shù)據(jù)結(jié)構(gòu),包括排序算法,雖然我們平時不用手寫了,但是這些內(nèi)功,作為開發(fā)人員來說是必須要掌握的。受此啟發(fā),我打算更一下經(jīng)典數(shù)據(jù)結(jié)構(gòu)和算法的系列文章。今天先從棧和隊列說起。

這些東西,擠地鐵時,吃飯排隊時,等公交時,可以拿來看看,或者,就把它當(dāng)作個下午茶吧~

我們知道,在數(shù)組中,若知道數(shù)據(jù)項的下標(biāo),便可立即訪問該數(shù)據(jù)項,或者通過順序搜索數(shù)據(jù)項,訪問到數(shù)組中的各個數(shù)據(jù)項。但是棧和隊列不同,它們的訪問是受限制的,即在特定時刻只有一個數(shù)據(jù)項可以被讀取或者被刪除。眾所周知,棧是先進(jìn)后出,只能訪問棧頂?shù)臄?shù)據(jù),隊列是先進(jìn)先出,只能訪問頭部數(shù)據(jù)。這里不再贅述。

棧的主要機制可以用數(shù)組來實現(xiàn),也可以用鏈表來實現(xiàn),下面用數(shù)組來實現(xiàn)棧的基本操作:

classArrayStack{

privatelong[] a;

privateint size;//棧數(shù)組的大小

privateint top;//棧頂

publicArrayStack(int maxSize){

this.size = maxSize;

this.a =newlong[size];

this.top =-1;//表示空棧

}

publicvoid push(long value){//入棧

if(isFull()){

System.out.println("棧已滿!");

return;

}

a[++top]= value;

}

publiclong peek(){//返回棧頂內(nèi)容,但不刪除

if(isEmpty()){

System.out.println("棧中沒有數(shù)據(jù)");

return0;

}

return a[top];

}

publiclong pop(){//彈出棧頂內(nèi)容,刪除

if(isEmpty()){

System.out.println("棧中沒有數(shù)據(jù)!");

return0;

}

return a[top--];

}

publicint size(){

return top +1;

}

publicboolean isEmpty(){

return(top ==-1);

}

publicboolean isFull(){

return(top == size -1);

}

publicvoid display(){

for(int i = top; i >=0; i--){

System.out.print(a[i]+" ");

}

System.out.println("");

}

}

數(shù)據(jù)項入棧和出棧的時間復(fù)雜度均為O(1)。這也就是說,棧操作所消耗的時間不依賴于棧中數(shù)據(jù)項的個數(shù),因此操作時間很短。棧不需要比較和移動操作。

隊列也可以用數(shù)組來實現(xiàn),不過這里有個問題,當(dāng)數(shù)組下標(biāo)滿了后就不能再添加了,但是數(shù)組前面由于已經(jīng)刪除隊列頭的數(shù)據(jù)了,導(dǎo)致空。所以隊列我們可以用循環(huán)數(shù)組來實現(xiàn),見下面的代碼:

publicclassRoundQueue{

privatelong[] a;

privateint size; //數(shù)組大小

privateint nItems;//實際存儲數(shù)量

privateint front;//頭

privateint rear; //尾

publicRoundQueue(int maxSize){

this.size = maxSize;

a =newlong[size];

front =0;

rear =-1;

nItems =0;

}

publicvoid insert(long value){

if(isFull()){

System.out.println("隊列已滿");

return;

}

rear =++rear % size;

a[rear]= value;//尾指針滿了就循環(huán)到0處,這句相當(dāng)于下面注釋內(nèi)容

nItems++;

/* if(rear == size-1){

rear = -1;

}

a[++rear] = value;

*/

}

publiclong remove(){

if(isEmpty()){

System.out.println("隊列為空!");

return0;

}

nItems--;

front = front % size;

return a[front++];

}

publicvoid display(){

if(isEmpty()){

System.out.println("隊列為空!");

return;

}

int item = front;

for(int i =0; i < nItems; i++){

System.out.print(a[item++% size]+" ");

}

System.out.println("");

}

publiclong peek(){

if(isEmpty()){

System.out.println("隊列為空!");

return0;

}

return a[front];

}

publicboolean isFull(){

return(nItems == size);

}

publicboolean isEmpty(){

return(nItems ==0);

}

publicint size(){

return nItems;

}

}

和棧一樣,隊列中插入數(shù)據(jù)項和刪除數(shù)據(jù)項的時間復(fù)雜度均為O(1)。

還有個優(yōu)先級隊列,優(yōu)先級隊列是比棧和隊列更專用的數(shù)據(jù)結(jié)構(gòu)。優(yōu)先級隊列與上面普通的隊列相比,主要區(qū)別在于隊列中的元素是有序的,關(guān)鍵字最?。ɑ蛘咦畲螅┑臄?shù)據(jù)項總在隊頭。數(shù)據(jù)項插入的時候會按照順序插入到合適的位置以確保隊列的順序。優(yōu)先級隊列的內(nèi)部實現(xiàn)可以用數(shù)組或者一種特別的樹——堆來實現(xiàn)。

publicclassPriorityQueue{

privatelong[] a;

privateint size;

privateint nItems;//元素個數(shù)

publicPriorityQueue(int maxSize){

size = maxSize;

nItems =0;

a =newlong[size];

}

publicvoid insert(long value){

if(isFull()){

System.out.println("隊列已滿!");

return;

}

int j;

if(nItems ==0){//空隊列直接添加

a[nItems++]= value;

}

else{//將數(shù)組中的數(shù)字依照下標(biāo)按照從大到小排列

for(j = nItems-1; j >=0; j--){

if(value > a[j]){

a[j+1]= a[j];

}

else{

break;

}

}

a[j+1]= value;

nItems++;

}

}

publiclong remove(){

if(isEmpty()){

System.out.println("隊列為空!");

return0;

}

return a[--nItems];

}

publiclong peekMin(){

return a[nItems-1];

}

publicboolean isFull(){

return(nItems == size);

}

publicboolean isEmpty(){

return(nItems ==0);

}

publicint size(){

return nItems;

}

publicvoid display(){

for(int i = nItems-1; i >=0; i--){

System.out.print(a[i]+" ");

}

System.out.println(" ");

}

}

這里實現(xiàn)的優(yōu)先級隊列中,插入操作需要 O(N) 的時間,而刪除操作則需要 O(1) 的時間。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 算法
    +關(guān)注

    關(guān)注

    23

    文章

    4607

    瀏覽量

    92826
  • 程序
    +關(guān)注

    關(guān)注

    117

    文章

    3785

    瀏覽量

    81001
  • 數(shù)據(jù)結(jié)構(gòu)

    關(guān)注

    3

    文章

    573

    瀏覽量

    40121

原文標(biāo)題:如果讓你手寫個棧和隊列,你還會寫嗎?

文章出處:【微信號:TheAlgorithm,微信公眾號:算法與數(shù)據(jù)結(jié)構(gòu)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    C語言|堆棧與隊列

    堆棧與隊列都是抽象的數(shù)據(jù)類型,注意堆和不是同一個概念,這里的堆棧指的是;是一種具有后進(jìn)先出的數(shù)據(jù)結(jié)構(gòu),又稱為后進(jìn)先出的線性表,簡稱 LIFO(Last In First Out)
    發(fā)表于 12-26 10:24 ?931次閱讀

    c++之隊列

    stack ,(堆棧),是一種先進(jìn)后出(First In Last Out,FILO)的數(shù)據(jù)結(jié)構(gòu),先插入的數(shù)據(jù)在底,后放入的數(shù)據(jù)在頂,所有的數(shù)據(jù)只能從頂取出。
    的頭像 發(fā)表于 07-15 08:50 ?943次閱讀
    c++之<b class='flag-5'>棧</b>和<b class='flag-5'>隊列</b>

    隊列與C++中的queue詳解

    隊列就是一種線性的數(shù)據(jù)結(jié)構(gòu),它與日常生活中排隊的隊列相似,即先進(jìn)先出(LIFO, First In First Out),這點也是它與(Stack)的最大不同之處。
    的頭像 發(fā)表于 07-18 17:31 ?1659次閱讀
    <b class='flag-5'>隊列</b>與C++中的queue詳解

    隊列以后出只有剛開始一組數(shù)出來,后續(xù)的就沒有了,怎么調(diào)了?有償

    隊列以后出只有剛開始一組數(shù)出來,后續(xù)的就沒有了,怎么調(diào)了?有償
    發(fā)表于 03-13 17:06

    隊列

    隊列:1、隊列定義:限定僅只能在表尾端進(jìn)行插入和刪除的線性表。頂:表尾端被稱之為頂。
    發(fā)表于 08-13 13:50 ?0次下載

    java中隊列的分析

    《p》《/p》《p》的英文單詞是Stack,它代表一種特殊的線性表,這種線性表只能在固定一端(通常認(rèn)為是線性表的尾端)進(jìn)行插入,刪除操作?!?p》《p》的基本定義《/p》《p》
    發(fā)表于 09-28 15:38 ?0次下載

    什么是?數(shù)據(jù)結(jié)構(gòu)中如何實現(xiàn)

    今天放松一下,我們來看看數(shù)據(jù)結(jié)構(gòu)中的,這節(jié)的知識點可以說是數(shù)據(jù)結(jié)構(gòu)中最容易上手的知識點了,其實比起鏈表,其實鏈表也有隊列的模型,鏈表的頭插其實就是后進(jìn)先出,鏈表的尾插其實就是先進(jìn)先出,這不
    發(fā)表于 04-29 18:25 ?0次下載
    什么是<b class='flag-5'>棧</b>?數(shù)據(jù)結(jié)構(gòu)中<b class='flag-5'>棧</b>如何<b class='flag-5'>實現(xiàn)</b>

    教你動手寫UDP協(xié)議—DNS報文解析

    教你動手寫UDP協(xié)議系列文章序號內(nèi)容1《教你動手寫UDP協(xié)議-UDP協(xié)議格式》2《教你動手寫
    的頭像 發(fā)表于 12-24 16:16 ?1420次閱讀

    深入淺出了解單調(diào)和單調(diào)隊列

    內(nèi)單調(diào)遞增或單調(diào)遞減的內(nèi)元素是有序的,單調(diào)隊列同樣也是。 下面我們通過幾個題目由淺入深,一點一點挖透他們吧! 提綱 單調(diào)隊列 劍指
    的頭像 發(fā)表于 02-02 10:18 ?1474次閱讀
    深入淺出了解單調(diào)<b class='flag-5'>棧</b>和單調(diào)<b class='flag-5'>隊列</b>

    隊列實現(xiàn)原理是什么?隊列實現(xiàn)方案有哪幾種?

    是一種后進(jìn)先出的數(shù)據(jù)結(jié)構(gòu),而隊列是一種先進(jìn)先出的數(shù)據(jù)結(jié)構(gòu),兩者原理不難理解,使用也簡單。
    的頭像 發(fā)表于 07-04 13:28 ?2731次閱讀
    <b class='flag-5'>隊列</b><b class='flag-5'>實現(xiàn)</b><b class='flag-5'>棧</b>原理是什么?<b class='flag-5'>隊列</b><b class='flag-5'>實現(xiàn)</b><b class='flag-5'>棧</b>方案有哪幾種?

    簡述Labview使用隊列的區(qū)別

    簡述Labview使用隊列的區(qū)別
    發(fā)表于 01-19 09:50 ?9次下載

    數(shù)據(jù)結(jié)構(gòu)之,隊列,串介紹

    隊列不再過多描述,了解入規(guī)則,入隊出隊規(guī)則,的遞歸應(yīng)用即可,面試肯定不會考這種概念,太簡單。
    的頭像 發(fā)表于 05-26 14:35 ?509次閱讀
    數(shù)據(jù)結(jié)構(gòu)之<b class='flag-5'>棧</b>,<b class='flag-5'>隊列</b>,串介紹

    RTOS消息隊列的應(yīng)用

    基于RTOS的應(yīng)用中,通常使用隊列機制實現(xiàn)任務(wù)間的數(shù)據(jù)交互,一個應(yīng)用程序可以有任意數(shù)量的消息隊列,每個消息隊列都有自己的用途。
    發(fā)表于 05-29 10:49 ?629次閱讀
    RTOS消息<b class='flag-5'>隊列</b>的應(yīng)用

    兩個實現(xiàn)一個隊列方法

    隊列是比較基礎(chǔ)的數(shù)據(jù)結(jié)構(gòu)。無論在工作中,還是在面試中,隊列都用的比較多。在計算機的世界,會看到
    的頭像 發(fā)表于 10-08 15:54 ?802次閱讀

    隊列實現(xiàn)的兩種方法

    兩個隊列實現(xiàn)一個 思路:兩個隊列實現(xiàn)一個,使用了隊列
    的頭像 發(fā)表于 10-08 16:01 ?654次閱讀
    RM新时代网站-首页