溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C語言怎么實現單鏈表

發布時間:2021-09-07 14:33:56 來源:億速云 閱讀:178 作者:chen 欄目:開發技術

這篇文章主要介紹“C語言怎么實現單鏈表”,在日常操作中,相信很多人在C語言怎么實現單鏈表問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”C語言怎么實現單鏈表”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

目錄
  • 一、單鏈表與順序表的區別:

    • 一、順序表:

    • 二、鏈表

  • 二、關于鏈表中的一些函數接口的作用及實現

    • 1、頭文件里的結構體和函數聲明等等

    • 2、創建接口空間

    • 3.尾插尾刪

    • 4、頭插頭刪

    •  5、單鏈表查找

    • 6、中間插入(在pos后面進行插入)

    •  7、中間刪除(在pos后面進行刪除)

    • 8、單獨打印鏈表和從頭到尾打印鏈表

    • 9、test.c


一、單鏈表與順序表的區別:

一、順序表:

1、內存中地址連續

2、長度可以實時變化

3、不支持隨機查找

4、適用于訪問大量元素的,而少量需要增添/刪除的元素的程序

5、中間插入或者刪除比較方便,內存命中率較高

二、鏈表

1、內存中地址不連續(邏輯上連續,物理上不連續)

2、長度可以實時變化(避免浪費空間)

3、不支持隨機查找,查找的時間復雜度為o(1),

4、適用于訪問大量元素的,對訪問元素無要求的程序

5、中間插入或者刪除比較方便,效率高

二、關于鏈表中的一些函數接口的作用及實現

1、創建接口,開辟空間

2、尾插尾刪

3、頭插頭刪

4、查找并修改

5、中插中刪

ps:我看了許多的單鏈表文章,在插刪的接口實現上大多數是往前進行插刪,這里寫的則是往后進行插刪

1、頭文件里的結構體和函數聲明等等

#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
 
 
typedef int SListDataType;
//節點
typedef struct SListNode
{
	SListDataType data;
	struct SListNode* next;
}SListNode;
 
//struct SList
//{
//	SListNode* head;
//	SListNode* tail;
//};
 
//尾插尾刪
void SListPushBack(SListNode** pphead, SListDataType x);
void SListPopBack(SListNode** pphead);
 
//頭插頭刪
void SListPushFront(SListNode**  pphead, SListDataType x);
void SListPopFront(SListNode** pphaed);
 
void SListPrint(SListNode* phead);
//查找并修改
SListNode* SListFind(SListNode* phead, SListDataType x);
//中插中刪
void SListInserAfter(SListNode**pphead,SListNode* pos, SListDataType x);
void SListEraseAfter(SListNode* pos);
 
//從頭到尾打印鏈表
void PrintTailToHead(SListNode* pList);

2、創建接口空間

//開辟的下一個空間
SListNode* BuySListNode(SListDataType x)
{
	SListNode* newNode = (SListNode*)malloc(sizeof(SListNode));
	if (newNode == NULL)
	{
		printf("申請結點失敗\n");
		exit(-1);
	}
	newNode->data = x;
	newNode->next = NULL;
	return newNode;
 
}

3.尾插尾刪

//尾插
void SListPushBack(SListNode** pphead, SListDataType x)
{
	SListNode* newNode = BuySListNode(x);//我們指向頭指針的那個結點是**pphead,*pphead就是頭指針的地址
	//如果頭指針的地址為空,我們就把新開辟的這個空間指針(已經傳入值)再賦給頭指針,也就是下面的這個if循環
	if (*pphead == NULL)
	{
		*pphead = newNode;
	}
	else
	{
		//找尾巴,判斷尾巴是不是空地址,這個函數實現的是尾插,我們找到尾巴后,如果尾巴是空地址,我們將插入的newNode賦給尾巴,此時
		//實現了尾插,在下面的代碼中,我們首先把頭指針當成尾巴,從頭指針開始依次往后找,如果下一個不是空指針,我們就令
		//tail=tail->next,此時指向下一個結點,進入循環繼續判斷,當找到后,我們再令尾巴=newNode,在上面我們也判斷了頭指針為空的情況
		SListNode* tail = *pphead;
		while (tail->next!= NULL)
		{
			tail = tail -> next;
		}
		tail->next = newNode;
	}
}
void SListPopBack(SListNode** pphead)
{
	//1、空
	//2、一個結點
	//3、一個以上
	if (*pphead == NULL)
	{
		return;
	}
	else if ((*pphead)->next == NULL)
	{
		free(*pphead);
		*pphead = NULL;
	}
	else
	{
		SListNode* prev = NULL;
		SListNode* tail = *pphead;
		while (tail->next != NULL)
		{
			prev = tail;
			tail = tail->next;
 
		}
		free(tail);
		//tail = NULL;//這個無所謂,因為我們釋放后,出了這個作用域,tail和prev都被銷毀,沒人能拿到,所以不會被再找到
		prev->next = NULL;	
	}
}

4、頭插頭刪

//頭插頭刪
void SListPushFront(SListNode** pphead, SListDataType x)
{
	SListNode* newnode = BuySListNode(x);
	newnode->next = *pphead;
	*pphead = newnode;
}
void SListPopFront(SListNode** pphead)
{
	//1、空
	//2、一個結點+3、一個以上
	
	if (*pphead == NULL)
	{
		return;
	}
	//(*phead)->next:*和>都是解引用,同一優先級,我們需要給*pphead帶括號,(*pphead)->next才是下一個結點
	
	else{
		//我們頭刪也會遇到情況,我們刪除第一個的話,第一個里面還存有第二個結點的地址,我們必須在刪除前,保存第二個結點的地址
		SListNode* next = (*pphead)->next;
		free(*pphead);//通過調試我們發現:free前后,*pphead的地址不變,但是*pphead里的值被置為隨機值,free不僅僅把這塊空間還給操作系統
		  //而且還把這塊空間存的值和地址都置為隨機值
		*pphead = next;
	}
 
}

 5、單鏈表查找

//單鏈表查找
SListNode* SListFind(SListNode* phead, SListDataType x)
{
	SListNode* cur = phead;
	while (cur)
	{
		if (cur->data == x)
		{
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
}

6、中間插入(在pos后面進行插入)

void SListInserAfter(SListNode** pphead,SListNode* pos, SListDataType x)
{
	assert(pos && pphead);
	if (*pphead == pos)
	{
		SListPushFront(pphead, x);
	}
	else
	{
		SListNode* newnode = BuySListNode(x);
		SListNode* tmp = *pphead;
		while (tmp->next != pos)
		{
			tmp = tmp->next;
		}
		tmp->next = pos;
		pos->next = newnode;
 
	}
	
}

 7、中間刪除(在pos后面進行刪除)

void SListEraseAfter(SListNode* pos)
{
	//刪除pos后面的
	assert(pos);
	if (pos->next)
	{
		//pos->next=pos->next->next//不推薦
		SListNode* next = pos->next;
		SListNode* nextnext = next->next;
		pos->next = nextnext;
		free(next);
	}
}

8、單獨打印鏈表和從頭到尾打印鏈表

void SListPrint(SListNode* phead)
{
	SListNode* cur = phead;
	while (cur != NULL)
	{
		printf("%d->", cur->data);
		cur = cur->next;
	}
	printf("NULL\n");
}
 
 
 
void PrintTailToHead(SListNode* pList)
{
	if (pList == NULL)
	{
		return;
	}
	PrintTailToHead(pList->next);
	printf("%d->",pList->data);
}

9、test.c

#include"SList.h"
 
TestSList1()
{
 
	SListNode* pList = NULL;//這個結構體指針指向開辟的空間,頭指針指向鏈表的開頭
	SListPushBack(&pList, 1);
	SListPushBack(&pList, 2);
	SListPushBack(&pList, 3);
	SListPushBack(&pList, 4);
	SListPrint(pList);
 
	SListPopBack(&pList);
	SListPopBack(&pList);
	SListPopBack(&pList);
	SListPopBack(&pList);
	SListPopBack(&pList);
	SListPrint(pList);
 
	SListPushFront(&pList, 1);
	SListPushFront(&pList, 2);
	SListPushFront(&pList, 6);
	SListPushFront(&pList, 4);
	SListPushFront(&pList, 5);
	SListPrint(pList);
	SListPopFront(&pList);
	SListPopFront(&pList);
	SListPopFront(&pList);
	SListPopFront(&pList);
	SListPopFront(&pList);
	SListPopFront(&pList);
	SListPrint(pList);
 
 
}
 
TestSList2()
{
	SListNode* pos1;
	SListNode* pList = NULL;//這個結構體指針指向開辟的空間,頭指針指向鏈表的開頭
	SListPushBack(&pList, 1);
	SListPushBack(&pList, 2);
	SListPushBack(&pList, 3);
	SListPushBack(&pList, 4);
	SListPrint(pList);
	SListNode* pos = SListFind(pList, 3);
	if (pos)
	{
		pos->data = 30;//這里將cur-data改為pos->data,然后再將pos-data原來的值改為30
	}
	SListPrint(pList);
	pos1 = SListFind(pList, 30);//我們先去找到這個pos1的位置,然后再去插入
	SListInserAfter(&pList,pos1,50);//函數傳參要對應起來,我們用指針傳用指針接收,不能在pos1位置直接寫個數字
	SListPrint(pList);
	SListEraseAfter(pos1);//pList指向第一個結點,pList->next指向第二個結點,那么我們刪除的是目標節點后面
	SListPrint(pList);
	//PrintTailToHead(&pList);
}
int main()
{
	TestSList1();
	TestSList2();
	return 0;
	
 
}

到此,關于“C語言怎么實現單鏈表”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女