版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
數(shù)據(jù)結(jié)構(gòu)王源2016年9月第2章線性表
2.1線性表ADT2.2線性表的順序表示2.3線性表的鏈接表示2.4多項(xiàng)式的算術(shù)運(yùn)算實(shí)驗(yàn)二、鏈表及其應(yīng)用
2.1線性表ADT線性表的定義線性表是n(0)個(gè)元素a0,a1,…,an-1的線性序列,記為:(a0,a1,…,an-1)。其中n是線性表中元素的個(gè)數(shù),稱為線性表的長度;n=0時(shí)稱為空表。
ai是表中下標(biāo)為i的元素(i=0,1,…,n-1),稱ai是ai+1的直接前驅(qū)元素,ai+1是ai的直接后繼元素。線性表是動(dòng)態(tài)數(shù)據(jù)結(jié)構(gòu),它的表長可以改變。
線性表ADTADTLinearList{數(shù)據(jù):
0個(gè)或多個(gè)元素的線性序列(a0,a1,...,an-1),其最大允許長度為MaxListSize。運(yùn)算:
Create():創(chuàng)建一個(gè)空線性表。
Destroy():撤消一個(gè)線性表。
IsEmpty():若線性表空,則返回true;否則返回false。
Length():返回表中元素個(gè)數(shù)。
Find(i,x):在x中返回表中下標(biāo)為i的元素ai。若不存在,則返回false,否則返回true。Search(x):若x不在表中,則返回-1,否則返回x在表中的下標(biāo)。Insert(i,x):在元素ai之后插入x。若i=-1,則x插在第一個(gè)元素a0前。若插入成功,則返回true,否則返回false。Delete(i):刪除元素ai。若刪除成功,則返回true,否則返回false。Update(i,x):將元素ai的值修改為x。若修改成功,則返回true,否則返回false。Output(out):把表送至輸出流}//插入x到表:(a0,a1,...,an-1)
線性表類template<classT>classLinearList{public:……virtualboolFind(inti,T&x)const=0;virtualboolInsert(inti,Tx)=0;virtualboolDelete(inti)=0;……protected:
intn;//線性表的長度};
2.2線性表的順序表示
2.2.1順序存儲(chǔ)結(jié)構(gòu)順序存儲(chǔ)表示是用一組地址連續(xù)的存儲(chǔ)單元依次存儲(chǔ)線性表中元素。順序表順序表示的線性表稱為順序表
a0a1…ai
…
an-1
…01…i…n-1…maxLength-1
地址計(jì)算公式
若已知順序表中每個(gè)元素占k個(gè)存儲(chǔ)單元,第一個(gè)元素a0在計(jì)算機(jī)內(nèi)存中的首地址是loc(a0),則表中任意一個(gè)元素ai在內(nèi)存中的存儲(chǔ)地址loc(ai)為
loc(ai)=loc(a0)+i*k
隨機(jī)存取結(jié)構(gòu)只要給定loc(a0)和k,就可以確定線性表中任意一個(gè)元素的存儲(chǔ)地址,換句話說,順序表是一種隨機(jī)存取結(jié)構(gòu)。2.2.2順序表類順序表類template<classT>classSeqList:public
LinearList<T>{public://公有函數(shù)
SeqList(intmSize);
~SeqList(){delete[]elements;}boolFind(inti,T&x)const;intSearch(Tx)const;boolInsert(inti,Tx);boolDelete(inti);……SingleListLinearListSeqList
……private://私有數(shù)據(jù)
intmaxLength; //順序表的最大長度
T*elements; //動(dòng)態(tài)一維數(shù)組的指針};
動(dòng)態(tài)存儲(chǔ)分配構(gòu)造函數(shù),構(gòu)建一個(gè)空線性表
template<classT>SeqList<T>::SeqList(intmSize){maxLength=mSize;elements=newT[maxLength];n=0;}
析構(gòu)函數(shù),撤消一個(gè)順序表template<classT>SeqList<T>::~SeqList(){delete[]elements;}2.2.3線性表運(yùn)算實(shí)現(xiàn)搜索運(yùn)算
Find(i,x):
查找下標(biāo)為i的元素ai。在x中返回表中下標(biāo)為i的元素ai(即表中第i+1個(gè)元素)。如果不存在,則返回
false,否則返回true。x=elements[i];漸近時(shí)間復(fù)雜度:O(1)
a0a1…ai
…
an-1
…01…i…n-1…maxLength-1
template<classT>boolSeqList<T>::Find(inti,T&x)const{//O(1)if(i<0||i>n?1){ //對(duì)i進(jìn)行越界檢查
cout<<"OutofBounds"<<endl;returnfalse;}
x=elements[i];//通過引用參數(shù)x返回下標(biāo)為i的元素
returntrue;}
插入運(yùn)算
Insert(i,x):在表中下標(biāo)為i的元素ai后插入x。若i=-1,則將新元素x插在最前面。若插入成功,返回true;
插入運(yùn)算的平均時(shí)間復(fù)雜度分析:設(shè)順序表長度為n,共有n+1個(gè)可插入元素的位置,并設(shè)在各位置處插入元素的概率是相等的,即Pi=1/(n+1),在位置i(i=-1,0,…,n-1)后插入一個(gè)元素要移動(dòng)n-i-1個(gè)元素。
template<classT>boolSeqList<T>::Insert(inti,Tx){//在元素ai之后插入xif(i<-1||i>n-1){//越界檢查
cout<<"OutOfBounds"<<endl;returnfalse;}if(n==maxLength){ //上溢出檢查
cout<<"OverFlow"<<endl;returnfalse;}//從后往前逐個(gè)后移元素
for(intj=n-1;j>i;j--)elements[j+1]=elements[j];
elements[i+1]=x;n++; returntrue;}
刪除運(yùn)算
Delete(i):刪除元素ai。
刪除運(yùn)算的平均時(shí)間復(fù)雜度分析:
設(shè)順序表長度為n,則刪除元素ai(i=0,…,n-1),要移動(dòng)n-i-1元素。若刪除表中每個(gè)元素的概率是相等的,即Qi=1/n,
template<classT>boolSeqList<T>::Delete(inti){//刪除元素ai
if(!n){ //下溢出檢查
cout<<"UnderFlow"<<endl;returnfalse;}if(i<0||i>n-1){ cout<<"OutOfBounds"<<endl;returnfalse;}//從前往后逐個(gè)前移元素
for(intj=i+1;j<n;j++)elements[j-1]=elements[j];
n--;returntrue;}
voidmain(){intx=10;SeqList<int>r(4);r.Insert(-1,x);r.Insert(-1,x);r.Output(cout);//??請(qǐng)復(fù)習(xí)C++,理解這一函數(shù)}線性表的順序存儲(chǔ)表示的優(yōu)缺點(diǎn)
優(yōu)點(diǎn):隨機(jī)存??;存儲(chǔ)空間利用率高。缺點(diǎn):插入、刪除效率低;必須按事先估計(jì)的最大元素個(gè)數(shù)分配連續(xù)的存儲(chǔ)空間,難以臨時(shí)擴(kuò)大。2.3線性表的鏈接表示2.3.1單鏈表鏈接存儲(chǔ)表示單鏈表的結(jié)點(diǎn)結(jié)構(gòu)單鏈表結(jié)構(gòu)elementlinka0a1a2an-1…first∧非空單鏈表first空單鏈表=>NULL指針變量的存儲(chǔ)單元紅色為結(jié)點(diǎn)的指針域
注意事項(xiàng)頭指針first是指向單鏈表的頭結(jié)點(diǎn)的指針最后一個(gè)結(jié)點(diǎn)的指針域?yàn)椋刂分禐?邏輯上相鄰的元素在物理上不一定相鄰不能出現(xiàn)“斷鏈”現(xiàn)象
結(jié)點(diǎn)類#include"linearlist.h"template<classT>classSingleList;//超前聲明template<classT>classNode{private:Telement;Node<T>*link;friendclassSingleList<T>;};elementlink
單鏈表類template<classT>classSingleList:publicLinearList<T>{public:SingleList(){first=NULL;n=0;}~SingleList();boolFind(inti,T&x)const;intSearch(Tx)const;boolInsert(inti,Tx);boolDelete(inti);……
…….private:
Node<T>*first;};
順序表類SeqList、單鏈表類SingleList是抽象線性表類LinearList類的派生類。SingleListLinearListSeqListNodefriend
構(gòu)造函數(shù)
SingleList(){first=NULL;n=0;}析構(gòu)函數(shù)
template<classT>SingleList<T>::~SingleList(){Node<T>*p;while(first){p=first->link;deletefirst;first=p;}}33/244單鏈表的類定義小結(jié)使用面向?qū)ο蠓椒?,要把?shù)據(jù)與操作一起定義和封裝,用多個(gè)類表達(dá)一個(gè)單鏈表。
鏈表結(jié)點(diǎn)(ListNode)類鏈表(SList)類定義方式(多種方式)
復(fù)合方式嵌套方式
繼承方式結(jié)構(gòu)方式34/244
classSList;
//復(fù)合方式
classListNode{
//鏈表結(jié)點(diǎn)類
friendclassSList;
//鏈表類為其友元類
private:
intdata;
//結(jié)點(diǎn)數(shù)據(jù),整型
ListNode*link;//結(jié)點(diǎn)指針
};classSList{ //鏈表類
private:ListNode*first;//表頭指針
};復(fù)合方式的類定義35/244classSList{//嵌套方式private:
classListNode{//嵌套鏈表結(jié)點(diǎn)類
public:
intdata;
ListNode*link;
};ListNode*first;
//表頭指針public:
//鏈表操作………};嵌套方式的類定義36/244//鏈表類和鏈表結(jié)點(diǎn)類定義(繼承方式)classListNode{
//鏈表結(jié)點(diǎn)類
protected:
intdata;
ListNode*link;
};classSList:public
classListNode{//鏈表類,繼承鏈表結(jié)點(diǎn)類的數(shù)據(jù)和操作
private:ListNode*first;//表頭指針};繼承方式的類定義37/244在復(fù)合方式中,鏈表結(jié)點(diǎn)類中聲明鏈表類是它的友元類,這樣可以“奉獻(xiàn)”它的私有成員給鏈表類。這種方式靈活。在嵌套方式中,鏈表結(jié)點(diǎn)類是鏈表類的私有成員,這樣限制了鏈表結(jié)點(diǎn)類的應(yīng)用范圍。在繼承方式中,鏈表類聲明為鏈表結(jié)點(diǎn)類的派生類,這在實(shí)現(xiàn)上是可行的。但在邏輯上是有問題的,如三角形is多邊形(繼承關(guān)系)鏈表is鏈表結(jié)點(diǎn)(顯然概念不準(zhǔn)確)
搜索運(yùn)算必須從頭指針開始沿鏈逐個(gè)計(jì)數(shù)查找,稱為順序查找
搜索運(yùn)算的平均、最壞的漸近時(shí)間復(fù)雜度:O(n)
template<classT>boolSingleList<T>::Find(inti,T&x)const{//在(a0,a1,...,an?1)中找下標(biāo)為i的元素aiif(i<0||i>n?1){ //對(duì)i進(jìn)行越界檢查
cout<<"OutOfBounds";returnfalse;}Node<T>*p=first;for(intj=0;j<i;j++)p=p->link;x=p->element;returntrue;}
插入運(yùn)算修改兩個(gè)指針域的值插入漸近時(shí)間復(fù)雜度:O(1)q->link=p->link;p->link=q;
插入運(yùn)算步驟:生成數(shù)據(jù)域?yàn)閤的新結(jié)點(diǎn),q指向新結(jié)點(diǎn);
從first開始找第i+1個(gè)結(jié)點(diǎn),p指向該結(jié)點(diǎn);將q插入p之后。
表長加1。
template<classT>boolSingleList<T>::Insert(inti,Tx){if(i<?1||i>n?1){cout<<"OutOfBounds";returnfalse;}Node<T>*q=newNode<T>;q->element=x; Node<T>*p=first; //找ai元素所在的結(jié)點(diǎn)pfor(intj=0;j<i;j++)p=p->link;firsta0a1a2an-1…∧非空單鏈表first空單鏈表pppi=2
if(i>?1){q->link=p->link; //新結(jié)點(diǎn)q插在p之后
p->link=q;}else{q->link=first;//新結(jié)點(diǎn)q插在頭結(jié)點(diǎn)之前
first=q;}n++;returntrue;}//刪除結(jié)點(diǎn)p是指刪除指針變量p所指示的結(jié)點(diǎn)*p。
單鏈表的刪除
只需修改一個(gè)指針“q->link=p->link”,但還需使用“deletep;”語句回收結(jié)點(diǎn)占用的空間。
單鏈表的步驟
從first開始找第i+1個(gè)結(jié)點(diǎn),p指向該結(jié)點(diǎn),q指向p之前驅(qū)結(jié)點(diǎn);
從單鏈表中刪除p;釋放p之空間;
表長減1。
template<classT>boolSingleList<T>::Delete(inti){if(!n){cout<<"UnderFlow"<<endl;returnfalse;}if(i<0||i>n-1){cout<<"OutOfBounds"<<endl;returnfalse;}Node<T>*p=first,*q=first;for(intj=0;j<i-1;j++)q=q->link;
if(i==0)first=first->link;//刪除頭結(jié)點(diǎn)
else{p=q->link;q->link=p->link;}deletep;n--;returntrue;}
單鏈表運(yùn)算的優(yōu)缺點(diǎn)優(yōu)點(diǎn)
單鏈表插入和刪除只需修改一兩個(gè)指針,無需移動(dòng)元素。如已知前驅(qū)結(jié)點(diǎn),插入刪除運(yùn)算的時(shí)間為O(1)
可以動(dòng)態(tài)分配結(jié)點(diǎn)空間,線性表的長度只受內(nèi)存大小限制。缺點(diǎn)
查找運(yùn)算費(fèi)時(shí),只能順序查找,不能隨機(jī)查找2.3.2帶表頭結(jié)點(diǎn)的單鏈表請(qǐng)區(qū)分“表頭結(jié)點(diǎn)”和“頭結(jié)點(diǎn)”template<classT>HeaderList<T>::HeaderList(){Node<T>*first=newNode<T>; first->link=NULL;n=0;}
template<classT>boolHeaderList<T>::Insert(inti,Tx){if(i<?1||i>n?1){cout<<"OutOfBounds"<<endl;returnfalse;}Node<T>*p=first; for(intj=0;j<=i;j++)p=p->link;Node<T>*q=newNode<T>;q->element=x;q->link=p->link; p->link=q;n++;returntrue;}
template<classT>boolHeaderList<T>::Delete(inti){if(!n){cout<<"UnderFlow"<<endl;returnfalse;}if(i<0||i>n?1){cout<<"OutOfBounds"<<endl;returnfalse;}Node<T>*q=first,*p; for(intj=0;j<i;j++)q=q->link;p=q->link; q->link=p->link; deletep; n--;returntrue;}2.3.3單循環(huán)鏈表2.3.4雙向鏈表
結(jié)點(diǎn)類template<classT>classDoubleList; //超前聲明template<classT> classDNode{private:Telement;DNode<T>*lLink,*rLink;friendDoubleList<T>;};
插入操作的核心步驟如下:(1)DNode<T>*q=newDNode<T>;q->element=x;(2)q->lLink=p->lLink;q->rLink=p;p->lLink->rLink=q;p->lLink=q;錯(cuò)誤:p->lLink->rLink=q;q->lLink=p->lLink;q->rLink=p;p->lLink=q;
刪除操作的核心步驟如下:(1)p->lLink->rLink=p->rLink;p->rLink->lLink=p->lLink;(2)deletep;2.4多項(xiàng)式的算術(shù)運(yùn)算
多項(xiàng)式相加
p(x)=3x14?8x8+6x2+2q(x)=2x10+4x8?6x2
q(x)p(x)+q(x)結(jié)果:q(x)=3x14+2x10?4x8+2
多項(xiàng)式的邏輯結(jié)構(gòu):視為線性表
p(x)=3x14-8x8+6x2+2
數(shù)據(jù)元素(coef,exp)
表示多項(xiàng)式項(xiàng)coef·xexp,coef是該項(xiàng)的系數(shù),exp是變?cè)獂的指數(shù)。
多項(xiàng)式的存儲(chǔ)表示
p(x)=3x14-8x8+6x2+2((3,14),(-8,8),(6,2),(2,0))
順序表示
線性表長度事先難以確定;算術(shù)運(yùn)算需插入和刪除元素。
多項(xiàng)式的鏈接表示多項(xiàng)式的項(xiàng)
2.4.1
項(xiàng)結(jié)點(diǎn)類項(xiàng)結(jié)點(diǎn)類
Term*InsertAfter(intc,inte)構(gòu)造一個(gè)新項(xiàng)(c,e)結(jié)點(diǎn),插在*this項(xiàng)之后,函數(shù)返回新項(xiàng)結(jié)點(diǎn)的地址。
classTerm{public:Term(intc,inte);//構(gòu)造函數(shù)1Term(intc,inte,Term*nxt);//構(gòu)造函數(shù)2Term*InsertAfter(intc,inte);private:intcoef;intexp;Term*link;friendostream&operator<<(ostream&,constTerm&);//重載“<<”,輸出多項(xiàng)式的一項(xiàng)
friendclassPolynominal;};
構(gòu)造函數(shù)Term::Term(intc,inte):coef(c),exp(e){link=0;}Term::Term(intc,inte,Term*nxt):coef(c),exp(e){link=nxt;}Term::Term(intc,inte){coef=c;exp=e;link=0;}
InsertAfter函數(shù)實(shí)現(xiàn)Term*Term::InsertAfter(intc,inte){link=newTerm(c,e,link); returnlink;}調(diào)用語句:q=q->InsertAfter(c,e);
重載輸出運(yùn)算符ostream&operator<<(ostream&out,constTerm&val){//用-4x^2表示-4x2。
if(val.coef=
=0)returnout;out<<val.coef;switch(val.exp){case0:break;case1:out<<"X";break;default:out<<"X^"<<val.exp;break;}returnout;}2.4.3
多項(xiàng)式的C++類classPolynominal{public:Polynominal();
~Polynominal();voidAddTerms(istream&in);//建立多項(xiàng)式鏈表
voidOutput(ostream&out)const;//輸出多項(xiàng)式
voidPolyAdd(Polynominal&r); //多項(xiàng)式相加
…
private:
Term*theList; //單循環(huán)鏈表的表頭指針
friendostream&operator<<(ostream&,constPolynominal&);friendistream&operator>>(istream&,Polynominal&);friendPolynominal&operator+(Polynominal&,Polynominal&);};2.4.4
多項(xiàng)式類的實(shí)現(xiàn)
構(gòu)造函數(shù)Polynominal::Polynominal() {theList=newTerm(0,?1);theList->link=theList; }2.4.5多項(xiàng)式的輸入和輸出輸入多項(xiàng)式voidPolynominal::AddTerms(istream&in){
Term*q=theList;intc,e;for(;;){ cout<<"Inputaterm(coef,exp):\n"<<endl;in>>c>>e; if(e<0)break;q=q->InsertAfter(c,e);}}
輸出多項(xiàng)式voidPolynominal::Output(ostream&out)const{boolstart=true;Term*p=theList->link;out<<"Thepolynominalis:\n"<<endl;for(;p!=theList;p=p->link){if(!start&&p->coef>0)out<<'+';start=false;out<<*p;}out<<endl;}
多項(xiàng)式相加
若p->exp==q->exp,則同類項(xiàng)合并,令q->coef=q->coef+p->coef;如果此時(shí)有q->coef==0,則從q(x)中刪除結(jié)點(diǎn)*q,指針q指向原*q的后繼,指針p指向下一項(xiàng);否則,指針p、q和q1均后移一項(xiàng)。若p->exp>q->exp,則復(fù)制*p,新結(jié)點(diǎn)插在*q1與*q之間,指針q1指向新結(jié)點(diǎn),指針q不動(dòng),而指針p指向下一項(xiàng)。若p->exp<q->exp,則將q指示的當(dāng)前項(xiàng)保留在q(x)中,所以令指針q1和q后移一項(xiàng),指針p不動(dòng)。
voidPolynominal::PolyAdd(Polynominal&r)//將多項(xiàng)式r加到多項(xiàng)式this上{Term*q,*q1=theList,*p;p=r.theList->link;q=q1->link;while(p->exp>=0){while(p->exp<q->exp){q1=q;q=q->link;}
if(p->exp==q->exp){q->coef=q->coef+p->coef;if(q->coef==0){q1->link=q->li
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 工作室《高中生職業(yè)生涯規(guī)劃教育內(nèi)容及途徑的行動(dòng)研究》開題報(bào)告初稿
- 借款合同個(gè)人協(xié)議書七篇
- 二婚離婚協(xié)議范本模板
- 《再塑生命的人》課件統(tǒng)編版語文七年級(jí)上冊(cè)
- 藥物性蕁麻疹病因介紹
- 中考政治總復(fù)習(xí)第四單元自然界的水教材知識(shí)梳理
- (立項(xiàng)備案申請(qǐng)模板)雕塑品項(xiàng)目可行性研究報(bào)告參考范文
- (案例)塑膠容器項(xiàng)目立項(xiàng)報(bào)告
- (2024)芒硝礦項(xiàng)目可行性研究報(bào)告寫作范本(一)
- 專題23 走進(jìn)法治天地 (講義)(原卷版)
- 中國農(nóng)業(yè)歷史文化智慧樹知到期末考試答案章節(jié)答案2024年西北農(nóng)林科技大學(xué)
- 中醫(yī)美容智慧樹知到期末考試答案章節(jié)答案2024年廣西中醫(yī)藥大學(xué)
- 水生產(chǎn)企業(yè)(自來水公司)安全生產(chǎn)風(fēng)險(xiǎn)分級(jí)管控和隱患排查治理雙體系方案全套資料(2021-2022版)
- 包莖環(huán)切手術(shù)后的護(hù)理
- 曹禺生平簡(jiǎn)介
- 在線網(wǎng)課知慧《邏輯學(xué)(山盟-德州)》單元測(cè)試考核答案
- (正式版)JBT 14449-2024 起重機(jī)械焊接工藝評(píng)定
- MOOC 國際貿(mào)易實(shí)務(wù)-上海對(duì)外經(jīng)貿(mào)大學(xué) 中國大學(xué)慕課答案
- 《混凝土粘度改性劑》
- YYT 1849-2022 重組膠原蛋白
- 2024年廣東深圳市龍崗金融投資控股有限公司招聘筆試參考題庫含答案解析
評(píng)論
0/150
提交評(píng)論