涉及到單鏈表的基本操作有如下:
int initlist(linklist *); //初始化乙個單鏈表,具有頭指標,頭結點,頭結點->next=null;
int createlisthead(linklist *, int n); //頭插法建立乙個鍊錶,鍊錶長度為n;
int createlisttail(linklist *, int n); //尾插法建立乙個鍊錶,鍊錶長度為n;
int getlength(linklist *); //獲取單鏈表的長度;
int printlist(linklist *); //列印整個鍊錶;
int getelem(linklist *,int i,elemtype *); //獲取鍊錶中第i個位置處節點的資料元素;
int insertlist(linklist *, int i, elemtype data); //在鍊錶的指定位置(i節點)插入乙個節點,i的範圍為1~length(鍊錶總長度);
int insertlisttail(linklist *, elemtype data); //給鍊錶追加乙個節點,在最末尾處增加;
int deletelist(linklist *, int i, elemtype *data); //刪除指定位置(i節點)處的節點,i的範圍為1~length(鍊錶總長度);
int clearlist(linklist *); //刪除整個鍊錶,使頭結點->next=null;
(一)adt:
typedef int elemtype;
typedef struct node node;
typedef struct node* linklist;
(二)初始化:int initlist(linklist *l)
int initlist(linklist *l)
初始化乙個指向頭節點的指標,使頭指標->next=null,頭指標->data不做處理;
(三)建立乙個單鏈表
int createlisthead(linklist *l,int n)
printf("鍊錶(頭插法)建立成功\n");
return 1;
}
說明:
1、圖中的head表示頭指標,而在建立單鏈表中的入參phead是指向指標的指標;即*phead等同於head,*head指向頭節點;
2、初始化和建立整表的函式中,為什麼入參是linklist *型別的引數呢,為什麼不是node *型別的;之前我的理解是可以使用node*型別的入參,這樣宣告乙個node *head,這樣在建立整表的函式中可以直接createlist(head,10),直接傳入頭指標,但是嘗試過以後,會在通過頭指標訪問各節點資料的時候,彈出錯誤視窗,原因還不太清楚;
3(補充)在看《c和指標》258的時候,看到了這麼一句話,好像可以解釋為什麼需要傳入鍊錶的基本操作函式中的入參是乙個指標型別的變數;
「i='a';*pi='a';**ppi='a'; //這三條語句具有同樣的效果;i-整型變數,pi-指向i的指標,ppi-指向pi指標的指標;
在一條簡單的對i賦值的語句就可以完成任務的情況下,為什麼還要使用更為複雜的涉及間接訪問的方法呢?這是因為簡單賦值並不總是可行,例如鍊錶的插入。在那些函式中,我們無法使用簡單賦值,因為變數名在函式的作用域內部是未知的。函式所擁有的只是乙個指向需要修改的記憶體位置的指標,所以要對該指標進行間接訪問操作以訪問需要修改的變數。
printf("鍊錶(尾插法)建立成功\n");
(四)獲取鍊錶的長度
int getlength(linklist *l)
return length;
}
(五)列印整個鍊錶
int printlist(linklist *l)
while (p)
return 1;
}
(六)獲取指定位置處的節點元素;
int getelem(linklist *l, int i, elemtype *getdata)
if (i < 1)
int j = 1;
while (p&&jnext;
}if (p == null)
*getdata = p->data;
printf("查詢成功!\n", i);
return 1;
}
(七)插入節點;插入節點分為兩種,一種是在鍊錶的長度範圍內插入節點,第二種是在鍊錶的尾部追加乙個節點;
假設鍊錶的長度為10,第一種可以在1-10位置處插入節點,比如在第10個位置插入乙個節點,則原先的第10節點變為了11節點,但是第二種是所有節點位置都不變,在第11個位置追加乙個新的節點;
int insertlist(linklist *l, int i, elemtype data)
// 鍊錶非空的情況下,可以在i=1~length的位置插入節點,如果超過了鍊錶的長度,就會提示錯誤;
// 其實如果在length+1的位置處插入乙個新節點,就相當於在尾部追加乙個節點,在本函式中會報錯,可以單獨實現乙個函式;
while(p && jnext;
//printf("j=%d\tp->data=%d\n", j, p->data);
}if (p->next==null)
insnode = (linklist)malloc(sizeof(node));
insnode->data = data;
insnode->next = p->next;
p->next = insnode;
printf("節點插入成功\n");
return 1;
}
追加節點;
int insertlisttail(linklist *l, elemtype data)
p = (linklist)malloc(sizeof(node));
p->data = data;
p->next = null;
temp->next = p;
printf("節點插入成功\n");
return 1;
}
(八)刪除節點;
int deletelist(linklist *l, int i, elemtype *data)
while (p->next && jnext;
//printf("j=%d\t p->data=%d\n",j,p->data);
}//條件最多定位到最後乙個節點;
if ( p->next == null)
pnext = p->next;
p->next = pnext->next;
*data = pnext->data;
free(pnext);
printf("節點刪除成功\n");
return 1;
}
(九)刪除這個鍊錶;
int clearlist(linklist *l)
(*l)->next = null;
printf("整個鍊錶已經clear.\n");
return 1;
}
資料結構之鍊錶操作
線性表鏈式儲存結構定義 為了表示每個資料元素ai與其後繼資料元素ai 1之間的邏輯關係,對資料元素ai來說,除了儲存其本身資訊外,還需儲存乙個指示其直接後繼的資訊。我們把儲存資料元素的域稱為資料域,把儲存直接後繼位置的域稱為指標域。指標域中儲存的資訊稱為指標或鏈。這兩部分資訊組成資料元素ai的儲存影...
資料結構之鍊錶操作
1 基本概念 鏈式儲存結構不需要用位址連續的儲存單元來實現,而是通過 鏈 建立起資料元素之間的順序關係,因此它不要求兩個在邏輯上相鄰的資料元素在物理邏輯上也相鄰。從而,在插入和刪除元素的時候,不需要對原來的資料元素進行移動,只需要改變鍊錶節點之間的指向關係即可,從而提公升了執行時效率。2 主要儲存結...
資料結構之鍊錶操作
面試中單鏈表的相關操作也是常考的內容,本博文也是之前學習時的筆記,在此記錄下來,以便日後用到,同時歡迎批評指正。一 基本操作typedef struct lnode 2.鍊錶的銷毀 void destorylist linklist l else l next ptemp 3.鍊錶的判空 bool ...