單鏈表的建立,查詢(按值查詢),銷燬,列印
阿新 • • 發佈:2018-12-14
單鏈表是資料結構中較為“簡單”的一部分,但是它卻是很重要的一部分。二叉樹,線索二叉樹,雜湊函式等等的相關操作都離不開連結串列,因此搞懂單鏈表顯得尤為重要。下面是我對連結串列簡單操作的一些理解。(本文中所有連結串列程式碼均無頭結點,ppFirst指的是首元結點)
首先,單鏈表的本質得先清楚。單鏈表是一種鏈式儲存的線性表。它可以解決陣列無法儲存多種型別的問題。我們通過圖簡單的認識一下連結串列:
其次,單鏈表的相關操作需要掌握。(重中之重)
1 單鏈表成員的建立,即結點的建立。
連結串列結點的建立,首先宣告結構體,結構體中包括資料域和指標域:程式碼如下所示:
typedef int DataType;
//建立單鏈表的成員,其實就是結點
typedef struct SListNode {
DataType data; // 值
struct SListNode *pNext; // 指向下一個結點
} SListNode; //SListNode為這個結構體的別名
2 初始化單鏈表
初始化單鏈表也就是將首元結點初始化為空,程式碼如下:
void SListInit(SListNode **ppFirst)
{
*ppFirst = NULL;
}
3 列印單鏈表
列印單鏈表,首先判斷連結串列是否為空,為空則直接列印“空連結串列”,否則迴圈打印出每個結點的資料
//列印
void SListprint(SListNode *ppFirst)
{//判斷是否為空連結串列
SListNode *p = ppFirst;
if(p == NULL)
{
printf("空連結串列\n");
}
else{
//非空連結串列:迴圈列印每個連結串列的data,迴圈結束條件為遇到空指標
for(p = ppFirst;p != NULL;p = p->pNext)
{
printf("%d ",p->data);
}
printf("NULL\n");
}
}
4 建立新結點
建立新的結點,新結點包含資料域和指標域。將其封裝為函式,呼叫更加方便。主要程式碼如下:
//建立新結點,結點的資料域為data,pNext域設定為空
SListNode *_CreateNode(DataType data)
{
SListNode *NewNode; //宣告新結點
NewNode = (SListNode *)malloc(sizeof(SListNode));//建立新結點
if(NewNode == NULL)
{
return;
}//建立失敗
NewNode ->data = data;
NewNode ->pNext = NULL;//建立成功
}
5 單鏈表的查詢
按值查詢,找到後返回第一個的結點指標,如果沒找到,返回NULL
// 按值查詢,返回第一個找到的結點指標,如果沒找到,返回NULL
SListNode * SListFind(SListNode *ppFirst, DataType data)
{
SListNode *cur;
//順序查詢,去遍歷
for(cur = ppFirst; cur != NULL; cur = cur->pNext)
{
if( cur->data == data)
{
return cur;
}
}
return NULL;
}
6 銷燬單鏈表
銷燬單鏈表也就是將每個結點free掉,並且將首元結點置空。
// 銷燬 (記錄並刪除連結串列中的每個結點,並將頭結點置為空)
void SListDestroy(SListNode **ppFirst)
{
SListNode *pre;
SListNode *cur;
assert(*ppFirst);
pre = *ppFirst;
for(pre = *ppFirst; pre != NULL;pre = cur)
{
cur = pre ->pNext;
free(pre);
}
*ppFirst = NULL;
}
7 單鏈表的尾插
此處未做詳細說明,連結串列的插入以及刪除在下一篇部落格中詳細說明。
// 尾部插入(先找到最後一個結點,並把它記錄下來,再把最後一個結點的pNext域指向新的結點)
void SListPushBack(SListNode** ppFirst, DataType data)
{
SListNode *p;//新結點p
SListNode *p1;
p = _CreateNode(data);
p1 = *ppFirst;//用來遍歷連結串列(開始位於頭結點處)
//空連結串列
if( (*ppFirst) == NULL ){
*ppFirst = p;
return;
} else{
for(p1 = *ppFirst;p1->pNext != NULL;p1 = p1->pNext)
{
}
p1 ->pNext = p;//此時p1為最後一個結點
}
}
上述連結串列操作的測試程式碼如下:
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <windows.h>
int main()
{
SListNode *result;
SListNode *p1;
SListInit(&p1);
SListPushBack(&p1,1);
SListPushBack(&p1,2);
SListPushBack(&p1,3);
SListPushBack(&p1,2);
SListPushBack(&p1,5);
SListPushBack(&p1,2);
SListPushBack(&p1,6);
result = SListFind(p1,5);
SListprint(result);
SListDestroy(&p1);
SListprint(p1);
system("pause");
return 0;
}
上述僅僅是單鏈表的簡單操作,重要的插入與刪除將在下一篇部落格中詳細說明。