線性表的邏輯結構 線性表是一種最簡單、最多見的數據結構算法
線性表是由n(n≥0)個數據元素(結點)a1,a2,a3,……an組成的有限序列。 數據元素的個數n定義爲表的長度。 當n=0時,稱爲空表數據結構
將非空的線性表(n>0)記做:L=(a1,a2,a3,……,an) a1:起始結點,an:終端結點。 a1稱爲a2的直接前驅,a3稱爲a2的直接後繼函數
線性表的特色:spa
線性表順序存儲的方法:將表中的結點依次存放在計算機內存 中的一組連續存儲單元中。指針
數據元素在線性表中的鄰接關係決定其在存儲空間中的存儲位置;即邏輯結構中相鄰的結點,其存儲位置也相鄰。code
用順序存儲實現的線性表稱爲順序表。blog
順序表上的基本運算 : 插入(Insert)、刪除(Delete)、定位(Locate)內存
=======================插入=========================it
線性表的插入運算:是指在表的位置i上,插入一個新結點x,使 長度爲n的線性表(a1,a2,……,ai,……,an) 變爲長度爲n+1的線性表(a1,……,x,……,an)class
插入時的主義事項:
順序表插入操做過程
插入算法的分析:
須要移動:10-4+1=7 ;7個節點
======================刪除=====================
線性表的刪除運算:是指將表的位置i的結點刪去,使長度爲n的線性 表(a1,a2,……,ai,……,an)變成長度爲n-1的線性表 (a1,a2,……,ai-1,ai+1,……,an)
注意事項:當要刪除元素的位置i不在表長範圍內時,爲非法位置,不能作正 常的刪除操做
順序表刪除操做過程
假設線性表中含有n個數據元素,在進行刪除操做時,有n個位置可刪除, 在位置i刪除時,要移動n-i個數據。
結論:順序存儲結構表示的線性表,在作插入或刪除操做時,平均 須要移動大約一半的數據元素。當線性表的數據元素量較大, 而且常常要對其作插入或刪除操做時,這一點須要考慮
===================定位=====================
定位:從第一個元素a1起,依次和x比較, 直到找到一個與x相等的數據元素,則 返回它在順序表中的存儲下標或序號;當查遍整個表都沒找到與x相等的元 素,返回0。
定位算法的分析:
定位運算的功能是查找出線性表L中值等於x的結點序號的最小值,當不存 在這種結點時,結果爲0。
i從0開始,做爲掃描順序表時的下標:
順序表的特色:
順序表的優勢:
順序表的缺點:
結點結構:
鏈表的具體存儲表示爲:
=================單鏈表===================
單鏈表的通常圖示法:因爲咱們經常只注重結點間的邏輯順序,不關心每一個結點的實際位置,能夠用 箭頭來表示鏈域中的指針
單鏈表各個結點在內存中的存儲位置(物理位置)並不必定連續
頭結點:通常不存數據,利用Head存放該結點地址。在單鏈表中,增長頭結點的目的是方便運算
單鏈表特色總結:
單鏈表的實現:
一、初始化
空表由一個頭指針和一個頭結點組成。算法描述以下: LinkList InitiateLinkList( ) //創建一個空的單鏈表 { LinkList head; //頭指針 head=malloc (sizeof (Node) ) ; //動態構建一結點,它是頭結點 head->next=NULL; return head; } 在算法中,變量head是鏈表的頭指針,它指向新建立的結點,即頭結點。一個空單鏈表僅有一個頭結點,它的指針域爲NULL。
二、求表長
在單鏈表存儲結構中,線性表的長度等於單鏈表所 含結點的個數(不含頭結點)
步驟:
int lengthLinklist (LinkList head){ Node *p; p=head; j=0; while( p->next != NULL ) { p=p->next; j++; } return(j); }
三、讀表元素步驟:查找第i個結點
Node * GetlinkList( LinkList head, int i ){ Node *p; p=head->next; int c=1; while ((c<i) && (p!=NULL) ){ p=p->next; c++; } if(i= =c) return(p); else return NULL; }
四、刪除節點
算法思路(此算法描述刪除第i個結點)
① 找到第i-1個結點;若存在繼續,不然結束;
② 刪除第i個結點,並釋放對應的內存,結束
刪除運算是將表的第i個結點刪去。
(1)找到ai-1的存儲位置p
(2)令p->next指向ai的直接後繼結點
(3)釋放結點ai的空間,將其歸還給"存儲池" 。
算法的實現
在單鏈表中刪除第 i 個結點的基本操做爲:找到線 性表中第i-1個結點,修改其指向後繼的指針。
void DeleteLinklist(LinkList head, int i) //刪除表head的第i個結點 { Node *q; if(i==1) q=head; else q=GetLinklist(head, i-1); //先找待刪結點的直接前驅 if(q !== NULL && q->next != NULL) //若直接前驅存在且待刪結點存在 { p=q->next; //p指向待刪結點 q->next=p->next; //移出待刪結點 free(p); //釋放已移出結點p的空間 } else exit (「找不到要刪除的結點」); //結點不存在 }
注意:free(p)是必不可少的,由於當一個結點從鏈表移出後,若是不釋放它的空間,它將變 成一個無用的結點,它會一直佔用着系統內存空間,其餘程序將沒法使用這塊空間
5. 定位
定位運算是對給定表元素的值,找出這個元素的位置。對 於單鏈表,給定一個結點的值,找出這個結點是單鏈表的 第幾個結點。定位運算又稱爲按值查找
具體步驟:
int LocateLinklist(LinkList head, DataType x) //求表head中第一個值等於x的結點的序號,若不存在這種結點,返回結果爲0 { Node *p=head; //p是工做指針 p=p->next; //初始時p指向首結點 int i=0; //i表明結點的序號,這裏置初值爲 while (p != NULL && p->data != x) //訪問鏈表 { i++; p=p->next; } if (p!=NULL) return i+1; else return 0; }
六、插入
插入運算是將值爲x的新結點插入到表的第i個結點 的位置上,即插入到ai-1與ai之間。
具體步驟:
void InsertLinklist (LinkList head, DataType x, int i) //在表head的第i個數據元素結點以前插入一個以x爲值的新結點 { Node *p,*q; if (i==1) q=head; else q=GetLinklist (head, i-1); //找第 i-1個數據元素結點 if (q==NULL) //第i-1個結點不存在 exit(「找不到插入的位置」); else { p=malloc(sizeof (Node) );p->data=x; //生成新結點 p->next=q->next; //新結點鏈域指向*q的後繼結點 q->next=p; //修改*q的鏈域 } }
注意:連接操做p->next=q->next和q->next=p兩條語句的執行順序不能顛倒,不然結點 *q的鏈域值(即指向原表第i個結點的指針)將丟失。
七、清除單鏈表中值爲x的重複結點
步驟:
void PurgeLinklist(LinkList head) //刪除表head中多餘的重複結點 { Node *p,*q,*r; q=head->next; //q指示當前檢查結點的位置,置其初值指向首結點 while(q!=NULL) //當前檢查結點*q不是尾結點時,尋找並刪除它的重複結點 { p=q; //工做指針p指向*q while(p->next!=NULL) //當*p的後繼結點存在時,將其數據域與*q數據域比較 { if (p->next->data==q->data) //若*(p->next)是*q的重複結點 { r=p->next; //r指向待刪結點 p->next = r->next; //移出結點* (p->next),p->next指向原來* (p->next)的後繼結點 free (r); } else p=p->next; //不然,讓p指向下一個結點 } q=q->next; //更新檢查結點 } }
線性表的基本運算
1,初始化 Initiate(L) 創建一個空表L=(),L不含數據元素。
2,求表長度 Length(L) 返回線性表L的長度。
三、取表元 Get(L,i) 返回線性表第i個數據元素,當i不知足 1≤i≤Length(L)時,返回一特殊值
四、定位 Locate(L,x) 查找線性表中數據元素值等於x的結點序號,如有多 個數據元素值與x相等,運算結果爲這些結點中序號 的最小值,若找不到該結點,則運算結果爲0
五、插入 Insert(L,x,i) 在線性表L的第i個數據元素以前插入一個值爲x的新數據 元素,參數i的合法取值範圍是1≤i≤n+1。操做結束後線性 表L由(a1,a2,…,ai-1, ai,ai+1,.…,an )變爲(a1,a2, …,ai-1,x, ai,ai+1,.…,an ),表長度加 1。
六、刪除 Delete(L,i) 刪除線性表L的第i個數據元素ai,i的有效取值範圍是1≤i≤n。 刪除後線性表L由(a1,a2,…,ai-1, ai,ai+1,.…,an )變爲 (a1,a2,…,ai-1,ai+1,.…,an ),表長度減1
一、循環鏈表
如何找到循環鏈表的尾結點
在循環鏈表中附設一個rear指針指向尾結點 適用於常常適用頭尾結點的鏈表操做中
二、雙向循環鏈表
在鏈表中設置兩個指針域, 一個指向後繼結點 一個指向前驅結點 這樣的鏈表叫作雙向鏈表
線性表與鏈表的優缺點:
(1)單鏈表的每一個結點包括數據域與指針域,指針域須要佔用額外空間。
(2)從總體考慮,順序表要預分配存儲空間,若是預先分配得過大,將形成 浪費,若分配得太小,又將發生上溢;單鏈表不須要預先分配空間,只 要內存空間沒有耗盡,單鏈表中的結點個數就沒有限制。