我們知道,陣列式計算機根據事先定義好的陣列型別與長度自動為其分配一連續的儲存單元,相同陣列的位置和距離都是固定的,也就是說,任何乙個陣列元素的位址都可乙個簡單的公式計算出來,因此這種結構可以有效的對陣列元素進行隨機訪問。但若對陣列元素進行插入和刪除操作,則會引起大量資料的移動,從而使簡單的資料處理變得非常複雜,低效。
為了能有效地解決這些問題,一種稱為「鍊錶」的資料結構得到了廣泛應用。
1. 鍊錶概述
鍊錶是一種動態資料結構,他的特點是用一組任意的儲存單元(可以是連續的,也可以是不連續的)存放資料元素。
鍊錶中每乙個元素成為「結點」,每乙個結點都是由資料域和指標域組成的,每個結點中的指標域指向下乙個結點。head是「頭指標」,表示鍊錶的開始,用來指向第乙個結點,而最後乙個指標的指標域為null(空位址),表示鍊錶的結束。
實際上,鍊錶中的每個結點可以用若干個資料和若干個指標。結點中只有乙個指標的鍊錶稱為單鏈表,這是最簡單的鍊錶結構。
再c++中實現乙個單鏈表結構比較簡單。例如,可定義單鏈表結構的最簡單形式如下
struct node
;這裡用到了結構體型別。其中,*next是指標域,用來指向該結點的下乙個結點;data是乙個整形變數,用來存放結點中的資料。當然,data可以是任何資料型別,包括結構體型別或類型別。
在此基礎上,我們在定義乙個鍊錶類list,其中包含鍊錶結點的插入,刪除,輸出等功能的成員函式。
class list
void insertlist(int adate,int bdate);//鍊錶結點的插入
void deletelist(int adate);//鍊錶結點的刪除
void outputlist();//鍊錶結點的輸出
node*gethead()
};2. 鍊錶結點的訪問
由於鍊錶中的各個結點是由指標鏈結在一起的,其儲存單元文筆是連續的,因此,對其中任意結點的位址無法向陣列一樣,用乙個簡單的公式計算出來,進行隨機訪問。只能從鍊錶的頭指標(即head)開始,用乙個指標p先指向第乙個結點,然後根據結點p找到下乙個結點。以此類推,直至找到所要訪問的結點或到最後乙個結點(指標為空)為止。
下面我們給出上述鍊錶的輸出函式;
void list::outputlist()
cout<
node*p,*q,*s; //p指向結點a,q指向結點a_k,s指向結點b
s=(node*)new(node); //動態分配乙個新結點
s->data=bdate; //設b為此結點
p=head;
if(head==null) //若是空表,使b作為第乙個結點
else
if(p->data==adate) //若a是第乙個結點
else
if(p->data==adate) ///若有結點a
else //若沒有結點a; }}
4. 鍊錶結點的刪除
如果要在鍊錶中刪除結點a並釋放被刪除的結點所佔的儲存空間,則需要考慮下列幾種情況。
(1) 若要刪除的結點a是第乙個結點,則把head指向a的下乙個結點。
(3) 空表或要刪除的結點a不存在,則不做任何改變。
以下是鍊錶類的結點刪除函式。
void list::deletelist(int adate) //設adate是要刪除的結點a中的資料成員
else
if(p->data==adate) //若有結點a}}
例題;利用以上三個鍊錶操作成員函式insertlist,deletelist.outputlist,可形成以下的簡單鍊錶操作程式。
#include"iostream.h"
struct node
;class list
void insertlist(int adata,int bdata);
void deletelist(int adata);
void outputlist();
node*gethead()
};void list::insertlist(int adata,int bdata) //設adata是結點a中的資料,bdata是結點b中的資料
else
if(p->data==adata) //若a是第乙個結點
else
if(p->data==adata) ///若有結點a
else //若沒有結點a;}}
void list::deletelist(int adata) //設adata是要刪除的結點a中的資料成員
else
if(p->data==adata) //若有結點a}}
void list::outputlist()
cout<
void main()
;a.insertlist(0,data[0]); //建立鍊錶a首結點
for(int i=1;i<10;i++)
a.insertlist(0,data[i]); //順序向後插入
cout<<"\n鍊錶a:";
a.outputlist();
a.deletelist(data[7]);
cout<<"刪除元素data[7]後";
a.outputlist();
b.insertlist(0,data[0]); //建立鍊錶b首結點
for(i=1;i<10;i++)
b.insertlist(b.gethead()->data,data[i]); //在首結點處順序向後插入
cout<<"\n鍊錶b:";
b.outputlist();
b.deletelist(67);
cout<<"刪除元素67後";
b.outputlist();
}程式執行結果為
鍊錶a;25,41,16,98,5,67,9,55,1,121
刪除元素data[7]後;
25,41,16,98,5,67,9,1,121
鍊錶b;121,1,55,9,67,5,98,16,41,25,
刪除元素67後;
121,1,55,9,5,98,16,41,25,
使用類建立鍊錶建立學生管理系統
在學生管理系統中經常需要使用陣列來進行物件的儲存,對於一些直觀的問題,陣列確實能夠大致的解決,但是陣列卻不能夠很好判斷越界問題以及對於資料成員數量的計算,而鍊錶能很好地解決這些問題。ps 因為學生管理系統可能還需派生出其他的人員,所以使用繼承 class date char getname cons...
C 建立鍊錶
自己儲存一下,建立鍊錶的程式,省的以後每次建立鍊錶的時候,還需要重新在寫。通過下面的 建立的鍊錶節點數為10,每個節點儲存的數為其下標即 0 9 這裡要注意一點,在void createlist listnode phead 的時候,用的是指標引用,因為在main中head並沒有開闢空間,如果在cr...
鍊錶建立,使用,銷毀
建立乙個鍊錶並輸出最後銷毀鍊錶 include include define n 5 鍊錶節點個數 struct node void creat linklist node l 建立 for i 1 i n 2 i 中間元素賦值 scanf d num 最後乙個元素賦值 p data num p n...