鍊錶是一種物理儲存結構上非連續、非順序的儲存結構,資料元素的邏輯順序是通過鍊錶中的指標鏈結次序實現的 。
實際中煉表的結構非常多樣,以下情況組合起來就有8種鍊錶結構:
1. 單向、雙向
2. 帶頭、不帶頭
3. 迴圈、非迴圈
帶頭雙向迴圈鍊錶:結構最複雜,一般用在單獨儲存資料。實際中使用的鍊錶資料結構,都是帶頭雙向迴圈鍊錶。另外這個結構雖然結構複雜,但是使用**實現以後會發現結構會帶來很多優勢,實現反而簡單了。
標頭檔案,裡面給出了鍊錶的定義以及基本操作函式的宣告
typedef int sdatatype;
typedef struct slistnode
node;
// 給乙個鍊錶結構
typedef struct slist
slist;
// 鍊錶的初始化
void slistinit(slist* pl);
// 在鍊錶中尾插值為data的節點
void slistpushback(slist* pl, sdatatype data);
// 刪除鍊錶最後乙個節點
void slistpopback(slist* pl);
// 在鍊錶第乙個元素前插入值為data的節點
void slistpushfront(slist* pl, sdatatype data);
// 刪除鍊錶中第乙個節點
void slistpopfront(slist* pl);
// 在鍊錶pos位置後插入置為data的節點
void slistinsertafter(slist *pl, node* pos, sdatatype data);
// 刪除鍊錶中的pos後面的節點
void slisteraseafter(slist* pl, node* pos);
// 在鍊錶中查詢值為data的節點,找到返回該節點的位址,否則返回空
node* slistfind(slist* pl, sdatatype data);
// 銷毀鍊錶
void slistdestroy(slist* pl);
// 獲取鍊錶中有效節點的個數
int slistsize(slist* pl);
// 檢測鍊錶是否為空
int slistempty(slist* pl);
// 獲取鍊錶的第乙個節點
node* slistfront(slist* pl);
// 獲取鍊錶的第二個節點
node* slistback(slist* pl);
// 刪除鍊錶中第乙個值為data的節點
void slistremove(slist* pl, sdatatype data);
// 刪除鍊錶中所有值為data的節點
void slistremoveall(slist* pl, sdatatype data);
函式定義
#include #include #include "slist.h"
#include // 鍊錶的初始化
void slistinit(slist* pl)
// 在鍊錶中尾插值為data的節點
void slistpushback(slist* pl, sdatatype data)
//鍊錶中至少有乙個節點,找到最後乙個節點
node *cur = pl->_phead;
while (cur->_pnext != null)
cur->_pnext = node;
}// 刪除鍊錶最後乙個節點
void slistpopback(slist* pl)
//不止乙個節點
node *cur = pl->_phead;
while (cur->_pnext->_pnext != null)
free(cur->_pnext);
cur->_pnext = null;
}// 在鍊錶第乙個元素前插入值為data的節點
void slistpushfront(slist* pl, sdatatype data)
// 刪除鍊錶中第乙個節點
void slistpopfront(slist* pl)
// 在鍊錶pos位置後插入值為data的節點
void slistinsertafter(slist *pl, node* pos, sdatatype data)
// 刪除鍊錶中的pos後面的節點
void slisteraseafter(slist* pl, node* pos)
// 在鍊錶中查詢值為data的節點,找到返回該節點的位址,否則返回空
node* slistfind(slist* pl, sdatatype data)
cur = cur->_pnext;
} return null;
}// 銷毀鍊錶
void slistdestroy(slist* pl)
pl->_phead = null;
}// 獲取鍊錶中有效節點的個數
int slistsize(slist* pl)
return size;
}// 檢測鍊錶是否為空
int slistempty(slist* pl)
return 0;
}// 獲取鍊錶的第乙個節點
node* slistfront(slist* pl)
// 獲取鍊錶的第二個節點
node* slistback(slist* pl)
// 刪除鍊錶中第乙個值為data的節點
void slistremove(slist* pl, sdatatype data)
//為頭節點
if (pl->_phead->_data == data)
//不是頭節點
node *cur = pl->_phead;
while (cur != null)
cur = cur->_pnext; }}
// 刪除鍊錶中所有值為data的節點
void slistremoveall(slist* pl, sdatatype data)
//為第乙個節點
if (pl->_phead->_data == data)
//不是第一乙個節點
node *cur = pl->_phead;
while (cur->_pnext != null)
cur = cur->_pnext; }}
//列印函式
void pri(slist* pl)
printf("\n");
return;
}
下面是測試的main函式
int main()
else
//獲取煉表頭節點
printf("鍊錶的頭節點為:%d %p\n", slistfront(&list)->_data, slistfront(&list));
printf("\n");
//獲取鍊錶第二個節點
printf("鍊錶的第二個節點為:%d %p\n", slistback(&list)->_data, slistback(&list));
printf("\n");
//頭插
slistpushfront(&list, 30);
slistpushfront(&list, 20);
slistpushfront(&list, 30);
slistpushfront(&list, 10);
//刪除鍊錶中第乙個值為30的節點
slistremove(&list, 30);
// 10 20 30 20 30 1
printf("刪除鍊錶中第乙個值為30的節點後:\n");
pri(&list);
//刪除鍊錶中所有值為30的節點
slistremoveall(&list, 30);
// 10 20 20 1
printf("刪除鍊錶中所有值為30的節點後:\n");
pri(&list);
//銷毀鍊錶
slistdestroy(&list);
//銷毀後判斷鍊錶是否為空,為空返回 1,不為空返回 0
if (slistempty(&list) == 1)
else
printf("鍊錶不為空\n");
system("pause");
return 0;
}
C語言實現鍊錶基本操作
之前說過順序表的基本操作。顯然,順序表有乙個很大的缺點,就是做插入刪除操作的時候,往往要做很大量的元素移動的操作。這裡我們討論另外一種線性表的表示方法 鏈式儲存結構。由於它不需要邏輯上的相鄰的元素在物理位置上也相鄰,因此它沒有順序儲存結構所具有的弱點,但是同時也失去了順序表的可隨機訪問的有點。inc...
鍊錶的基本操作(C語言實現
鍊錶的基本操作 c語言實現 include include define ok 1 define error 0 typedef int elemtype typedef int status typedef struct lnodelnode,linklist status initlist l ...
2 8靜態鍊錶基本操作(C語言實現)
上節,我們初步建立了乙個靜態鍊錶 本節學習有關靜態鍊錶 的一些基本操作,包括對錶中資料元素的新增 刪除 查詢和更改。本節是建立在已能成功建立靜態鍊錶的基礎上,因此我們繼續使用上節中已建立好的靜態鍊錶學習本節內容,建立好的靜態鍊錶如圖 1 所示 圖 1 建立好的靜態鍊錶 例如,在圖 1 的基礎,將元素...