線性表是數據結構中比較重要的一種結構。線性表可以用連續存儲空間來表示,也可以用鏈表的形式表示。鏈式存儲結構不要求在邏輯上相鄰的元素在物理位置上也相鄰,因此他在插入元素和刪除元素上具有着得天獨厚的優勢,但是卻失去了順序存儲中可隨機存儲的優點。
線性鏈表中每個元素被存放在一個叫做結點的地方,結點包含一個數據域和一個指針域,數據域存放元素,指針域存放着指向下一個結點的指針。若鏈表的結點中只包含一個指針域,那麼這個鏈表被稱爲線性鏈表或者單鏈表。有時我們會在第一個結點前加上一個結點,這個結點的數據域可以不存放內容,也可以存放數據元素的個數,指針域指向第一個結點,當頭結點的指針域爲空時,那麼這個鏈表就爲一個空鏈表。
下面是實現單鏈表的代碼:
首先定義一個結點結構體:包含一個數據域和一個指針域
typedef struct LNode
{
int data;
LNode *next;
}LNode,*LinkList;
下面來創建一個鏈表:輸入爲元素的個數,此鏈表具有頭結點
void createList(LinkList &L,int n) //這裏一定要加引用傳遞
{
L=new LNode;
L->next=NULL;
LinkList p=NULL;
for(int i=n;i>0;i--)
{
p=new LNode;
cin>>p->data;
p->next=L->next;
L->next=p;
}
}
第一個參數要加引用傳遞,原因下面會講到;
下面是關於在某個位置往鏈表中插入一個元素的代碼:
bool listInsert(LinkList L,int i,int e)
{
LinkList p=L;int j=0;
while(p && j<i-1)
{
p=p->next;
j++;
}
if(!p||j>i-1) return false;
LinkList s=new LNode;
s->data=e;
s->next=p->next;
p->next=s;
return true;
}
接下來是獲得鏈表中某個位置上元素的數據的代碼:
bool getElem(LinkList L,int i,int &e)
{
LinkList p=NULL;
p=L->next;
int j=0;
while(j<i)
{
p=p->next;
j++;
}
if(!p||j>i) return false;
e=p->data;
return true;
}
最後寫了測試代碼的程序:
void main()
{
LNode *p=NULL;
createList(p,5);
int x=0;
cout<<"before inserting: ";
showList(p);
listInsert(p,1,20);
cout<<"after inserting: ";
showList(p);
cout<<"get a value: ";
getElem(p,2,x);
cout<<x<<endl;
}
其中showlist()爲打印鏈表元素的函數:
void showList(LinkList L)
{
LinkList p=L->next;
while(p)
{
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
上面說到爲什麼要加引用傳遞參數呢?那是因爲我們傳遞的是指針,而指針的地址是在調用函數中申請的,等於給指針賦值了,調用函數結束後,這個地址就銷燬了。但是可能有人問那爲什麼我們傳址的函數可以使用指針呢?那是因爲我們在調用前這樣的指針的地址已經存在了。