




下載本文檔
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
數(shù)據(jù)結(jié)構(gòu)與算法
—線性結(jié)構(gòu)主講教員:段凌宇2014年3月12日
北京大學(xué)信息科學(xué)與技術(shù)學(xué)院,轉(zhuǎn)載或翻印必究北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page22.2.2向量的運算(示例)插入元素運算voidinsert(constELEM&item)
刪除元素運算
ELEMremove()
北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page3插入算法/*
設(shè)元素類型為ELEM,nodelist是存儲順序表向量,msize是此向量的最大長度,curr_len是此向量的當(dāng)前長度,curr為此向量當(dāng)前下標(biāo))*/#include<assert.h>…template<classELEM>voidlist<ELEM>::insert(constELEM&item){
//需要檢查當(dāng)前長度不能大于或等于msize;//當(dāng)前游標(biāo)指針curr不能小于0,也不能大于或等于當(dāng)前長度;
//此條件不滿足時,程序異常,退出運行。
assert((curr_len<msize)&&(curr>=0)&&(curr<curr_len));北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page4
//從表尾curr_len-1起往右移動直到curr
for
(inti=curr_len;i>curr;i--) nodelist[i]=nodelist[i-1];
//當(dāng)前指針處插入新元素
nodelist[curr]=item;
//表的實際長度curr_len加1
curr_len++;}循環(huán)至i=curr+1,最后一次移動是nodelist[curr]北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page5插入算法執(zhí)行時間
元素總個數(shù)為k,各個位置插入的概率(可能性)相等,即p=1/k平均移動元素次數(shù)為
:總時間開銷估計為:
O(k)
北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page6刪除算法/*設(shè)元素類型為ELEM,nodelist是存儲順序表向量,msize是此向量的最大長度,curr_len是此向量的當(dāng)前長度,curr為此向量當(dāng)前下標(biāo)*///返回curr所指的元素值,并從表中刪去此元素#include<assert.h>…template<classELEM>ELEMlist<ELEM>::remove(){
//需要檢查當(dāng)前長度不能大于msize;//當(dāng)前游標(biāo)指針curr不能小于0,也不能大于等于當(dāng)前長度;
//此條件不滿足時,程序異常,退出運行。
assert((curr_len<=msize)&&(curr>=0)&&(curr<curr_len));北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page7ELEMtemp=
nodelist[curr];//從指針curr到curr_len每個元素往前移一格for(inti=curr;i<curr_len-1;i++)nodelist[i]=nodelist[i+1];curr_len--;//表的實際長度cur_len減1returntemp;//返回值是進入時的舊值}循環(huán)至i=curr_len-2,最后一次移動是nodelist[curr_len-1]北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page8刪除算法時間代價
刪除操作與插入操作相似時間代價為O(k)
順序表存取元素方便時間代價為O(1)北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page9大綱2.1線性表(linearlist)2.2順序表—
向量(vector)2.3鏈表(linkedlist)2.3.1單鏈表2.3.2雙鏈表2.3.3循環(huán)鏈表2.4線性表實現(xiàn)方法的比較2.5棧(stack)2.6隊列(queue)2.7棧與遞歸(recursivefunction)北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page10約瑟夫環(huán)問題
(JosephusProblem)在羅馬人占領(lǐng)喬塔帕特(Yodfat)
后,39個猶太人與Josephus及他的朋友躲到一個洞中,39個猶太人決定寧愿死也不要被敵人抓到,于是決定了一個自殺方式,41個人排成一個圓圈,由第1個人開始報數(shù),每報數(shù)到第3人該人就必須自殺,然后再由下一個重新報數(shù),直到所有人都自殺身亡為止。Josephus和他的朋友并不想遵從,Josephus要他的朋友先假裝遵從,他將朋友與自己安排在第16個與第31個位置,于是逃過了這場死亡游戲。北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page11約瑟夫環(huán)問題
(JosephusProblem)用鏈表(或者數(shù)組)實現(xiàn),時間復(fù)雜度高達(dá)O(nm),當(dāng)n,m非常大(例如上百萬,上千萬)的時候,幾乎是沒有辦法在短時間內(nèi)出結(jié)果的.模擬整個游戲過程注意到原問題僅僅是要求出最后的勝利者的序號,而不是要模擬整個過程。遞推公式:
f[1]=0;
f[i]=(f[i-1]+m)%i;(i>1)
北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page12約瑟夫環(huán)問題
(JosephusProblem)遞推公式:
f[1]=0;
f[i]=(f[i-1]+m)%i;(i>1)
將這些人從0到n-1編號,假設(shè)出列的是第k個人。
0,1,2,3,...,k-2,k-1,k,...,n-1//originalsequence(1)
0,1,2,3,...,k-2,,k,...,n-1//getridofthekthperson(2)
k,k+1,...,n-1,0,1,...,k-2//rearrangethesequence(3)
0,1,...,n-k-1,n-k,n-k+1,...,n-2//n-1person(4)
就接下來出列編號來說,注意到(2)式(3)其實是同一個序列,并且編號與(1)序列保持一致,然后(4)式進行了重新編號(對應(yīng)“新一輪的報數(shù)”)。
對比(3)(4)兩式,可以看出(3)中的編號x‘與(4)中的編號x對應(yīng)關(guān)系即為x’(注:上一輪報數(shù)階段的編號)=(x(注:當(dāng)前報數(shù)階段的編號)+m)modn考慮(4)式的編號與(3)式的編號,存在上述遞推關(guān)系;當(dāng)知道(4)式(當(dāng)前報數(shù)階段)的出列編號R,就可以遞推出(4)式R在(3)式的編號R’,即(1)式的編號。北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page13約瑟夫環(huán)問題
(JosephusProblem)用鏈表(或者數(shù)組)實現(xiàn),時間復(fù)雜度高達(dá)O(nm),當(dāng)n,m非常大(例如上百萬,上千萬)的時候,幾乎是沒有辦法在短時間內(nèi)出結(jié)果的.模擬整個游戲過程注意到原問題僅僅是要求出最后的勝利者的序號,而不是要模擬整個過程?;谶f推的算法的時間復(fù)雜度為O(n),相對于模擬算法已經(jīng)有了很大的提高。適當(dāng)?shù)剡\用數(shù)學(xué)策略,不僅可以讓編程變得簡單,而且往往會成倍地提高算法執(zhí)行效率。北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page142.3.1
單鏈表通過指針將一串存儲結(jié)點鏈接成一個鏈
存儲結(jié)點由兩部分組成:Data字段Link字段數(shù)據(jù)的邏輯結(jié)構(gòu)(K,R)K是由有限個結(jié)點組成的集合;R是定義在集合K上的一組二元關(guān)系北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page15單鏈表的存儲結(jié)構(gòu)
每一個存儲結(jié)點Data字段都代表一個基本類型數(shù)據(jù),或一組有明確結(jié)構(gòu)的數(shù)據(jù)(復(fù)合數(shù)據(jù)類型、類對象)北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page16單鏈表結(jié)點類型定義,頭尾指針變量申明structListNode{ ELEMdata;
ListNode*link;};typedefListNode*ListPtr;ListPtrfirst,last;//頭、尾指針在VC6中,若源程序是cpp后綴名那么是沒有問題的,但是如果后綴名為c,會如何?出現(xiàn)errorC2081等錯誤,意思就是ListNode沒有定義等。北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page17//在VC6中,若源程序是c后綴名,//需做以下修改typedef
struct
tagListNode{ ELEMdata;
ListNode*link;}ListNode;typedefListNode*ListPtr;ListPtrfirst,last;//頭、尾指針例子:來自微軟的矩形類型定義typedefstructtagRECT{LONGleft;LONGtop;LONGright;LONGbottom;}RECT,*PRECT;北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page18查找
單鏈表中第i個結(jié)點算法
ListNode*FindIndex(constinti)//函數(shù)返回值是找到的結(jié)點指針{ //first表首變量,可能指向空表
if(i==-1)returnfirst; ListNode*p=first->link;
北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page19intj=0; while(p!=NULL&&j<i) { p=p->link; j++; };returnp;}循環(huán)至j=i-1,p=p->link指向第i個結(jié)點P何時返回NULL?當(dāng)鏈表中結(jié)點數(shù)小于i+1時北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page20插入
單鏈表中第i個結(jié)點算法ii+1北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page21插入
單鏈表中第i個結(jié)點算法
ListNode*Insert(ELEMvalue,inti)//插入數(shù)據(jù)內(nèi)容為value的新結(jié)點,//使之成為第i個結(jié)點{ ListNode*p,*q; q=newListNode; p=FindIndex(i-1); if(p==NULL)returnNULL;鏈表中結(jié)點數(shù)小于i,表尾結(jié)點最多是第i-2個結(jié)點北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page22 q->data=value;
q->link=p->link; p->link=q; if(q->link==NULL) last=q;//若插入結(jié)點無后繼,更新尾指針 returnq;//返回插入結(jié)點的指針}
北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page23刪除
單鏈表指定結(jié)點算法
北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page24voidRemoveAfter(ListNode*link)//刪除由參數(shù)link指定結(jié)點的下一個節(jié)點{ ListNode*newlink=link->link; if(newlink!=NULL){ link->link=newlink->link;
deletenewlink;}//若link指向的結(jié)點不是尾部結(jié)點}
北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page25單鏈表長度算法intLength(){ intcount=0; ListNode*p=first->link; while(p!=NULL) { p=p->link; count++; } returncount;}
北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page26大綱2.3鏈表(linkedlist)2.3.1單鏈表2.3.2雙鏈表2.3.3循環(huán)鏈表2.4線性表實現(xiàn)方法的比較北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page272.3.2雙鏈表
(doublelinkedlist)
單鏈表的主要不足:link字段僅僅指向后繼結(jié)點,不能有效地找到前驅(qū)雙鏈表彌補了上述不足:增加一個指向前驅(qū)的指針北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page28雙鏈表及其結(jié)點類型定義structDblListNode{ ELEMdata;
DblListNode*rlink; DblListNode*llink;};
structDoubleList{ DblListNode*first,*last;};北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page29插入雙鏈表中
指定結(jié)點的算法會出現(xiàn)問題嗎?有更簡潔方式?會出現(xiàn)問題嗎?北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page30在p所指結(jié)點后面
插入一個新結(jié)點首先執(zhí)行newq開辟結(jié)點空間。然后,讓該新結(jié)點的rlink填入p所指的后繼地址,新結(jié)點的llink填入指向p結(jié)點的指針,即newq;q->rlink=p->rlink;q->llink=p;//Error:q->llink=p->rlink->llink;此外,要把新結(jié)點的地址填入原p所指結(jié)點的rlink字段,而且新結(jié)點后繼的llink字段也應(yīng)該回指新結(jié)點。p->rlink=q;q->rlink->llink=q;
//注意:安全代碼需檢查q->rlink是否為空北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page31刪除雙鏈表中
指定結(jié)點的算法有問題嗎?實踐中需要檢驗p所指的結(jié)點是否有后繼?北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page322.3.3循環(huán)鏈表
(circularlylinkedlist)
將單鏈表或者雙鏈表的頭尾結(jié)點鏈接起來,就是一個循環(huán)鏈表。給操作帶來了方便,不增加額外存儲花銷從循環(huán)表中任一結(jié)點出發(fā),都能訪問到表中其他結(jié)點;單鏈不可以。提高訪問效率。北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page33幾種主要鏈表比較北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page342.4線性表實現(xiàn)方法的比較順序表的主要優(yōu)點
沒有使用指針,不用花費附加開銷
線性表元素的讀訪問非常簡潔便利
鏈表的主要優(yōu)點
無需事先了解線性表的長度
允許線性表的長度有很大變化
能夠適應(yīng)經(jīng)常插入、刪除內(nèi)部元素的情況通過建立雙向或循環(huán)鏈表提高訪問效率北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page35應(yīng)用場合的選擇
避免使用順序表的場合經(jīng)常插入、刪除時,不宜使用順序表
線性表的最大長度也是一個重要因素避免使用鏈表的場合
讀操作頻率大于插入、刪除操作頻率當(dāng)指針的存儲開銷,和整個結(jié)點內(nèi)容所占空間相比,指針開銷比例較大時,應(yīng)該慎重選擇
北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page36大綱2.5棧(stack)2.5.1順序棧
2.5.2鏈?zhǔn)綏?/p>
2.5.3順序棧與鏈?zhǔn)綏5谋容^
2.5.4棧的應(yīng)用——后綴表達(dá)式求值2.6隊列(queue)2.6.1順序隊列
2.6.2鏈?zhǔn)疥犃?/p>
2.2.3順序隊列與鏈?zhǔn)疥犃械谋容^
2.7棧與遞歸(recursivefunction)北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page372.5棧(stack)
一種限制訪問端口的線性表,后進先出表(LIFO表,Last-InFirst-Out)。也稱為“下推表”。元素插入稱為棧的‘壓入’(push),刪除稱為棧的‘彈出’(pop)。表首被稱為‘棧頂’,而棧的另一端則叫做‘棧底’
每次取出(并被刪除)的總是剛壓進的元素,而最先壓入的元素則被放在棧的底部
棧頂棧底按壓入先后次序,最先壓入的元素編號為1,然后依次為2,3,4北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page38棧的抽象數(shù)據(jù)類型
template<classELEM>classStack{…//棧的運算集
}棧頂棧底棧的元素類型為ELEM棧的存儲:可以用順序表或單鏈表存儲,長度為定長北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page39enumBoolean{True,False}template<classELEM>classStack{stack(ints);//創(chuàng)建棧的實例
~stack();//該實例消亡
voidPush(ELEMitem); //item壓入棧頂
ELEMPop();//返回棧頂內(nèi)容,并從棧頂出
ELEMGetTop();//返回棧頂內(nèi)容,但不彈出
voidMakeEmpty(); //變?yōu)榭諚?/p>
BooleanIsEmpty(); //返回真,若棧已空
BooleanIsFull();//返回真,若棧已滿};北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page40棧的實現(xiàn)
順序棧使用向量實現(xiàn)鏈?zhǔn)綏S脝捂湵矸绞酱鎯?,其中指針的方向是從棧頂向下鏈接,即鏈表的頭結(jié)點位置對應(yīng)“棧頂”。
北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page412.5.1順序棧//設(shè)棧的類定義為stack,棧元素類型為浮點float類型enumBoolean{True,False}#include<assert.h>//引入邏輯斷言語句classStack{public: float*ElmList;//存放數(shù)據(jù)元素的指針變量北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page42inttop;//該變量指示棧頂在該向量的位置(下標(biāo)值)//當(dāng)新元素壓入或棧內(nèi)容彈出,top值隨之增減intmaxsize;//棧的最大長度Stack(intsize); //構(gòu)建函數(shù),創(chuàng)建棧的實例,向量空間長度為size//其他運算集,比如~Stack();};北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page43
順序棧的創(chuàng)建
//棧實例的創(chuàng)建,指定最大長度10Stack::Stack(intsize=10){ maxsize=size; //開辟向量存儲空間
ElmList=newfloat[maxsize]; //判斷new命令成功否,否則斷言程序異常
assert(ElmList!=NULL); top=-1;//表示??諁北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page44壓入棧頂
voidStack::Push(floatitem){ //判斷是非棧滿,若棧溢出,退出運行
assert(!IsFull()); top++;//更新棧頂位置
ElmList[top]=item;//壓入棧頂元素}北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page45從棧頂彈出
floatStack::Pop(){ //判斷棧非空,若斷言棧空異常,退出運行
assert(!IsEmpty()); returnElmList[top--];}北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page46從棧頂讀取,但不彈出
floatStack::GetTop(){
//判斷棧非空,若斷言棧空異常,退出運行
assert(!IsEmpty());
returnElmList[top];}北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page47其他算法
清空棧voidStack::MakeEmpty()
{top=-1;}棧消亡
~Stack(){delete[]ElmList;}棧滿時,返回真(true)BooleanIsFull(){returntop==(maxsize-1);}北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page48大綱(續(xù))2.5棧(stack)2.5.1順序棧
2.5.2鏈?zhǔn)綏?/p>
2.5.3順序棧與鏈?zhǔn)綏5谋容^
2.5.4棧的應(yīng)用——后綴表達(dá)式求值2.6隊列(queue)2.6.1順序隊列
2.6.2鏈?zhǔn)疥犃?/p>
2.2.3順序隊列與鏈?zhǔn)疥犃械谋容^
2.7棧與遞歸(recursivefunction)北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page492.5.2鏈?zhǔn)綏S脝捂湵矸绞酱鎯χ羔樀姆较驈臈m斚蛳骆溄?/p>
北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page50鏈?zhǔn)綏5膭?chuàng)建
#include<assert.h>structListNode{
ELEMdata;
ListNode*link;};//單鏈表的結(jié)點類型
classStack{private:ListNode*top;public:
//創(chuàng)建一個空棧
//不用指定最大長度
Stack(){top=NULL;};
//其它運算集};北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page51壓入棧頂
voidStack::Push(floatitem){ ListNode*temp; temp=newListNode; //若無存儲空間則
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 虛擬現(xiàn)實影視技術(shù)應(yīng)用-深度研究
- 《GBZ 44526-2024無損檢測 操作能力鑒定》全新解讀
- 【+高中語文+】《項脊軒志》課件+高二語文選擇性必修下冊
- 預(yù)防性侵教學(xué)
- 2024年咨詢工程師考試題庫帶答案(鞏固)
- 2024年咨詢工程師(經(jīng)濟政策)考試題庫(突破訓(xùn)練)
- 2024年助理會計師《初級會計實務(wù)》真題庫匯編(含答案)
- 幼兒園教育:空氣的秘密
- 2025年行政執(zhí)法證資格考試必刷經(jīng)典題庫及答案(共160題)
- 預(yù)防乙型腦炎健康教育
- 中央廚房建設(shè)項目可行性研究報告
- 2025年輿情應(yīng)對面試試題及答案
- 山東省大教育聯(lián)盟學(xué)校2024-2025學(xué)年高三下學(xué)期開學(xué)檢測化學(xué)試題(含答案)
- 語文-福建省廈門市2025屆高中畢業(yè)班第二次質(zhì)量檢測(廈門二檢)試題和答案
- 2025屆浙江名校協(xié)作體高三語文考場高分作文點評:這種向往到底是人的苦處還是人的樂處呢
- 2025年浙江名校協(xié)作體高三語文2月聯(lián)考作文題分析+素材+范文:這種向往到底是人的苦處還是人的樂處呢
- 2025年云南省高職單招《職測》高頻必練考試題庫400題(含答案)
- 新教科版一年級科學(xué)下冊第一單元第6課《哪個流動得快》課件
- 2025年廣西旅發(fā)置業(yè)集團有限公司招聘筆試參考題庫含答案解析
- 全國職業(yè)院校技能大賽高職組(商務(wù)數(shù)據(jù)分析賽項)備賽試題及答案
- 任務(wù)三學(xué)做麥糊燒(教案)三年級下冊勞動浙教版
評論
0/150
提交評論