數(shù)據(jù)結(jié)構(gòu)-棧和隊(duì)列_第1頁(yè)
數(shù)據(jù)結(jié)構(gòu)-棧和隊(duì)列_第2頁(yè)
數(shù)據(jù)結(jié)構(gòu)-棧和隊(duì)列_第3頁(yè)
數(shù)據(jù)結(jié)構(gòu)-棧和隊(duì)列_第4頁(yè)
數(shù)據(jù)結(jié)構(gòu)-棧和隊(duì)列_第5頁(yè)
已閱讀5頁(yè),還剩37頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

數(shù)據(jù)結(jié)構(gòu)第3章棧和隊(duì)列

從數(shù)據(jù)結(jié)構(gòu)上看,棧和隊(duì)列也是線性表,不過(guò)是兩種特殊的線性表。棧只允許在表的一端進(jìn)行插入或刪除操作,而隊(duì)列只允許在表的一端進(jìn)行插入操作、而在另一端進(jìn)行刪除操作。堆棧和隊(duì)列在各種類型的軟件系統(tǒng)中應(yīng)用廣泛。堆棧技術(shù)被廣泛應(yīng)用于編譯軟件和程序設(shè)計(jì)中,在操作系統(tǒng)和事務(wù)管理中廣泛應(yīng)用了隊(duì)列技術(shù)。通過(guò)本章的學(xué)習(xí),讀者應(yīng)能掌握棧和隊(duì)列的邏輯結(jié)構(gòu)和存儲(chǔ)結(jié)構(gòu),以及棧和隊(duì)列的基本運(yùn)算以及實(shí)現(xiàn)算法。3.1棧3.2隊(duì)列3.1棧

1、棧(Stack)的定義:

棧是一種特殊的線性表,限定僅在表的一端進(jìn)行插入或刪除操作的線性表。棧的插入操作通常稱為入?;蜻M(jìn)棧(push),而棧的刪除操作則稱為出棧或退棧(pop)。當(dāng)棧中無(wú)數(shù)據(jù)元素時(shí),稱為空棧。特點(diǎn):

(1)只允許在一端插入和刪除的順序表(2)允許插入和刪除的一端稱為棧頂(top),另一端稱為棧底(bottom)

(3)后進(jìn)先出(LIFO,lastinfirstout)第3章棧和隊(duì)列

2、棧的存儲(chǔ)結(jié)構(gòu):(1)順序存儲(chǔ)結(jié)構(gòu)兩種存儲(chǔ)結(jié)構(gòu):

(2)鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)

順序棧:利用數(shù)組存放自棧底到棧頂?shù)臄?shù)據(jù)元素,附設(shè)指針top指示棧頂元素在順序棧中的位置。

#defineMAXNUM<最大元素?cái)?shù)>//棧的最大數(shù)據(jù)元素?cái)?shù)目

typedefstruct{Elemtypestack[MAXNUM];//存放棧中數(shù)據(jù)元素的存儲(chǔ)單元

inttop;//棧頂指針

}sqstack;

鑒于C語(yǔ)言中數(shù)組的下標(biāo)約定是從0開始的,因而使用C語(yǔ)言的一維數(shù)組作為棧時(shí),應(yīng)設(shè)棧頂指針top=-1時(shí)為空棧。一般有:

s->top=s->base是為空棧?;静僮魉惴ǎ海?)初始化棧操作

intinitStack(sqstack*s){/*創(chuàng)建一個(gè)空棧由指針S指出*/s=(sqstack*)malloc(sizeof(sqstack));if(s==NULL)

{returnFALSE;}else{s->top=s->base;returnTRUE;}}(2)進(jìn)棧操作

intpush(sqstack*s,Elemtypex){/*將元素x插入到棧s中,作為s的新棧頂*/if(s->top>=MAXNUM-1)returnFALSE;/*棧滿*/

s->stack[s->top]=x;s->top++;returnTRUE;}(3)出棧操作

intpop(sqstack*s){/*若棧s不為空,則刪除棧頂元素*/if(s->top<0)returnNULL;/*???/

s->top--;x=s->stack[s->top];returnx;}(4)取棧頂元素操作

intgettop(sqstack*s){/*若棧s不為空,則返回棧頂元素*/if(s->top<0)returnNULL;/*???/

return(s->stack[--s->top]);}

注:取棧頂元素與出棧不同之處在于出棧操作改變棧頂指針top的位置,而取棧頂元素操作不改變棧的棧頂指針。(5)判斷空操作

intEmpty(sqstack*s){//棧s為空時(shí),返回為TRUE;

//非空時(shí),返回為FALSE

if(s->top<0)returnTRUE;

returnFALSE;}

鏈?zhǔn)綏#喝羰菞V性氐臄?shù)目變化范圍較大或不清楚棧元素的數(shù)目,就應(yīng)該考慮使用鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)。人們將用鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)表示的棧稱作“鏈?!薄S捎跅5牟迦雱h除操作只能在一端進(jìn)行,而對(duì)于單鏈表來(lái)說(shuō),在首端插入刪除結(jié)點(diǎn)要比尾端相對(duì)地容易一些,所以,我們將單鏈表的首端作為棧頂端,即將單鏈表的頭指針作為棧頂指針。datanexttop棧頂棧底鏈棧示意圖

typestructnode{//鏈棧的結(jié)點(diǎn)結(jié)構(gòu)

ELEMTPdata;//棧的數(shù)據(jù)元素類型

structnode*next;//指向后繼結(jié)點(diǎn)的指針

}SNode;基本操作算法:(1)建立一個(gè)空棧

StatusInitLStack(Linkstack&S){

S=NULL;

returnok;

}//InitLStack

(2)取棧頂元素

StatusGettopLStack(Linkstack&S,SElemType&e){

//若棧不為空,則用e返回S的棧頂元素,

//并返回OK,否則返回ERROR.

if(S==NULL)returnERROR;

e=S->data;

return(OK);

}//GettopLStack(3)入棧操作

voidPush(LinkStack*s,ELEMTPx){s=(LinkStack*)malloc(sizeof(LinkStack));s->data=x;s->next=top;top=s;

returntop;}(4)出棧操作

voidPop(LinkStack*s,ELEMTP*x){if(s==NULL)returnNULL;/*空棧*/else{

p=top;*x=p->data;top=p->next;free(p);

}returntop;}

例:十進(jìn)制數(shù)N和其他d進(jìn)制數(shù)的轉(zhuǎn)換是計(jì)算機(jī)實(shí)現(xiàn)計(jì)算的基本問題,其解決方法很多,其中一個(gè)簡(jiǎn)單算法基于下列原理:N=(Ndivd)×d+Nmodd(其中:div為整除運(yùn)算,mod為求余運(yùn)算)

voidconversion(){//對(duì)于輸入的任意一個(gè)非負(fù)十進(jìn)制整數(shù),打印輸出與其等值的八進(jìn)制數(shù)

InitStack(S);//構(gòu)造空棧

scanf("%d",N);while(N){Push(S,N%8);N=N/8;}while(!StackEmpty(S)){Pop(S,e);printf("%d",e);}}//conversion3.2隊(duì)列

1、隊(duì)列(Queue)的定義:

隊(duì)列是一種特殊的線性表,限定插入在線性表的一端進(jìn)行,刪除在線性表的另外一端進(jìn)行。特點(diǎn):

(1)只允許在一端插入,在另外一端刪除的順序表(2)允許刪除的一端叫做隊(duì)頭(front),允許插入的一端叫做隊(duì)尾(rear)

(3)后進(jìn)先出(FIFO,F(xiàn)irstinFirstOut)frontreara0

a1

a2

an-1

2、隊(duì)列的存儲(chǔ)結(jié)構(gòu):(1)順序存儲(chǔ)結(jié)構(gòu)兩種存儲(chǔ)結(jié)構(gòu):

(2)鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)

順序隊(duì)列:利用一組地址連續(xù)的存儲(chǔ)單元依次將數(shù)據(jù)元素存放到隊(duì)列中。附設(shè)一個(gè)為指向隊(duì)頭元素位置的指針front,另一個(gè)為指向隊(duì)尾的元素位置的指針rear。

(1)進(jìn)隊(duì)時(shí):隊(duì)尾指針先進(jìn)一rear=rear+1,再將新元素按rear指示位置加入。(2)出隊(duì)時(shí):隊(duì)頭指針先進(jìn)一front=front+1,再將下標(biāo)為front的元素取出。插入端和刪除端都是浮動(dòng)的。通常我們將插入端稱為隊(duì)尾,用“rear”指示;而刪除端被稱為隊(duì)頭,用“front”指示。frontrear空隊(duì)列frontrearA進(jìn)隊(duì)AfrontrearB進(jìn)隊(duì)ABfrontrearC,D進(jìn)隊(duì)ABCDfrontrearA退隊(duì)BCDfrontrearB退隊(duì)CDfrontrearE,F,G進(jìn)隊(duì)CDEFGCDEFGfrontrearH進(jìn)隊(duì),溢出

用C語(yǔ)言定義的順序存儲(chǔ)結(jié)構(gòu)的隊(duì)列如下:

#defineMAXNUM<最大元素?cái)?shù)>//隊(duì)列的最大數(shù)據(jù)元素?cái)?shù)目

typedefstruct{ElemtypeQueue[MAXNUM];//存放隊(duì)列中數(shù)據(jù)元素的存儲(chǔ)單元

intrear,front;//隊(duì)頭隊(duì)尾指針

}SeqQueue;SeqQueue*sq;Sq=newSeqQueue;

為了算法設(shè)計(jì)的方便,在此我們約定:初始化隊(duì)列時(shí),空隊(duì)列時(shí)令front=rear=-1,當(dāng)插入新的數(shù)據(jù)元素時(shí),尾指示器rear加1,而當(dāng)隊(duì)頭元素出隊(duì)列時(shí),隊(duì)頭指示器front加1。另外還約定,在非空隊(duì)列中,頭指示器front總是指向隊(duì)列中實(shí)際隊(duì)頭元素的前面一個(gè)位置,而尾指示器rear總是指向隊(duì)尾元素?;静僮魉惴ǎ海?)初始化隊(duì)列

intinitQueue(sqqueue*q){/*創(chuàng)建一個(gè)空隊(duì)列由指針q指出*/q=(sqqueue*)malloc(sizeof(sqqueue))if(q==NULL)returnFALSE;

q->front=q->rear=0;returnTRUE;}(2)入隊(duì)列操作

intappend(sqqueue*q,Elemtypex){/*將元素x插入到隊(duì)列q中,作為q的新隊(duì)尾*/if(q->rear>=MAXNUM-1)returnFALSE;/*隊(duì)列滿*/

q->rear++;q->queue[q->rear]=x;returnTRUE;}(3)出隊(duì)列操作

Elemtypedelete(sqqueue*q){/*若隊(duì)列q不為空,則返回隊(duì)頭元素*/Elemtypex;if(q->rear==q->front)returnNULL;/*隊(duì)列空*/

x=q->queue[++q->front];returnx;}(4)取隊(duì)頭元素操作

ElemtypegetHead(sqqueue*q){/*若隊(duì)列q不為空,則返回隊(duì)頭元素*/if(q->rear==q->front)returnNULL;/*隊(duì)列空*/return(q->queue[s->front+1]);}(5)判隊(duì)列非空操作

intEmpty(sqqueue*q){//隊(duì)列q為空時(shí),返回TRUE;

//否則返回FALSE

if(q->rear==q->front)returnTRUE;returnFALSE;}(6)求隊(duì)列長(zhǎng)度操作

intlength(sqqueue*q){/*返回隊(duì)列q的元素個(gè)數(shù)*/

return(q->rear-q->front);}隊(duì)滿時(shí)再進(jìn)隊(duì)—>溢出隊(duì)空時(shí)再出隊(duì)—>隊(duì)空

解決辦法:將隊(duì)列元素?cái)?shù)組首尾相接,形成循環(huán)隊(duì)列。在循環(huán)隊(duì)列中,每插入一個(gè)新元素時(shí),就把隊(duì)尾指針沿順時(shí)針方向移動(dòng)一個(gè)位置。即:

q->rear=q->rear+1;if(q->rear==MAXNUM)q->rear=0;

在循環(huán)隊(duì)列中,每刪除一個(gè)元素時(shí),就把隊(duì)頭指針沿順時(shí)針方向移動(dòng)一個(gè)位置。即:

q->front=q->front+1;if(q->front==MAXNUM)q->front=0;01234567front01234567front01234567frontrearAABCrearrear空隊(duì)列A進(jìn)隊(duì)B,C進(jìn)隊(duì)0123456701234567A退隊(duì)B退隊(duì)01234567D,E,F,G,H進(jìn)隊(duì)frontBCrearAfrontBCrearfrontCrearDEFGH

假設(shè)為隊(duì)列開辟的數(shù)組單元數(shù)目為MAX_QUEUE,在C語(yǔ)言中,它的下標(biāo)在0~MAX_QUEUE-1之間,若增加隊(duì)頭或隊(duì)尾指針,可以利用取模運(yùn)算實(shí)現(xiàn)。如下:front=(front+1)%MAX_QUEUE;rear=(rear+1)%MAX_QUEUE;當(dāng)front或rear為MAX_QUEUE-1時(shí),上述兩個(gè)公式計(jì)算的結(jié)果就為0。這樣,就使得指針自動(dòng)由后面轉(zhuǎn)到前面,形成循環(huán)的效果。隊(duì)空和隊(duì)滿的標(biāo)志問題:隊(duì)列變?yōu)榭?,?duì)頭和隊(duì)尾指針相等。(1)初始化操作

StatusInitQueue(SqQueue*Q){//構(gòu)造一個(gè)空隊(duì)列Q

Q=(QElemType)malloc(MAXQSIZE*sizeof(QElemType));

if(!Q)exit(OVERFLOW);//存儲(chǔ)分配失敗

Q.front=Q.rear=0;

returnOK;

}(2)入隊(duì)列操作

intEnQueue(SqQueue&Q,QElemTypee){//插入元素e為Q的新的隊(duì)尾元素

if((Q.rear+1)%MAXQSIZE==Q.front)returnERROR;//隊(duì)列滿

Q.base[Q.rear]=e;

Q.rear=(Q.rear+1)%MAXQSIZE;

return1;

}(3)出隊(duì)列操作

StatusDeQueue(SqQueue&Q,QElemType&e){//若隊(duì)列不空,則刪除Q的隊(duì)頭元素,

//用e返回其值,并返回1,否則返回ERRORif(Q.Front==Q.rear)returnERROR;

e=Q.base[Q.front];

Q.front=(Q.front+1)%MAXQSIZE;

returnOK;

}(4)求循環(huán)隊(duì)列長(zhǎng)度

IntQueueLength(SqQueueQ){//返回Q的元素個(gè)數(shù),即隊(duì)列的長(zhǎng)度

return(Q.rear–Q.front+MAXSIZE)%MAXQSIZE;

}

鏈?zhǔn)疥?duì)列:用鏈表表示的隊(duì)列。

(1)一個(gè)鏈隊(duì)列需要兩個(gè)指針,分別指示隊(duì)頭和隊(duì)尾的指針——頭指針和尾指針。

(2)給鏈隊(duì)列添加一個(gè)頭結(jié)點(diǎn)??盏逆滉?duì)列的判決條件為頭指針和尾指針均指向頭結(jié)點(diǎn)。frontrear(1)初始化操作

StatusInitQueue(LinkQ

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論