第2章线性表的基本使用及其cpp示例(第二章汇总,线性表都在这里)
2.1線性表的定義和特點
【類型定義:
*是n個元素的有限序列
*除了第一個元素沒有直接前驅(qū)和最后一個沒有直接后驅(qū)之外,其余的每個元素只有一個直接前驅(qū)和直接后驅(qū);
(a1,a2…an)
【特征:
*有窮性:由有限個元素組成,元素個數(shù)表長度 n=0空表
(a1,a2…an),稱下標i為線性表的位序
*有序性: 線性表元素之間存在嚴格次序關(guān)系(序偶關(guān)系)
*同一性:線性表屬于同類數(shù)據(jù)元素組成,每一個元素都屬于同一數(shù)據(jù)對象
eg:(A,12,b)不是線性表,不遵守同一性
2.1.2線性表抽象數(shù)據(jù)類型定義
ADT List{
//數(shù)據(jù)對象
D={ai|ai∈ElemSet,i=1,2…n, n>0}
//數(shù)據(jù)關(guān)系
R1={<ai-1,ai>|ai-1,ai∈D,i=2,…n}
//基本操作
1)InitList(&L)
將:初數(shù)化為空表
2)
…
}ADT list
【引用在什么情況下使用】
所用到的元素,哪個元素變化(帶入數(shù)據(jù)或者 ),就在此元素前加 &
【eg】
1)InitList(&L)
將:初數(shù)化為空表
//表L初始化帶入值,發(fā)生變化,故早L前加&
2.1.5 示例 *有序集合的合并
有序表:LA和LB,求合并遞減有序LC
基本思路:
{若ai<=bi,則ci=bi
{
{若bi<ai,則ci=ai
//誰小就先吧他賦給c
算法時間復雜度:O(ListLength(LA))+O(ListLength(LB))
2.2.1線性表的順序表示和實現(xiàn)------順序映像
【順序存儲】在【查找時】的時間復雜度為【O(1)】,因為它的地址是連續(xù)的,只要知道首元素的地址,根據(jù)下標可以很快找到指定位置的元素
【插入和刪除】操作由于可能要在插入前或刪除后對元素進行移動,所以順序存儲的時間復雜度為【O(n)】。
1)初始化操作
思想:構(gòu)造一個空表
設(shè)置表起始位置、表長及可用空間
2.2.3順序表的插入
2)順序插入操作
目的:在線性表L第i個元素前插入一個元素e
【基本思想
1)判斷i是否在允許范圍
2)存儲空間是否已滿
3)將第i個元素和后面的所有元素向后移動
4)新元素寫在空出的第i個位置
5)線性表長度加1
【注意】
長度為n的順序表第i個位置插入移動n-i+1個元素
2.2.4順序表的刪除和插入
【基本思路
1)判斷i是否在允許范圍
2)將線性表的第i個元素給e
3)將第i個元素和后面的所有元素向前移動一個位置
4)線性表長度減1
【圖】:平均移動次數(shù)
【查找操作】11:42
int LocateElem_Sq(SqList,ElseType e) { //查詢第一個 滿足條件的元素,若存在,返回位序,否則返回0; int i; i=1; while (i<=L.length&&L.elem[i-1]!=e) ++i; if(i<=L.length) return i; else return 0; }// locateElem_Sqi<=L.length&&L.elem[i-1]!=e i>L.length【順序結(jié)構(gòu)優(yōu)缺點14:15
【優(yōu)點:
邏輯相鄰,物理相鄰
可隨機存取一元素
存儲空間使用緊湊
【缺點:
插入,刪除需要移動大量元素
預(yù)先分配空間需按最大空間分配,利用不充分表難以擴充
【】線性表的合并問題
【圖:例1】
基本思路:
1)初始化Lc為空表
2)分別從La和Lb取得當前元素ai和bi
3)若ai<bj,則將ai插入到Lc中,否則
bj插入到Lc中
代碼:
Viod MergeList(SqList La.SqList ,lb.SqList &Lc) { Pa=La.elem; Pb=Lb.elem; Lc.listsize=Lc.length=La.elem+Lb.elem; Pc=Lc.elem=(ElemType*)malloc(Lc.listsize* sizeof(ElemType)); if(!Lc.elem) exit(overflow); Pa_last=La.elem+La.length-1; Pb_last=Lb.elem+Lb.length-1; while(pa<=pa_last&&pb<=pb_last) { if(*pa<= *pb) *pc++= *pa++; else *pc++= *pb++; } while(pa<=pa_last) *pc++= *pa++; while (pb<=pb_last) *pc++= *pb++; }2.3線性表的鏈式表現(xiàn)與實現(xiàn)
2.3.1.1單鏈表
【特點:
*用一組任意的存儲單元存儲線性表的數(shù)據(jù)元素
*利用指針實現(xiàn)用不同相鄰的存儲單元存放邏輯上相鄰的元素
*每個元素ai,除存儲本身信息外,還存儲其直接后繼的元素(后一個元素的地址)
*結(jié)點:數(shù)據(jù)元素ai的存儲映像
{數(shù)據(jù)域:數(shù)據(jù)元素本身
指針域:指示直接后繼的存儲位置
【頭指針、頭結(jié)點、第一個元素結(jié)點
*頭指針:以線性表的第一個數(shù)據(jù)元素a1的存數(shù)地址作為線性表的地址,稱為線性表的頭指針
*頭結(jié)點:為了操作方便,在第一個結(jié)點前虛加一個“頭結(jié)點”,指向頭結(jié)點的指針為鏈表的頭指針(相當于第一個呀元素的結(jié)點)
代碼:
typedef struct LNode{ElemType data;struct LNode*next; }LNode,*LinkList //LNode是結(jié)構(gòu)體的別名,LinkList為指針變量 //相當于:typedef LNode *LinkList2.3.1.2 單鏈表存儲結(jié)構(gòu)實現(xiàn)
格式: data | next
【p指向數(shù)據(jù)域
(*p).data=10;
或:p->data=10; //表示p指向結(jié)點的數(shù)據(jù)域
(*p).next=10
或 p->next //表示p指向結(jié)點的指針域
*生成一個LNode型新結(jié)點:
p=(LinkList)malloc(sizeof(LNode));
*系統(tǒng)回收p的結(jié)點
free(p)
*單鏈表特點:
1)是它是一種動態(tài)結(jié)構(gòu),整個存儲空間為多個鏈表共用
2)不需預(yù)先分配空間
3)指針占用額外存儲空間
4)不能隨機存取,查找速度慢
【基本操作:
1)GetElem(L,i,&e) //第i個元素用e帶回結(jié)果
2)ListInsert(&L,i,e) //插入
3)ListDelete(&L,i,e) //刪除
4)CreateList_L(&L,n) //創(chuàng)建線性表
2.3.1.3單鏈表的查找
【操作:
1)GetElem(L,i,&e)
【基本思想:
1)令p為指針變量,首先指向第一個結(jié)點,變量 j為計數(shù)器
2)依次向后查找,循環(huán)結(jié)束條件:p為空或j>=i;
3)找到用e返回第i個值
【代碼:
Status GetElem_L(LinkList L,int i,ElemType&e) { //L是鏈表的頭指針(對帶頭結(jié)點的鏈表),以e返回dii個值 p=L->next; j=1;while (p&&j<i) {p=p->next; ++j;if(!p||j>i)return ERROR;e=p->data; //取第i個值 return OK; }2.3.1.4單鏈表的插入操作
2)ListInsert(&L,i,e)
在線性表第i個元素之前插入一個元素e,元素e存在結(jié)點s中
【思路:在第i項的前加一個接結(jié)點,i-1項的地址域和e的數(shù)據(jù)域連接
int ListInsert_L(LinkList&L,int i,int e) { LNode*p,*s;int j; //或:LinkList p,s; 等同 p=L;j=0; //計數(shù)器 while(p&&j<i-1) {p=p->next;++j;} if(!p||j>i-1) return ERROR; s=LinkList()malloc(sizeof(LNode)); //新結(jié)點 s->data=e; s->next=p->next; p->next=s; return OK; }2.3.1.5 單鏈表的刪除
【思路:刪除第i個元素,并保存到元素e中
【代碼:
int ListDelete_L(LinkList&L,int i,ElemType&e) { LNode*p,*q;int j; p=L;j=0; while(p->next||j<i-1) //????我覺得應(yīng)該是(!p||j>i-1) {p=p->next;++j} if(p->next==NULL||j>i-1) return ERROR; //刪除位置不合理 q=p->next; //q指向被刪除結(jié)點 p->next=q->next; // e=q->data; //取出第i個結(jié)點的數(shù)據(jù)域 free(q); // 釋放dii個結(jié)點的內(nèi)存 return OK; }2.3.1.6單鏈表的建立
【頭插法建立有頭結(jié)點的單鏈表
可理解為:每次插一個新的頭
【圖】
L=(Linklist)malloc(sizeof(LNode)) //sizeof后面跟數(shù)據(jù)類型(LNode)
L->next=NULL
【圖】
p=(LinkList)malloc(sizeof(LNode))
scanf("%f",&(p->data)); //
【整個代碼:
void CreateList_L(LinkList &L,int n) { LNode*p;int i; L=(LinkList)malloc(sizeof(Lnode)); L->next=NULL; for(i=n;i>0;--i) { p=(Listlink)malloc(sizeof(LNode)); scanf("%d",&p->data); p->next=L->next; l->next=p //這里的=都可以理解為“給了,到,指向” } }2.3.1.7有序單鏈表的合并
例:線性表LA和LB中數(shù)據(jù)元素按照廢帝劍有序排列,將LA和LB合并為一個新的LC,且LC中的數(shù)據(jù)元素仍按照遞減有序排列
【代碼:
2.3.1.8靜態(tài)鏈表
定義:用數(shù)組描述的鏈表叫靜態(tài)鏈表
目的:為在不設(shè)指針類型的高級程序語言中使用鏈表結(jié)構(gòu)
存儲結(jié)構(gòu):
#define MAXSIZE 100 //靜態(tài)鏈表最大長度 typedef struct{ ElemType data; int cur; //游標,代替指針的結(jié)點,表示數(shù)組中的位置 }component,SLinkList[MAXSIZE]2.3.2循環(huán)鏈表
循環(huán)鏈表是單鏈表的變形
循環(huán)鏈表最后一個結(jié)點link指針部位NULL,而是指向表的前端
為簡化操作,在循環(huán)鏈表往往插入頭結(jié)點
特點:
只要知道表中一結(jié)點的地址,就可以搜索到所有其他結(jié)點的地址
操作的時間復雜度:
表尾插入,時間復雜度:O(1)
表尾刪除:O(n)
表頭插入,同表尾
表頭刪除:O(1)
2.3.3雙向鏈表 插入、刪除
指在前驅(qū)和后驅(qū)方向都能游歷(遍歷)的線性鏈表
雙向鏈表的每個結(jié)點有兩個指針域
【結(jié)構(gòu)】:prior data next
雙鏈表通常采用帶頭結(jié)點的循環(huán)鏈表形式
可理解為首位相接的數(shù)據(jù)“圈”,每個結(jié)點都可以向前或向后走
【結(jié)點指向】
【插入操作】:
1.分配空間
2.斷開與連接
【操作算法
【刪除操作】
1.p指向目標結(jié)點
2.將目標結(jié)點的前一個結(jié)點與后一個連接(跳過中間那個)
3釋放內(nèi)存
【操作算法】
status ListDelete_Dul(DuLinkList &L,int i,ElemType &e)
{ 刪除頭結(jié)點的雙向循環(huán)鏈表L中第i個元素返回,1=i=表長
if(!p=GetElem_Dul(L,i))
return ERROR; 查找第i個指針
e=p-data; 將p指向結(jié)點數(shù)據(jù)域中的值取出
p-prior-next=p-next; p前一個結(jié)點的后驅(qū)指向p的后一個結(jié)點
p-next-prior=p-prior; 后指向前
free§; 釋放p
return OK;
} ListDelete_DuL
【 算法評價:T(n)=O(n) 】
!注意:如何選擇合適的存儲結(jié)構(gòu)
鏈表只能順序存取,在單鏈表的最后一個元素后插入元素,需遍歷整個鏈表
頻繁插入刪除用鏈式存儲
偶爾 用順序存儲
2.4一元多項式的表示及相加
- n階多項式的表示:
n階多項式有n+1項
指數(shù)按升冪排序
【 優(yōu)點:
- 多項式的項數(shù)可以動態(tài)增長,不存在存儲溢出的問題
- 插入,刪除方便,不移動元素
【表示:
有兩個數(shù)據(jù)域,一個地址域
【一元多項式的建立算法:
【一元多項式相加:
-
掃描兩個多項式
{若當前被檢測項指數(shù)相等,系數(shù)相加。 和不為0,則結(jié)果加到結(jié)果多項式{若檢查指數(shù)不等,將指數(shù)小的加到結(jié)果多項式,然后往后移
-
若一個多項式檢測完,將另一個多項式剩余全部復制到結(jié)果多項式
【設(shè)計思想:
算法:
總結(jié)
以上是生活随笔為你收集整理的第2章线性表的基本使用及其cpp示例(第二章汇总,线性表都在这里)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 莫名被喂“猪食” 腾讯副总抨击短视频
- 下一篇: oracle插补缺失日期,Oracle连