版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
數(shù)據(jù)結構課件西北大學計算機系本演示文稿可能包含觀眾討論和即席反應。使用PowerPoint可以跟蹤演示時的即席反應,在幻燈片放映中,右鍵單擊鼠標請選擇“會議記錄”選擇“即席反應”選項卡必要時輸入即席反應單擊“確定”撤消此框此動作將自動在演示文稿末尾創(chuàng)建一張即席反應幻燈片,包括您的觀點。
6/10/20231第2章
線性表
2.1線性表的概念及運算2.2線性表的順序存儲2.3線性表的鏈式存儲2.4一元多項式的表示及相加6/10/202322.1線性表的概念及運算2.1.1線性表的邏輯結構
2.1.2線性表的抽象數(shù)據(jù)類型定義
6/10/20233線性表的定義線性表(LinearList)是由n(n≥0)個類型相同的數(shù)據(jù)元素a1,a2,…,an組成的有限序列,記做(a1,a2,…,ai-1,ai,ai+1,…,an)。
數(shù)據(jù)元素之間是一對一的關系,即每個數(shù)據(jù)元素最多有一個直接前驅和一個直接后繼。線性表的邏輯結構圖為:
6/10/20234線性表的特點同一性:線性表由同類數(shù)據(jù)元素組成,每一個ai必須屬于同一數(shù)據(jù)對象。有窮性:線性表由有限個數(shù)據(jù)元素組成,表長度就是表中數(shù)據(jù)元素的個數(shù)。有序性:線性表中相鄰數(shù)據(jù)元素之間存在著序偶關系<ai,ai+1>。
6/10/202352.1.2線性表的抽象數(shù)據(jù)類型定義抽象數(shù)據(jù)類型定義
:ADTLinearList{ 數(shù)據(jù)元素:D={ai|ai∈D0,i=1,2,…,n
n≥0,D0為某一數(shù)據(jù)對象}關系:S={<ai,ai+1>|ai,ai+1∈D0,i=1,2,…,n-1}基本操作:(1)InitList(L)操作前提:L為未初始化線性表。 操作結果:將L初始化為空表。(2)DestroyList(L)操作前提:線性表L已存在。操作結果:將L銷毀。(3)ClearList(L)操作前提:線性表L已存在
。操作結果:將表L置為空表?!瓆ADT
LinearList6/10/202362.2線性表的順序存儲2.2.1線性表的順序存儲結構
2.2.2線性表順序存儲結構上的基本運算
6/10/20237順序存儲結構的定義
線性表的順序存儲是指用一組地址連續(xù)的存儲單元依次存儲線性表中的各個元素,使得線性表中在邏輯結構上相鄰的數(shù)據(jù)元素存儲在相鄰的物理存儲單元中,即通過數(shù)據(jù)元素物理存儲的相鄰關系來反映數(shù)據(jù)元素之間邏輯上的相鄰關系。采用順序存儲結構的線性表通常稱為順序表。假設線性表中每個元素占k個單元,第一個元素的地址為loc(a1),則第k個元素的地址為: loc(ai)=loc(a1)+(i-1)×k 6/10/20238順序存儲結構示意圖存儲地址
內存空間狀態(tài)
邏輯地址
Loc(a1)a11Loc(a1)+(2-1)ka2
2………loc(a1)+(i-1)kai
i………loc(a1)+(n-1)kan
n...
loc(a1)+(maxlen-1)k空閑6/10/20239順序存儲結構的C語言定義#define maxsize=線性表可能達到的最大長度;typedefstruct{ElemTypeelem[maxsize];/*線性表占用的數(shù)組空間*/intlast;/*記錄線性表中最后一個元素在數(shù)組elem[]中的位置(下標值),空表置為-1*/}SeqList;
注意區(qū)分元素的序號和數(shù)組的下標,如a1的序號為1,而其對應的數(shù)組下標為0。
6/10/2023102.2.2線性表順序存儲結構的基本運算線性表的基本運算:查找操作
插入操作
刪除操作順序表合并算法線性表順序存儲結構的優(yōu)缺點分析6/10/202311查找操作線性表的兩種基本查找運算按序號查找GetData(L,i):要求查找線性表L中第i個數(shù)據(jù)元素,其結果是L.elem[i-1]或L->elem[i-1]。按內容查找Locate(L,e):
要求查找線性表L中與給定值e相等的數(shù)據(jù)元素,其結果是:若在表L中找到與e相等的元素,則返回該元素在表中的序號;若找不到,則返回一個“空序號”,如-1。線性表的查找運算算法描述為:6/10/202312線性表的查找運算intLocate(SeqListL,ElemTypee){ i=0;/*i為掃描計數(shù)器,初值為0,即從第一個元素開始比較*/while((i<=L.last)&&(L.elem[i]!=e)
)i++;/*順序掃描表,直到找到值為key的元素,或掃描到表尾而沒找到*/if(i<=L.last)return(i);/*若找到值為e的元素,則返回其序號*/
else return(-1);/*若沒找到,則返回空序號*/}6/10/202313插入操作線性表的插入運算是指在表的第i(1≤i≤n+1)個位置,插入一個新元素e,使長度為n的線性表(e1,…,ei-1,ei,…,en)變成長度為n+1的線性表(e1,…,ei-1,e,ei,…,en)。
線性表的插入運算算法。6/10/202314插入算法示意圖
已知:線性表(4,9,15,28,30,30,42,51,62),需在第4個元素之前插入一個元素“21”。則需要將第9個位置到第4個位置的元素依次后移一個位置,然后將“21”插入到第4個位置,序號移動元素插入元素12345678109491528303042516249152830304262514915212830304262516/10/202315插入運算intInsList(SeqList*L,inti,ElemTypee){intk;if((i<1)||(i>L->last+2))/*首先判斷插入位置是否合法*/{printf(“插入位置i值不合法”);return(ERROR);}if(L->last>=maxsize-1){printf(“表已滿無法插入”);return(ERROR);}for(k=L->last;k>=i-1;k--)/*為插入元素而移動位置*/L->elem[k+1]=L->elem[k];L->elem[i-1]=e;/*在C語言中數(shù)組第i個元素的下標為i-1*/
L->last++;return(OK);} 算法演示(此處連接算法演示程序)。6/10/202316刪除操作
線性表的刪除運算是指將表的第i(1≤i≤n)個元素刪去,使長度為n的線性表(e1,…,ei-1,ei,ei+1,…,en),變成長度為n-1的線性表(e1,…,ei-1,ei+1,…,en)。
算法思路示意
算法實現(xiàn)6/10/202317刪除算法示意
將線性表(4,9,15,21,28,30,30,42,51,62)中的第5個元素刪除。
序號123456781094915212830304262514915213030425162刪除28后6/10/202318刪除算法
intDelList(SeqList*L,inti,ElemType*e)/*在順序表L中刪除第i個數(shù)據(jù)元素,并用指針參數(shù)e返回其值*/{intk;if((i<1)||(i>L->last+1)){printf(“刪除位置不合法!”);return(ERROR);}*e=L->elem[i-1];
/*將刪除的元素存放到e所指向的變量中*/for(k=i;i<=L->last;k++)L->elem[k-1]=L->elem[k];/*將后面的元素依次前移*/L->last--;return(OK);}
6/10/202319合并算法已知
:有兩個順序表LA和LB,其元素均為非遞減有序排列,編寫一個算法,將它們合并成一個順序表LC,要求LC也是非遞減有序排列。
算法思想:設表LC是一個空表,為使LC也是非遞減有序排列,可設兩個指針i、j分別指向表LA和LB中的元素,若LA.elem[i]>LB.elem[j],則當前先將LB.elem[j]插入到表LC中,若LA.elem[i]≤LB.elem[j],當前先將LA.elem[i]插入到表LC中,如此進行下去,直到其中一個表被掃描完畢,然后再將未掃描完的表中剩余的所有元素放到表LC中。算法實現(xiàn)此處連接算法演示6/10/202320順序表合并算法實現(xiàn)voidmerge(SeqList*LA,SeqList*LB,SeqList*LC){i=0;j=0;k=0;while(i<=LA->last&&j<=LB->last)if(LA->elem[i]<=LB->elem[j])
{
LC->elem[k]=LA->elem[i];i++;k++;}
else
{
LC->elem[k]=LB->elem[j];j++;k++;}while(i<=LA->last)
/*當表LA長則將表LA余下的元素賦給表LC*/
{
LC->elem[k]=LA->elem[i];
i++;k++;}while(j<=LB->last)/*當表LB長則將表LB余下的元素賦給表LC*/
{
LC->elem[k]=LB->elem[j];
j++;k++;}
LC->last=LA->last+LB->last;}6/10/202321順序存儲結構的優(yōu)點和缺點優(yōu)點:1.無需為表示結點間的邏輯關系而增加額外的存儲空間;
2.可方便地隨機存取表中的任一元素。
缺點:1.插入或刪除運算不方便,除表尾的位置外,在表的其它位置上進行插入或刪除操作都必須移動大量的結點,其效率較低;
2.由于順序表要求占用連續(xù)的存儲空間,存儲分配只能預先進行靜態(tài)分配。因此當表長變化較大時,難以確定合適的存儲規(guī)模。6/10/2023222.3線性表的鏈式存儲鏈表定義:
采用鏈式存儲結構的線性表稱為鏈表。現(xiàn)在我們從兩個角度來討論鏈表:1.從實現(xiàn)角度看,鏈表可分為動態(tài)鏈表和靜態(tài)鏈表;2.從鏈接方式的角度看,鏈表可分為單鏈表、循環(huán)鏈表和雙鏈表。
6/10/2023232.3.1單鏈表
2.3.2單鏈表上的基本運算
2.3.3循環(huán)鏈表
2.3.4雙向鏈表
*2.3.5靜態(tài)鏈表
2.3.6順序表和鏈表的比較鏈表6/10/2023242.3.1單鏈表
結點(Node)為了正確地表示結點間的邏輯關系,必須在存儲線性表的每個數(shù)據(jù)元素值的同時,存儲指示其后繼結點的地址(或位置)信息,這兩部分信息組成的存儲映象叫做結點(Node)。單鏈表:鏈表中的每個結點只有一個指針域,我們將這種鏈表稱為單鏈表。單鏈表包括兩個域:數(shù)據(jù)域用來存儲結點的值;指針域用來存儲數(shù)據(jù)元素的直接后繼的地址(或位置)。頭指針:指向鏈表頭結點的指針。6/10/202325單鏈表的示例圖頭指針H存儲地址數(shù)據(jù)域指針域1D437B1313C119HNULL25F3731A737G1943E25316/10/202326帶頭結點的單鏈表示意圖有時為了操作的方便,還可以在單鏈表的第一個結點之前附設一個頭結點。帶頭結點的空單鏈表
帶頭結點的單鏈表
∧Ha1a2…Han
∧6/10/202327單鏈表的存儲結構描述typedefstructNode/*結點類型定義*/{ElemTypedata;structNode*next;}Node,*LinkList;/*LinkList為結構指針類型*/
6/10/2023282.3.2單鏈表上的基本運算線性表的基本運算:建立單鏈表
單鏈表查找
單鏈表插入操作
單鏈表刪除
算法應用示例:求單鏈表的長度
求兩個集合的差
6/10/202329建立單鏈表頭插法建表
算法描述:從一個空表開始,重復讀入數(shù)據(jù),生成新結點,將讀入數(shù)據(jù)存放到新結點的數(shù)據(jù)域中,然后將新結點插入到當前鏈表的表頭結點之后,直至讀入結束標志為止。c1∧sL∧L
ci-1∧c2c1∧cis…c1∧6/10/202330頭插法建表算法LinklistCreateFromHead(){LinkListL;Node
*s;intflag=1;
/*設置一個標志,初值為1,當輸入“$”時,flag為0,建表結束*/L=(Linklist)malloc(sizeof(Node));/*為頭結點分配存儲空間*/
L->next=NULL;while(flag){c=getchar();if(c!=’$’)/*為讀入的字符分配存儲空間*/{s=(Node*)malloc(sizeof(Node));s->data=c;s->next=L->next;L->next=s;}else
flag=0;}}
6/10/202331尾插法建表C1
∧sr∧Lc1rsc2∧Lc1∧rsL6/10/202332尾插法建表算法LinklistCreateFromTail()/*將新增的字符追加到鏈表的末尾*/{LinkListL;Node*r,*s;intflag=1;
L=(Node*)malloc(sizeof(Node));/*為頭結點分配存儲空間*/L->next=NULL;r=L;/*r指針始終動態(tài)指向鏈表的當前表尾*/while(flag)/*標志,初值為1。輸入“$”時flag為0,建表結束*/
{ c=getchar();
if(c!=’$’){s=(Node*)malloc(sizeof(Node));s->data=c;r->next=s;r=s}else{flag=0;r->next=NULL;}}}6/10/202333單鏈表查找按序號查找
算法描述:設帶頭結點的單鏈表的長度為n,要查找表中第i個結點,則需要從單鏈表的頭指針L出發(fā),從頭結點(L->next)開始順著鏈域掃描,用指針p指向當前掃描到的結點,初值指向頭結點(pL->next),用j做記數(shù)器,累計當前掃描過的結點數(shù)(初值為0),當j=i時,指針p所指的結點就是要找的第i個結點。算法實現(xiàn),算法演示。 6/10/202334按序號查找算法實現(xiàn)/*在帶頭結點的單鏈表L中查找第i個結點,若找到(1≤i≤n),則返回該結點的存儲位置;否則返回NULL*/Node*Get(LinkListL,inti){Node*p;p=L;j=0;/*從頭結點開始掃描*/while((p->next!=NULL)&&(j<i){p=p->next;j++;/*掃描下一結點*/}/*已掃描結點計數(shù)器*/if(i==j)returnp;/*找到了第i個結點*/elsereturnNULL;/*找不到,i≤0或i>n*/}6/10/202335按值查找
算法描述:按值查找是指在單鏈表中查找是否有結點值等于e的結點,若有的話,則返回首次找到的其值為e的結點的存儲位置,否則返回NULL。查找過程從單鏈表的頭指針指向的頭結點出發(fā),順著鏈逐個將結點的值和給定值e作比較。算法實現(xiàn),算法演示。單鏈表查找6/10/202336按值查找算法實現(xiàn)/*在帶頭結點的單鏈表L中查找其結點值等于key的結點,若找到則返回該結點的位置p,否則返回NULL*/Node*Locate(LinkListL,ElemTypekey){Node*p;p=L->next;/*從表中第一個結點比較*/while(p!=NULL)if(p->data!=key) p=p->next;elsebreak;/*找到結點key,退出循環(huán)*/returnp;}6/10/202337單鏈表插入操作算法描述:
要在帶頭結點的單鏈表L中第i個數(shù)據(jù)元素之前插入一個數(shù)據(jù)元素e,需要首先在單鏈表中找到第i-1個結點并由指針pre指示,然后申請一個新的結點并由指針s指示,其數(shù)據(jù)域的值為e,并修改第i-1個結點的指針使其指向s,然后使s結點的指針域指向第i個結點。esa1……an∧ai-1aiespreLa1……an∧preai-1ai6/10/202338單鏈表插入操作算法實現(xiàn)voidInsList(LinkListL,inti,ElemTypee){/*在帶頭結點的單鏈表L中第i個結點之前插入值為e的新結點。*/
Node*pre,*s;
pre=L;intk=0;while(pre!=NULL&&k<i-1)/*先找到第i-1個數(shù)據(jù)元素的存儲位置,使指針Pre指向它*/
{pre=pre->next;
k=k+1;}if(k!=i-1){printf(“插入位置不合理!”);return;}s=(Node*)malloc(sizeof(Node));/*為e申請一個新的結點*/s->data=e;/*將待插入結點的值e賦給s的數(shù)據(jù)域*/s->next=pre->next;pre->next=s;}
6/10/202339單鏈表刪除算法描述: 欲在帶頭結點的單鏈表L中刪除第i個結點,則首先要通過計數(shù)方式找到第i-1個結點并使p指向第i-1個結點,而后刪除第i個結點并釋放結點空間。pa1…ai-1ai…an∧pa1…L…an∧ai-1aiai+1rL6/10/202340單鏈表刪除算法實現(xiàn)voidDelList(LinkListL,inti,ElemType*e)/*在帶頭結點的單鏈表L中刪除第i個元素,并保存其值到變量*e中*/{
Node*p,*r;p=L;intk=0;
while(p->next!=NULL&&k<i-1)/*尋找被刪除結點i的前驅結點*/{p=p->next;k=k+1;}if(k!=i-1)/*即while循環(huán)是因為p->next=NULL而跳出的*/{printf(“刪除結點的位置i不合理!”);returnERROR;}r=p->next;p->next=p->next->next/*刪除結點r*/free(r);/*釋放被刪除的結點所占的內存空間*/}6/10/202341求單鏈表的長度
算法描述:可以采用“數(shù)”結點的方法來求出單鏈表的長度,用指針p依次指向各個結點,從第一個元素開始“數(shù)”,一直“數(shù)”到最后一個結點(p->next=NULL)。
int ListLength(LinkListL)/*L為帶頭結點的單鏈表*/{Node*p;p=L->next; j=0;/*用來存放單鏈表的長度*/while(p!=NULL){ p=p->next;j++;}returnj;}算法演示鏈接。6/10/202342兩個有序單鏈表的合并有兩個單鏈表LA和LB,其元素均為非遞減有序排列,編寫一個算法,將它們合并成一個單鏈表LC,要求LC也是非遞減有序排列。要求:利用新表LC利用現(xiàn)有的表LA和LB中的元素結點空間,而不需要額外申請結點空間。例如LA=(2,2,3),LB=(1,3,3,4),則LC=(1,2,2,3,3,3,4)。
【算法描述】要求利用現(xiàn)有的表LA和LB中的結點空間來建立新表LC,可通過更改結點的next域來重建新的元素之間的線性關系,為保證新表仍然遞增有序,可以利用尾插入法建立單鏈表的方法,只是新建表中的結點不用malloc,而只需要從表LA和LB中選擇合適的點插入到新表LC中即可。6/10/2023436/10/202344兩個有序單鏈表的合并的算法實現(xiàn)LinkListMergeLinkList(LinkListLA,LinkListLB)/*將遞增有序的單鏈表LA和LB合并成一個遞增有序的單鏈表LC*/{Node*pa,*pb;LinkListLC;/*將LC初始置空表。pa和pb分別指向兩個單鏈表LA和LB中的第一個結點,r初值為LC*/pa=LA->next;pb=LB->next;LC=LA;LC->next=NULL;r=LC; /*初始化操作*/6/10/202345兩個有序單鏈表的合并的算法實現(xiàn)(續(xù))/*當兩個表中均未處理完時,比較選擇將較小值結點插入到新表LC中。*/
while(pa!=NULL&&pb!=NULL) {if(pa->data<=pb->data){r->next=pa;r=pa;pa=pa->next;}else{r->next=pb;r=pb;pb=pb->next;}}if(pa)/*若表LA未完,將表LA中后續(xù)元素鏈到新表LC表尾*/r->next=pa;else /*否則將表LB中后續(xù)元素鏈到新表LC表尾*/r->next=pb;free(LB);return(LC);}/*MergeLinkList*/6/10/2023462.3.3循環(huán)鏈表
循環(huán)鏈表(CircularLinkedList)是一個首尾相接的鏈表。特點:將單鏈表最后一個結點的指針域由NULL改為指向頭結點或線性表中的第一個結點,就得到了單鏈形式的循環(huán)鏈表,并稱為循環(huán)單鏈表。在循環(huán)單鏈表中,表中所有結點被鏈在一個環(huán)上。
帶頭結點循環(huán)單鏈表示意圖。6/10/202347帶頭結點的循環(huán)單鏈表示意圖
La1……ai-1aianLa1……ai-1aianrear*(rear->next)*rear空鏈表帶頭結點的一般形式
帶尾結點的一般形式
6/10/202348循環(huán)單鏈表合并為一個循環(huán)單鏈表
已知:有兩個帶頭結點的循環(huán)單鏈表LA、LB,編寫一個算法,將兩個循環(huán)單鏈表合并為一個循環(huán)單鏈表,其頭指針為LA。 算法思想:先找到兩個鏈表的尾,并分別由指針p、q指向它們,然后將第一個鏈表的尾與第二個表的第一個結點鏈接起來,并修改第二個表的尾Q,使它的鏈域指向第一個表的頭結點。
6/10/202349循環(huán)單鏈表合并算法實現(xiàn)LinkListmerge_1(LinkListLA,LinkListLB)/*此算法將兩個鏈表的首尾連接起來*/{Node*p,*q;p=LA;q=LB;while(p->next!=LA)p=p->next; /*找到表LA的表尾*/while(q->next!=LB)q=q->next; /*找到表LB的表尾*/q->next=LA;/*修改表LB的尾指針,使之指向表LA的頭結點*/p->next=LB->next;/*修改表LA的尾指針,使之指向表LB中的第一個結點*/ free(LB);return(LA);}6/10/2023502.3.4雙向鏈表
雙向鏈表:在單鏈表的每個結點里再增加一個指向其前趨的指針域prior。這樣形成的鏈表中就有兩條方向不同的鏈,我們稱之為雙(向)鏈表(DoubleLinkedList)。雙向鏈表的結構定義: typedefstructDnode {ElemTypedata; structDNode*prior,*next; }DNode, *DoubleList;6/10/202351雙鏈表的結構定義雙鏈表的結點結構后繼指針域priordatanext前驅指針域數(shù)據(jù)域6/10/202352雙向循環(huán)鏈表示意圖a1a2a3LL空的雙向循環(huán)鏈表
非空的雙向循環(huán)鏈表
6/10/202353雙向鏈表的前插操作算法描述:欲在雙向鏈表第i個結點之前插入一個的新的結點,則指針的變化情況如圖所示。es①②③④…bpa…6/10/202354雙向鏈表的前插操作算法實現(xiàn)void
DlinkIns(DoubleListL,inti,ElemTypee)
{DNode*s,*p; …/*首先檢查待插入的位置i是否合法*/
…/*若位置i合法,則讓指針p指向它*/s=(DNode*)malloc(sizeof(DNode));if(s){s->data=e;s->prior=p->prior;p->prior->next=s;s->next=p;p->prior=s;returnTRUE;}
else
returnFALSE;}算法演示連接。6/10/202355雙向鏈表的刪除操作算法描述:欲刪除雙向鏈表中的第i個結點,則指針的變化情況如圖所示。abcp②①……6/10/202356雙向鏈表的刪除操作算法實現(xiàn)int
DlinkDel(DoubleListL,inti,ElemType*e)
{ DNode*p; …/*首先檢查待插入的位置i是否合法*/
…/*若位置i合法,則讓指針p指向它*/ *e=p->data; p->prior->next=p->next; p->next->prior=p->prior; free(p); returnTRUE;}6/10/202357*2.3.5靜態(tài)鏈表基本概念:
游標實現(xiàn)鏈表的方法:定義一個較大的結構數(shù)組作為備用結點空間(即存儲池)。當申請結點時,每個結點應含有兩個域:data域和next域。data域存放結點的數(shù)據(jù)信息,next域為游標指示器,指示后繼結點在結構數(shù)組中的相對位置(即數(shù)組下標)。數(shù)組的第0個分量可以設計成表的頭結點,頭結點的next域指示了表中第一個結點的位置,為0表示靜態(tài)單鏈表的結束。我們把這種用游標指示器實現(xiàn)的單鏈表叫做靜態(tài)單鏈表(StaticLinkedList)。靜態(tài)鏈表的結構定義,靜態(tài)鏈表的插入和刪除操作示例?;静僮鳎撼跏蓟⒎峙浣Y點與結點回收、前插操作、刪除。
6/10/202358靜態(tài)鏈表的結構定義#defineMaxsize=鏈表可能達到的最大長度typedefstruct{ElemTypedata;intcursor;}Component,StaticList[Maxsize];
6/10/202359靜態(tài)鏈表的插入和刪除操作示例已知:線性表a,b,c,d,f,g,h,i),Maxsize=110123456789100123456789101a2b3c4d9f6g8h8i0e51a2b3c4d9f6g7h8i0e51a2b3c4d5f6g7h8i0012345678910(a)初始化(b)插入e后(c)刪除h后6/10/202360靜態(tài)鏈表初始化算法描述:初始化操作是指將這個靜態(tài)單鏈表初始化為一個備用靜態(tài)單鏈表。設space為靜態(tài)單鏈表的名字,av為備用單鏈表的頭指針,其算法如下:voidinitial(StaticListspace,int*av){intk;space[0]->cursor=0;/*設置靜態(tài)單鏈表的頭指針指向位置0*/for(k=0;k<Maxsize-1;k++) space[k]->cursor=k+1;/*連鏈*/space[Maxsize-1].cursor
=0;/*標記鏈尾*/*av=1;/*設置備用鏈表頭指針初值*/}
6/10/202361靜態(tài)鏈表分配結點與結點回收分配結點intgetnode(int*av)/*從備用鏈表摘下一個結點空間,分配給待插入靜態(tài)鏈表中的元素*/{inti=*av;*av=space[*av].cur;returni;}結點回收voidfreenode(int*av,intk)/*將下標為k的空閑結點插入到備用鏈表*/{space[k].cursor=*av;*av=k;}6/10/2023622.4一元多項式的表示及相加一元多項式可按升冪的形式寫成:Pn(x)=p0+p1xe1+p2xe2+…+pnxen,其中ei為第i項的指數(shù),pi是指數(shù)ei的項的系數(shù),(且1≤e1≤e2≤…≤en)假設Qm(x)是一個一元多項式,則它也可以用一個線性表Q來表示。即:Q=(q0,q1,q2,…,qm)若假設m<n,則兩個多項式相加的結果Rn(x)=Pn(x)+Qm(x),也可以用線性表R來表示:R=(p0+q0,p1+q1,,p2+q2,…,pm+qm,pm+1,…,pn)6/10/202363一元多項式的存儲一元多項式的順序存儲表示一元多項式的鏈式存儲表示6/10/202364一元多項式的順序存儲表示1一元多項式Pn(x)的順序表示有兩種。法1、只存儲該一元多項式各項的系數(shù),每個系數(shù)所對應的指數(shù)項則隱含在存儲系數(shù)的順序表的下標中。即p[0]存系數(shù)p0,對應為x0的系數(shù),p[1]存系數(shù)p1,對應為x1的系數(shù),……p[n]存系數(shù)pn,對應為xn的系數(shù)。采用這種存儲方法使得多項式的相加運算的算法定義十分簡單,只需將下標相同的單元的內容相加即可。適合于存儲表示非零系數(shù)多的多項式。6/10/202365一元多項式的順序存儲表示2法2、采用只存儲非零項的方法,此時每個非零項需要存儲:非零項系數(shù)和非零項指數(shù)。適合存儲表示非零項少的多項式。piei┋┋圖2.19一元多項式只存非零項存儲示意圖6/10/202366一元多項式的鏈式存儲表示在鏈式存儲中,對一元多項式只存非零項,則該多項式中每一非零項由兩部分構成(指數(shù)項和系數(shù)項),用單鏈表存儲表示的結點結構為:用單鏈表存儲多項式的結點結構如下: structPolynode { intcoef;intexp;Polynode*next;}Polynode,*Polylist;
系數(shù)coef指數(shù)exp指針next6/10/202367建立一元多項式鏈式存儲的算法【算法思想】通過鍵盤輸入一組多項式的系數(shù)和指數(shù),用尾插法建立一元多項式的鏈表。以輸入系數(shù)0為結束標志,并約定建立多項式鏈表時,總是按指數(shù)從小到大的順序排列。【算法描述】Polylist
polycreate(){Polynode*head,*rear,*s; intc,e; rear=head=(Polynode*)malloc(sizeof(Polynode)); /*建立多項式的頭結點,rear始終指向單鏈表的尾*/
scanf(“%d,%d”,&c,&e);/*鍵入多項式的系數(shù)和指數(shù)項*/ while(c!=0) /*若c=0,則代表多項式的輸入結束*/ {s=(Polynode*)malloc(sizeof(Polynode)); /*申請新的結點*/s->coef=c;s->exp=e;rear->next=s; /*在當前表尾做插入*/rear=s; scanf(“%d,%d”,&c,&e);}rear->next=NULL;/*將表的最后一個結點的next置NULL,以示表結束*/return(head);}6/10/202368一元多項式的單鏈表表示示意圖說明:圖示分別為多項式 A(x)=7+3x+9x8+5x17 B(x)=8x+22x7-9x8
-17031517∧9881-1227-98∧
6/10/202369兩個一元多項式相加運算規(guī)則:兩個多項式中所有指數(shù)相同的項的對應系數(shù)相加,若和不為零,則構成“和多項式”中的一項;所有指數(shù)不相同的項均復抄到“和多項式”中。算法實現(xiàn),算法演示若p->exp<q->exp,則結點p所指的結點應
是“和多項式”中的一項,令指針p后移;若p->exp>q->exp,則結點q所指的結點應是“和多項式”中的一項,將結點q插入在結點p之前,且令指針q在原來的鏈表上后移;若p->exp=q->exp,則將兩個結點中的系數(shù)相加,當和不為零時修改結點p的系數(shù)域,釋放q結點;若和為零,則和多項式中無此項,從A中刪去p結點,同時釋放p和q結點。6/10/202370兩個多項式相加算法實現(xiàn)voidpolyadd(Polylistpolya;Polylistpolyb){……/*p和q分別指向polya和polyb鏈表中的當前計算結點*/ ……/*pre指向和多項式鏈表中的尾結點*/whilep!=NULL&&q!=NULL){if
(p->exp<q->exp){…/*將p結點加入到和多項式中*/}elseif(p->exp==q->exp)
{…/*若指數(shù)相等,則相應的系數(shù)相加。若系數(shù)為0則刪除p,q節(jié)點*/}
else{…/*將q結點加入到和多項式中*/}}…../*將多項式polya或polyb中剩余的結點加入到和多項式中*/}6/10/2023712.5順序表和鏈表的比較
1.基于空間的考慮
2.基于時間的考慮
3.基于語言的考慮
6/10/202372線性表鏈式存儲方式的比較操作名稱鏈表名稱找表頭結點找表尾結點找P結點前驅結點帶頭結點單鏈表LL->next時間耗費O(1)一重循環(huán)時間耗費O(n)順P結點的next域無法找到P結點的前驅帶頭結點循環(huán)單鏈表(頭指針)LL->next時間耗費O(1)一重循環(huán)時間耗費O(n)順P結點的next域可以找到P結點的前驅時間耗費O(n)帶尾指針的循環(huán)單鏈表RR->nextO(1)R時間耗費O(1)順P結點的next域可以找到P結點的前驅時間耗費O(n)帶頭結點雙向循環(huán)鏈表LL->nextO(1)L->prior時間耗費O(1)P->prior時間耗費O(1)6/10/2023732.6總結與提高
主要知識點
1、線性表的特征:線性表中每個數(shù)據(jù)元素有且僅有一個直接前驅和一個直接后繼,第一個結點無前驅,最后一個結點無后繼。2、線性表存儲方式:線性表順序存儲(順序表):采用靜態(tài)分配方式,借助于C語言的數(shù)組類型,申請一組連續(xù)的地址空間,依次存放表中元素,其邏輯次序隱含在存儲順序之中。6/10/2023742.6總結與提高線性表鏈式存儲(鏈表):采用動態(tài)分配方式,借助于C語言的指針類型,動態(tài)申請與動態(tài)釋放地址空間,故鏈表中的各結點的物理存儲可以是不連續(xù)的。當表長度變化時僅需適當變化指針的聯(lián)接,適合于表中元素個數(shù)動態(tài)變化。3、單鏈表的操作特點:⑴順鏈操作技術⑵指針保留技術4、鏈表處理中的相關技術6/10/202375典型題例
例1:已知順序表L中的數(shù)據(jù)元素類型為int。設計算法將其調整為左右兩部分,左邊的元素(即排在前面的)均為奇數(shù),右邊所有元素(即排在后面的)均為偶數(shù),并要求算法的時間復雜度為O(n),空間復雜度為O(1)。6/10/202376例1【問題分析】初見此題,可能會想到額外申請1個順序表空間,之后依次從順序表L中選擇奇數(shù)放入新表前部分,選擇偶數(shù)放在新表的后半部分。但是題目要求空間復雜度為O(1),很顯然上述方法是不可行的。既然要求空間復雜度為O(1),說明只能借助1個輔助空間。分析題目要求,其實我們只需要將位于表左半部分的偶數(shù)與位于表右半部分的奇數(shù)通過一個輔助變量進行交換即可,為此我們可以設置兩個位置指示器i和j,i初值為0,j初值為L->last,當L->elem[i]為偶數(shù),L->elem[j]為奇數(shù)時,則將L->elem[i]與L->elem[j]交換;否則,L->elem[i]為奇數(shù),i++,L->elem[j]為偶數(shù),j++。這樣既可以保證算法的時間復雜度為O(n),亦可保證空間復雜度為O(1)。6/10/202377【算法描述】
AdjustSqlist(SeqList*L)/*{inti=0,j=L->last;while(i<j){while(L->elem[i]%2!=0)i++;/*從表的左半部分開始檢測,若為奇數(shù),則i加1,直到找到偶數(shù)為止*/while(L->elem[j]%2==0)j--;/*從表的右半部分開始檢測,若為偶數(shù),則j減1,直到找到奇數(shù)為止*/if(i<j){t=L->elem[i];L->elem[i]=L->elem[j];L->elem[j]=t;}/*交換*/}}/*endofAdjustSqlist*/6/10/202378例2:算法實現(xiàn)帶頭結點單鏈表的就地逆置問題?!締栴}分析】逆置就是使得表中內容由原來的(a1,a2,…,ai-1,ai,ai+1,…,an)變?yōu)椋╝n,an-1,…,ai+1,ai,ai-1,…,a1)。就地逆置就是不需要額外申請結點空間,只需要利用原有的表中的節(jié)點空間。若對順序表中的元素進行逆置,可以借助于“交換”前后相應元素;對單
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 質量管理生產制度
- 水產品生產部規(guī)章制度
- 2026廣西來賓市忻城縣城鎮(zhèn)公益性崗位工作人員招聘2人備考考試題庫附答案解析
- 生產車間批號管理制度
- 生產現(xiàn)場安全標識制度
- 生產設備招標制度
- 生產單位規(guī)章制度范本
- 廠區(qū)安全生產會議制度
- 自然經(jīng)濟生產制度
- 2025河南洛陽市瀍河區(qū)區(qū)屬國有企業(yè)招聘背景調查事宜參考考試試題附答案解析
- 2025年開封大學單招職業(yè)技能測試題庫完整
- 亞馬遜運營廣告培訓
- 中建給排水施工方案EPC項目
- 電氣工程及自動化基于PLC的皮帶集中控制系統(tǒng)設計
- 醫(yī)學教材 常見輸液反應的處理(急性肺水腫)
- FURUNO 電子海圖 完整題庫
- 企業(yè)年會攝影拍攝合同協(xié)議范本
- 焊接質量控制規(guī)范培訓課件
- 急診科護士長述職報告
- JGT334-2012 建筑外墻用鋁蜂窩復合板
- 汽車4S店安全生產責任書
評論
0/150
提交評論