1. 程式人生 > >單鏈表的建立,查詢(按值查詢),銷燬,列印

單鏈表的建立,查詢(按值查詢),銷燬,列印

       單鏈表是資料結構中較為“簡單”的一部分,但是它卻是很重要的一部分。二叉樹,線索二叉樹,雜湊函式等等的相關操作都離不開連結串列,因此搞懂單鏈表顯得尤為重要。下面是我對連結串列簡單操作的一些理解。(本文中所有連結串列程式碼均無頭結點,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;
}

        上述僅僅是單鏈表的簡單操作,重要的插入與刪除將在下一篇部落格中詳細說明。