資料結構之連結串列操作
阿新 • • 發佈:2019-02-09
之前看資料結構時,以為連結串列操作很容易,真正寫程式碼時才發現被打臉了。。。經歷了各種錯誤後,現在總結一下走過的彎路。
這裡主要說下連結串列的增加刪除節點操作。
typedef struct lnode
{
int data;
struct lnode *next;
}lnode,*llist;
以上是我定義的節點結構,比較簡單,不再贅述。
下面說下犯的錯誤
錯誤1. addnode函式為增加節點操作
void addnode(lnode *lst,int value)
{
lnode *p=new lnode();
p->data=value;
p-> next=NULL;
if (lst==NULL) {
lst=p;
return;
}
lnode *q=lst;
while (q->next) {
q=q->next;
}
q->next=p;
}
好吧,上面屬於低階錯誤,但是一遇到指標就有些搞不清楚。所以這裡想總結一下。
lst為存放lnode結構體地址的指標,初始值為空,在addnode函式體內,對lst賦值,lst改變,但是出了函式,lst仍然為原來值,這是典型的值傳遞(lst內容即地址的值傳遞),行參的改變不影響實參。如果是基本變數,沒有搞錯過,but加了個指標就搞混了。。所以為了改變實參,這裡採用了指標傳遞。
錯誤2.
void addnode(llist *lst,int value)
{
lnode *p=new lnode();
p->data=value;
p->next=NULL;
if (lst==NULL) {
*lst=p;
return;
}
lnode *q=*lst;
while (q->next) {
q=q->next;
}
q->next=p;
}
對待二維指標,一定要認真搞清楚哪個變數指向什麼
lst結構如圖所示,lst是地址,地址中存放的內容*lst為p的地址,p中存放的內容*p為lnode的地址。
錯誤2就在於沒有搞清lst=null和*lst=null的區別。
lst=null也就是lst指向0x0000000000000000地址(核心地址,不能訪問),此時,可以對lst另賦值,讓lst指向其他地址,但是不能改變*lst 。
所以,正確的做法應該是判斷*lst是否為null,此時lst為自己的地址,*lst記憶體放的是p的地址,若*lst為null,則說明p為空,即沒有指標指向連結串列,即連結串列為空。
經歷了以上兩次錯誤,最終得到正確答案,在進行插入操作時,要注意連結串列為空的情況;刪除時,也需要注意刪除第一個節點的情況。
正確程式碼:
void addnode(llist *lst,int value)
{
lnode *p=new lnode();
p->data=value;
p->next=NULL;
if (*lst==NULL) {
*lst=p;
return;
}
lnode *q=*lst;
while (q->next) {
q=q->next;
}
q->next=p;
}
void deletenode(llist *p,int value)
{
if (p==NULL||(*p)==NULL) {
return;
}
else
{
lnode *q=*p;
lnode *r=q;
if (q->data==value) {
*p=q->next;
delete q;
q=NULL;
return;
}
while (q->next && q->data!=value) {
r=q;
q=q->next;
}
if (q->data==value) {//判斷最後一個節點是否為value
r->next=q->next;
delete q;
q=NULL;
}
}
}