




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
線性表順序表鏈表順序表與鏈表的比較第二章線性表線性表(LinearList)線性表的定義和特點(diǎn)
定義
n(0)個(gè)數(shù)據(jù)元素的有限序列,記作
(a1,a2,…,an)
ai
是表中數(shù)據(jù)元素,n是表長度。
遍歷逐項(xiàng)訪問:
從前向后從后向前線性表的特點(diǎn)除第一個(gè)元素外,其他每一個(gè)元素有一個(gè)且僅有一個(gè)直接前驅(qū)。除最后一個(gè)元素外,其他每一個(gè)元素有一個(gè)且僅有一個(gè)直接后繼。a1a2a3a4a5a6順序表(SequentialList)順序表的定義和特點(diǎn)
定義將線性表中的元素相繼存放在一個(gè)連續(xù)的存儲空間中??衫靡痪S數(shù)組描述存儲結(jié)構(gòu)特點(diǎn)
線性表的順序存儲方式
遍歷順序訪問,可以隨機(jī)存取
253457164809
012345data順序表的連續(xù)存儲方式352749186054778341020123456789llll
l
lllll
LOC(i)=LOC(i-1)+l=a+i*lLOC(i)=
LOC(i-1)+l=a+i*l,i>0
a,i=0
a+i*la順序表(SeqList)的定義#defineListSize100//最大允許長度typedefintListData;typedefstruct
{
ListData*data;
//存儲數(shù)組
intlength; //當(dāng)前元素個(gè)數(shù)}SeqList;
順序表基本運(yùn)算的實(shí)現(xiàn)構(gòu)造一個(gè)空的順序表
voidInitList
(
SeqList&L){
L.data=(ListData*)
malloc
(ListSize*
sizeof(ListData)
);if(L.data==NULL){
printf
(“存儲分配失敗!\n”
);exit(1);}L.length=0;}求表的長度
int
Length(SeqList&L){returnL.length;
}
提取函數(shù):在表中提取第i個(gè)元素的值
ListData
GetData(SeqList
&L,int
i){
if(i>=0&&i<L.length)
returnL.data[i];
else
printf(“參數(shù)
i不合理!\n”); }
//在出錯(cuò)情況,函數(shù)返回值不能用!按值查找:在順序表中從頭查找結(jié)點(diǎn)值等于給定值x
的結(jié)點(diǎn)
int
Find(SeqList&L,ListDatax){
int
i=0;while(i<L.length&&L.data[i]!=x)i++;if(i<L.length)returni;elsereturn-1;}順序查找圖示253457164809
012345data查找
16i253457164809
i253457164809
i253457164809
i查找成功2534571648
01234data查找
50i2534571648
i2534571648
i2534571648
i2534571648
i查找失敗查找成功的平均比較次數(shù)
若查找概率相等,則
查找不成功數(shù)據(jù)比較n
次表項(xiàng)的插入2534571648096301234567data50插入x253457501648096301234567data50i
表項(xiàng)的插入
int
Insert(SeqList
&L,ListDatax,
inti){//在表中第
i個(gè)位置插入新元素
x
if(i<0
||
i>L.length
||L.length==
ListSize)
return0;//插入不成功
else{
for(
intj=L.length;j>i;j--)L.data[j]=L.data[j-1]; L.data[i]=x;L.length++;
return1;
//插入成功
}}表項(xiàng)的刪除253457501648096301234567data16刪除
x2534575048096301234567data
表項(xiàng)的刪除
int
Delete(SeqList
&L,ListDatax){
//在表中刪除已有元素
x
int
i=Find(L,x);
//在表中查找
x
if(i>=0){ L.length--
; for(
intj=i;j<L.length;j++)L.data[j]=L.data[j+1];
return1; //成功刪除
}
return0;//表中沒有
x}順序表的應(yīng)用:集合的“并”運(yùn)算voidUnion(SeqList
&A,SeqList
&B){
int
n=Length(A);
intm=Length(B);
for(
inti=0;i<m;i++){
intx=GetData(B,i);//在B中取一元素
int
k=Find(A,x);
//在A中查找它
if(k==
-1)
//若未找到插入它
{Insert(A,x,n);n++;}
}}
voidIntersection(SeqList
&A,SeqList
&B){
int
n=Length(A);
intm=Length(B);int
i=0;
while(i<n){
intx=GetData(A,i);//在A中取一元素
int
k=Find(B,x);//在B中查找它
if(k==-1){Delete(A,i);n--;} elsei++;//未找到在A中刪除它}}順序表的應(yīng)用:集合的“交”運(yùn)算鏈表(LinkedList)鏈接表是線性表的鏈接存儲表示單鏈表靜態(tài)鏈表
循環(huán)鏈表雙向鏈表單鏈表(SinglyLinkedList)特點(diǎn)
每個(gè)元素(表項(xiàng))由結(jié)點(diǎn)(Node)構(gòu)成。線性結(jié)構(gòu)
結(jié)點(diǎn)可以連續(xù),可以不連續(xù)存儲結(jié)點(diǎn)的邏輯順序與物理順序可以不一致表可擴(kuò)充datalinka0a1a2a3a4first單鏈表的存儲映像free(a)可利用存儲空間a0a2a1a3freefirst(b)經(jīng)過一段運(yùn)行后的單鏈表結(jié)構(gòu)單鏈表的定義typedefchar
ListData;typedefstructnode{
//鏈表結(jié)點(diǎn)
ListDatadata;
//結(jié)點(diǎn)數(shù)據(jù)域
struct
node*link;
//結(jié)點(diǎn)鏈域}ListNode;typedef
ListNode*LinkList;//鏈表頭指針LinkListfirst;//鏈表頭指針單鏈表中的插入與刪除插入
第一種情況:在第一個(gè)結(jié)點(diǎn)前插入
newnode->link=first;
first=newnode;(插入前)(插入后)
firstnewnodenewnodefirst
(插入前)(插入后)
第二種情況:在鏈表中間插入
newnode->link=p->link; p->link=newnode;newnodepnewnodep
第三種情況:在鏈表末尾插入
newnode->link=p->link; p->link=newnode;(插入前)(插入后)newnodenewnodeppint
Insert(LinkList&first,
intx,int
i){//在鏈表第
i個(gè)結(jié)點(diǎn)處插入新元素
x
ListNode*p=first;intk=0;while(
p!=NULL&&k<i-1)
{p=p->link;k++;
}
//找第i-1個(gè)結(jié)點(diǎn)
if(p==NULL&&first!=NULL){
printf(“無效的插入位置!\n”);return0;}
ListNode*newnode=
//創(chuàng)建新結(jié)點(diǎn)(ListNode*)malloc
(
sizeof(ListNode));
newnode->data=x;if(first==NULL||i==1){
//插在表前
newnode->link=first;
first=newnode;}else{
//插在表中或末尾
newnode->link=p->link;p->link=newnode;}
return1;
}刪除第一種情況:刪除表中第一個(gè)元素第二種情況:刪除表中或表尾元素在單鏈表中刪除含ai的結(jié)點(diǎn)ai-1ai-1aiaiai+1ai+1pq刪除前刪除后intDelete(LinkList&first,inti){//在鏈表中刪除第i個(gè)結(jié)點(diǎn)
ListNode*p,*q;if(i==1)
//刪除表中第1個(gè)結(jié)點(diǎn)
{q=first;first=first->link;}
else{
p=first;intk=0;
//找第i-1個(gè)結(jié)點(diǎn)
while(p!=NULL&&k<i-1)
{p=p->link;
k++;
}
if(p==NULL||p->link==NULL){
printf(“無效的刪除位置!\n”);return0;
}else{
//刪除表中或表尾元素
q=p->link;
//重新鏈接
p->link=q->link;
}}free(q);
//刪除q
return1;
}帶表頭結(jié)點(diǎn)的單鏈表表頭結(jié)點(diǎn)位于表的最前端,本身不帶數(shù)據(jù),僅標(biāo)志表頭。設(shè)置表頭結(jié)點(diǎn)的目的是統(tǒng)一空表與非空表的操作簡化鏈表操作的實(shí)現(xiàn)。非空表
空表0ana1firstfirst0在帶表頭結(jié)點(diǎn)的單鏈表第一個(gè)結(jié)點(diǎn)前插入新結(jié)點(diǎn)
newnode->link=p->link;p->link=newnode;firstnewnodefirstnewnode插入firstnewnode0firstnewnode0插入pppp
q=p->link;p->link=q->link;deleteq;
從帶表頭結(jié)點(diǎn)的單鏈表中刪除第一個(gè)結(jié)點(diǎn)firstfirst(非空表)first0first(空表)0pqpq前插法建立單鏈表從一個(gè)空表開始,重復(fù)讀入數(shù)據(jù):生成新結(jié)點(diǎn)將讀入數(shù)據(jù)存放到新結(jié)點(diǎn)的數(shù)據(jù)域中將該新結(jié)點(diǎn)插入到鏈表的前端直到讀入結(jié)束符為止。firstnewnodefirstnewnode00LinkListcreateListF(void){charch;
ListNode*s;
LinkListhead=//建立表頭結(jié)點(diǎn)(LinkList)malloc
(sizeof(ListNode));head->link=NULL;while((ch=getchar())!=‘\n’){s=(listNode*)malloc(sizeof(ListNode));s->data=ch;
//建立新結(jié)點(diǎn)
s->link=head->link;
//插入到表前端
head->link=s;
}
returnhead;}
后插法建立單鏈表每次將新結(jié)點(diǎn)加在鏈表的表尾;設(shè)置一個(gè)尾指針r,總是指向表中最后一個(gè)結(jié)點(diǎn),新結(jié)點(diǎn)插在它的后面;尾指針r初始時(shí)置為指向表頭結(jié)點(diǎn)地址。00newnodefirstnewnode00rrrrLinkListcreateListR(void){charch;
LinkListhead=//建立表頭結(jié)點(diǎn)(LinkList)malloc
(sizeof(ListNode));
ListNode*s,*r=head;
//r指向表尾
while((ch=getchar())!=‘\n’){s=(listNode*)malloc(sizeof(ListNode));s->data=ch;
//建立新結(jié)點(diǎn)
r->link=s;r=s;
//插入到表末端
}
r->link=NULL;
//表收尾
returnhead;}
firstqfirstfirstqqfirsta0a1a1a2a2a2單鏈表清空單鏈表清空voidmakeEmpty(LinkListfirst){//刪去鏈表中除表頭結(jié)點(diǎn)外的所有其他結(jié)點(diǎn)
ListNode*q;
while(first->link!=NULL){
q=first->link;first->link=q->link;
//將表頭結(jié)點(diǎn)后第一個(gè)結(jié)點(diǎn)從鏈中摘下
free(q);
//釋放它
}
}firstpa0a1a2c=0firstpa0a1a2c=1firstpa0a1a2c=2firstpa0a1a2c=3計(jì)算單鏈表長度int
Length(LinkListfirst){
ListNode*p=first->link;
//檢測指針p
指示第一個(gè)結(jié)點(diǎn)
int
count=0;
while(p!=NULL){
//逐個(gè)結(jié)點(diǎn)檢測
p=p->link;count++;}
returncount;}計(jì)算單鏈表長度ListNode
*Find(LinkListfirst,ListData
value
){//在鏈表中從頭搜索其數(shù)據(jù)值為value的結(jié)點(diǎn)
ListNode*p=first->link;
//檢測指針
p
指示第一個(gè)結(jié)點(diǎn)
while(p!=NULL&&p->data!=value)
p=p->link;
returnp;}在單鏈表中按值查找ListNode*Locate(LinkListfirst,
inti){//返回表中第i
個(gè)元素的地址
if(i<0)returnNULL;
//i值不合理
ListNode*p=first;
int
k=0;//置于表頭
while(p!=NULL&&k<i)
{p
=p->link;k++;}
//找第i個(gè)結(jié)點(diǎn)
if(k==i)returnp;
elsereturnNULL;//返回第i個(gè)結(jié)點(diǎn)地址或NULL}在單鏈表中按序號查找(定位)在單鏈表中插入新結(jié)點(diǎn)
newnode->link=p->link;p->link=newnode;firstnewnodefirstnewnode插入newnodenewnode插入ppppintInsert(LinkListfirst,ListDatax,
int
i){//將新元素x插入在鏈表中第i
號結(jié)點(diǎn)位置
ListNode*p=Locate(first,i-1);
if(p==NULL)return0; //不插入
ListNode*newnode=
//創(chuàng)建新結(jié)點(diǎn)(ListNode*)malloc
(sizeof(ListNode));
newnode->data=x;
newnode->link=p->link;//鏈入
p->link=newnode;return1;
//插入成功,函數(shù)返回1}在單鏈表中插入新元素在單鏈表中刪除一個(gè)結(jié)點(diǎn)
q=p->link;p->link=q->link;deleteq;
first0firstpppqqqintdelete(LinkListfirst,int
i){//將鏈表第i
號元素刪去
ListNode*p=Locate(first,i-1);
//尋找被刪結(jié)點(diǎn)的前驅(qū)結(jié)點(diǎn)
if(p==NULL||p->link==NULL)
return0; //不刪除
ListNode*q=p->link;
//被刪結(jié)點(diǎn)地址
p->link=q->link;
//摘下被刪結(jié)點(diǎn)
free(q
);
//釋放
returnl;}在單鏈表中刪除一個(gè)結(jié)點(diǎn)【例】單鏈表求和函數(shù)
typedefint
ListData;
intsum(LinkListls){
ListNode*p=
ls->link;
intretvalue=0;while(p!=NULL){
retvalue+=p->data;//
累加
p=p->link;}
returnretvalue; }循環(huán)鏈表(CircularList)循環(huán)鏈表是單鏈表的變形。循環(huán)鏈表最后一個(gè)結(jié)點(diǎn)的link
指針不為NULL,而是指向了表的前端。為簡化操作,在循環(huán)鏈表中往往加入表頭結(jié)點(diǎn)。循環(huán)鏈表的特點(diǎn)是:只要知道表中某一結(jié)點(diǎn)的地址,就可搜尋到所有其他結(jié)點(diǎn)的地址。循環(huán)鏈表的示例帶表頭結(jié)點(diǎn)的循環(huán)鏈表
a0a1a2an-1firstan-1firsta1a0first(空表)(非空表)查找成功查找不成功循環(huán)鏈表的查找firstfirst3131484815155757查找15查找25pppppppp循環(huán)鏈表的定義typedefchar
ListData;typedefstructcnode
{
//鏈表結(jié)點(diǎn)
ListDatadata;
//結(jié)點(diǎn)數(shù)據(jù)域
structcnode*link;
//結(jié)點(diǎn)鏈域}CircListNode;typedef
CircListNode*CircLinkList;//循環(huán)鏈表頭指針CircLinkListfirst;//循環(huán)鏈表頭指針循環(huán)鏈表的查找算法CircListNode
*Find(CircLinkListfirst,ListData
value
){//在鏈表中從頭搜索其數(shù)據(jù)值為value的結(jié)點(diǎn)
CircListNode*p=first->link;
//檢測指針
p
指示第一個(gè)結(jié)點(diǎn)
while(p!=first&&p->data!=value)
p=p->link;
returnp;}帶尾指針的循環(huán)鏈表rear3148155722
如果插入與刪除僅在鏈表的兩端發(fā)生,可采用帶表尾指針的循環(huán)鏈表結(jié)構(gòu)。在表尾插入,時(shí)間復(fù)雜性O(shè)(1)
在表尾刪除,時(shí)間復(fù)雜性O(shè)(n)
在表頭插入,相當(dāng)于在表尾插入在表頭刪除,時(shí)間復(fù)雜性O(shè)(1)將循環(huán)鏈表鏈入單鏈表鏈頭rear1520253010first60657055rear1520253010p60657055first雙向鏈表(DoublyLinkedList)雙向鏈表是指在前驅(qū)和后繼方向都能游歷(遍歷)的線性鏈表。雙向鏈表每個(gè)結(jié)點(diǎn)結(jié)構(gòu):
雙向鏈表通常采用帶表頭結(jié)點(diǎn)的循環(huán)鏈表形式。前驅(qū)方向
后繼方向priordata
next結(jié)點(diǎn)指向
p==p->prior->next==p->next->prior非空表
空表p->priorp->nextppriornextfirstfirst雙向循環(huán)鏈表的定義typedefintListData;typedefstructdnode
{
ListNodedata;//數(shù)據(jù)
structdnode*prior,*next;//指針}DblNode;typedefDblNode*DblList;//雙向鏈表
建立空的雙向循環(huán)鏈表void
CreateDblList(DblList&
first){
first=(DblNode*)malloc
(sizeof
(DblNode));
if(first==NULL)
{print(“存儲分配錯(cuò)!\n”);exit(1);}first->prior=first->next=first;
//表頭結(jié)點(diǎn)的鏈指針指向自己}計(jì)算雙向循環(huán)鏈表的長度int
Length(DblListfirst){//計(jì)算帶表頭結(jié)點(diǎn)的雙向循環(huán)鏈表的長度
DblNode*p=first->next;
intcount=0;
while(p!=first)
{p=p->next;count++;
}returncount;}查找成功查找不成功雙向循環(huán)鏈表的查找firstfirst3131484815155757查找15查找25ListNode*Find(DblListfirst,ListDatax){//在雙向循環(huán)鏈表中搜索含x的結(jié)點(diǎn),
若找到,//則返回該結(jié)點(diǎn)的地址,否則返回表頭地址。
DblNode*p=first->next;
while(p!=first&&p->data!=x)
p=p->next; returnp;}//也可以在prior(前驅(qū))方向查找,程序類似。DblNode*Locate(DblListfirst,int
i){
if(i<0)returnfirst;
DblNode*p=first->next;intj=1;
while(p!=first&&j<i)
{p=p->next;j++;}returnp;}//也可以在prior(前驅(qū))方向查找,程序類似。定位:查找第i個(gè)結(jié)點(diǎn)在鏈中的位置雙向
溫馨提示
- 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五年度教育培訓(xùn)檔口租賃合同
- T-ZJCX 0046-2024 簾子線直捻機(jī)
- 二零二五年度公車私用行為規(guī)范與責(zé)任追究協(xié)議
- 二零二五年度全新碼頭租賃協(xié)議及倉儲服務(wù)合作協(xié)議
- 2025年度果園租賃與農(nóng)業(yè)科技研發(fā)合同
- 二零二五年度廣告代理合同解除與權(quán)益調(diào)整協(xié)議
- 2025年度高科技企業(yè)計(jì)件工資勞動(dòng)合同
- 2025年度智能合同履約跟蹤與風(fēng)險(xiǎn)控制管理辦法
- 2025年度消防設(shè)施定期維護(hù)與消防通道清理合同
- 二零二五年度美發(fā)店員工勞動(dòng)健康保險(xiǎn)與意外傷害合同
- 學(xué)校食品安全長效管理制度
- 滋補(bǔ)品項(xiàng)目效益評估報(bào)告
- 提綱作文(解析版)- 2025年天津高考英語熱點(diǎn)題型專項(xiàng)復(fù)習(xí)
- 2025年南京機(jī)電職業(yè)技術(shù)學(xué)院高職單招數(shù)學(xué)歷年(2016-2024)頻考點(diǎn)試題含答案解析
- 2025年春新人教版歷史七年級下冊全冊課件
- 2025年浙江臺州機(jī)場管理有限公司招聘筆試參考題庫含答案解析
- 《中式風(fēng)格陳設(shè)》課件
- 《汽車空調(diào)工作原理》課件
- 2024年鄭州黃河護(hù)理職業(yè)學(xué)院單招職業(yè)技能測試題庫及解析答案
- 2025屆廣東省佛山一中石門中學(xué)高考沖刺押題(最后一卷)數(shù)學(xué)試卷含解析
- 2024-2030年中國氣象服務(wù)行業(yè)深度調(diào)查及投資戰(zhàn)略建議報(bào)告
評論
0/150
提交評論