国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【數(shù)據(jù)結(jié)構(gòu)入門指南】單鏈表

這篇具有很好參考價值的文章主要介紹了【數(shù)據(jù)結(jié)構(gòu)入門指南】單鏈表。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

概述:

?由于順序表插入和刪除元素需要移動大量數(shù)據(jù),導(dǎo)致運行效率下降。因此引入了另一種數(shù)據(jù)結(jié)構(gòu) —— 鏈表。鏈表又分為單鏈表和雙鏈表。單鏈表結(jié)構(gòu)簡單,一般不會單獨用來存數(shù)據(jù)。實際中更多是作為其他數(shù)據(jù)結(jié)構(gòu)的子結(jié)構(gòu),如哈希桶、圖的鄰接表等等。另外這種結(jié)構(gòu)在筆試面試中出現(xiàn)很多。


一. 單鏈表的定義

?單鏈表通過一組任意的存儲單元來存儲線性表中的數(shù)據(jù)元素,不需要使用地址連續(xù)的存儲單元,因此它不要求在邏輯上相鄰的兩個元素在物理位置上也相鄰。

構(gòu)成:

?單鏈表由一系列節(jié)點組成,每個節(jié)點包含兩個部分:數(shù)據(jù)域(存儲數(shù)據(jù)元素)和指針域(存儲下一個節(jié)點地址)。

typedef int SLTDateType;
typedef struct SListNode
{
	SLTDateType date;//數(shù)據(jù)域
	struct SListNode* next;//指針域
}SLTNode;

特點:

  1. 單鏈表的節(jié)點是離散分布在內(nèi)存中的,通過指針將它們串聯(lián)起來。
  2. 單鏈表可以動態(tài)地分配內(nèi)存空間,可以根據(jù)需要靈活地插入、刪除節(jié)點。
    【數(shù)據(jù)結(jié)構(gòu)入門指南】單鏈表,數(shù)據(jù)解構(gòu)和C++學(xué)習(xí)分享,數(shù)據(jù)結(jié)構(gòu),學(xué)習(xí),c++,c語言

二. 單鏈表的創(chuàng)建

typedef int SLTDateType;
typedef struct SListNode
{
	SLTDateType date;//數(shù)據(jù)域
	struct SListNode* next;指針域
}SLTNode;

首先創(chuàng)建一個結(jié)構(gòu)體struct SListNode用來存儲數(shù)據(jù)和指針。
考慮到后續(xù)數(shù)據(jù)類型修改的方便性,我們將struct SListNode 用typedef重命名為SLNode。
同時為方便以后調(diào)用接口實現(xiàn)不同數(shù)據(jù)類型鏈接,我們將數(shù)據(jù)域的類型int重命名為SLDateType。(后續(xù)存儲不停數(shù)據(jù)只需修改此處即可)


三、單鏈表各種接口實現(xiàn)

1. 動態(tài)申請一個結(jié)點

?后續(xù)要插入新節(jié)點時,首先要創(chuàng)建一個節(jié)點來存儲相關(guān)信息,在連接到單鏈表合適位置。

代碼實現(xiàn):

SLTNode* BuySListNode(SLTDateType x)
{
	SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
	if (newnode == NULL)
	{
		perror("malloc");
		exit(-1);
	}
	newnode->date = x;
	newnode->next = NULL;
	return newnode;
}

2. 單鏈表打印

打印單鏈表,我們只需記錄頭節(jié)點,然后遍歷訪問,依次打印即可。

代碼實現(xiàn):

void SLTPrint(SLTNode* phead)
{ 
	SLTNode* cur = phead;
	while (cur)
	{
		printf("%d->", cur->date);
		cur = cur->next;
	}
	printf("NULL\n");
}

3. 尾插

尾插分兩種情況:沒有節(jié)點和有節(jié)點。
①:沒有節(jié)點:創(chuàng)建一個新節(jié)點,然后頭指針指向新節(jié)點。
②:有節(jié)點:遍歷找到最后一個節(jié)點,然后將其下一個節(jié)點指向新節(jié)點

代碼實現(xiàn):

//由于尾插第一種情況需要改變結(jié)構(gòu)體指針,所以我們要傳結(jié)構(gòu)體二級指針
void SLTPushBack(SLTNode** pphead, SLTDateType x)
{
	assert(pphead);
	SLTNode* newnode = BuySListNode(x);
	if (*pphead == NULL)//沒有節(jié)點
	{
		*pphead = newnode;
	}
	else
	{
	    //有節(jié)點
		SLTNode* tail = *pphead;
		while (tail->next)//遍歷找到最后一個節(jié)點
		{
			tail = tail->next;
		}
		//尾插
		tail->next = newnode;
	}
}

4. 頭插

頭插就相對簡單。不管原鏈表有無節(jié)點,只需插入新節(jié)點即可。

代碼實現(xiàn):

//由于頭插會改變頭指針,所以我們傳二級指針
void SLTPushFront(SLTNode** pphead, SLTDateType x)
{
	assert(pphead);
	SLTNode* newnode = BuySListNode(x);//新節(jié)點
	//頭插
	newnode->next = *pphead;
	*pphead = newnode;
}

5. 尾刪

尾刪分3中情況:
①:首先要判斷鏈表中是否還有節(jié)點可刪。
②:鏈表中只有一個節(jié)點。一個節(jié)點比較簡單,將頭指針置空,然后釋放頭節(jié)點即可。
③:鏈表中有多個節(jié)點。多個節(jié)點,首先要遍歷找到尾節(jié)點的前一個節(jié)點。然后將其指針域置空,并釋放尾節(jié)點。

代碼實現(xiàn):

void SLTPopBack(SLTNode** pphead)
{
	assert(pphead);
	//1.空
	assert(*pphead);

	if ((*pphead)->next == NULL)//2.一個節(jié)點
	{
		(*pphead)->next = NULL;
	}
	else
	{
		//3.多個節(jié)點
		SLTNode* tail = *pphead;
		遍歷找到尾節(jié)點的前一個節(jié)點
		while (tail->next->next)
		{
			tail = tail->next;
		}
		free(tail->next);
		tail->next = NULL;
	}

}

6. 頭刪

頭刪分兩種情況:
①:首先判斷鏈表中是否還有節(jié)點可刪。
②:鏈表還有節(jié)點可刪。首先保存第二個節(jié)點,在釋放頭節(jié)點。并將頭指針指向第二個節(jié)點。

代碼實現(xiàn):

void SLTPopFront(SLTNode** pphead)
{
	assert(pphead);
	//空
	assert(*pphead);
	//非空
	SLTNode* newnode = (*pphead)->next;//保存第二個節(jié)點
	free(*pphead);//釋放頭節(jié)點
	*pphead = newnode;
}

7、查找

查找和打印一樣,直接遍歷訪問即可。找到了返回地址,沒有找打返回空指針。

代碼實現(xiàn):

SLTNode* SLTFind(SLTNode* phead, SLTDateType x)
{
	SLTNode* cur = phead;
	while (cur)
	{
		if (cur->date == x)
			return cur;
		cur = cur->next;
	}
	return NULL;
}

8、在pos之前插入x

鏈表中,不管是單鏈表還是雙鏈表在某處插入新節(jié)點,一般默認前插。
前插分兩種情況:
①:pos位置為第一個節(jié)點??梢詮?fù)用前面頭插接口實現(xiàn)。
②: 遍歷訪問鏈表找到pos前一個節(jié)點prev,然后將pos、prev、新節(jié)點連接起來。

代碼實現(xiàn):

void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDateType x)
{
	assert(pphead);
	assert(*pphead);
	if (*pphead == pos)
	{
		SLTPushFront(pphead, x);//頭插
	}
	else
	{
		SLTNode* prev = *pphead;
		//遍歷找到pos前一個節(jié)點
		while (prev->next != pos)
		{
			prev = prev->next;
		}
		SLTNode* newnode = BuySListNode(x);
		//prev,newnode,pos三個節(jié)點鏈接
		prev->next = newnode;
		newnode->next = pos;
	}
}

9、在pos后插入x

在pos之前插入x,相對來所比較復(fù)雜。所以如果沒有特殊要求,可以采用pos后插。所以我們在這提供pos后插接口。

代碼實現(xiàn):

void SLTInsertAfter(SLTNode* pos, SLTDateType x)
{
	assert(pos);

	SLTNode* newnode = BuySListNode(x);
	//后插
	newnode->next = pos->next;
	pos->next = newnode;
}

10、刪除pos位置的值

刪除pos位置的值一樣分兩種情況:
①:如果pos為頭節(jié)點,復(fù)用頭刪接口。
②:遍歷找到pos前一個節(jié)點prev。然后將pos前一個節(jié)點和后一個節(jié)點鏈接起來,并釋放pos即可。

代碼實現(xiàn):

void SLTErase(SLTNode** pphead, SLTNode* pos)
{
	assert(pphead);
	assert(pos);

	if (*pphead == pos)
	{
		SLTPopFront(pphead);
	}
	else
	{
		SLTNode* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}

		prev->next = pos->next;
		//free(pos);
	}
}

11、刪除pos位置之后的值

要刪除pos位置之后的值,我們首先將pos和pos后兩個節(jié)點指針鏈接起來,并釋放pos后一個節(jié)點即可。(要判斷pos是否為尾節(jié)點)

代碼實現(xiàn):

void SLTEraseAfter(SLTNode* pos)
{
	assert(pos);
	//檢查pos是否為尾節(jié)點
	assert(pos->next);

	SLTNode* posNext = pos->next;
	pos->next = posNext->next;

	free(posNext);
	posNext = NULL;
}

12、銷毀

代碼實現(xiàn):

void SLTDestory(SLTNode** pphead)
{
	assert(pphead);

	SLTNode* cur = *pphead;
	while (cur)
	{
		SLTNode* next = cur->next;
		free(cur);
		cur = next;
	}
	*pphead = NULL;
}

四、所有代碼展示

List.h:

#pragma once

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>


typedef int SLTDateType;
typedef struct SListNode
{
	SLTDateType date;
	struct SListNode* next;
}SLTNode;


void SLTPrint(SLTNode* phead);

SLTNode* BuySListNode(SLTDateType x);

void SLTPushBack(SLTNode** pphead, SLTDateType x);
void SLTPushFront(SLTNode** pphead, SLTDateType x);
void SLTPopBack(SLTNode** pphead);
void SLTPopFront(SLTNode** pphead);

SLTNode* SLTFind(SLTNode* phead, SLTDateType x);

//在pos之前插入x
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDateType x);
//在pos之后插入x
void SLTInsertAfter(SLTNode* pos, SLTDateType x);
//刪除pos位置的值
void SLTErase(SLTNode** pphead, SLTNode* pos);
//刪除pos位置之后的值
void SLTEraseAfter(SLTNode* pos);

//銷毀
void SLTDestory(SLTNode** pphead)

List.h:

include "SList.h"


void SLTPrint(SLTNode* phead)
{ 
	SLTNode* cur = phead;
	while (cur)
	{
		printf("%d->", cur->date);
		cur = cur->next;
	}
	printf("NULL\n");
}


SLTNode* BuySListNode(SLTDateType x)
{
	SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
	if (newnode == NULL)
	{
		perror("malloc");
		exit(-1);
	}
	newnode->date = x;
	newnode->next = NULL;
	return newnode;
}


void SLTPushBack(SLTNode** pphead, SLTDateType x)
{
	assert(pphead);
	SLTNode* newnode = BuySListNode(x);
	if (*pphead == NULL)
	{
		*pphead = newnode;
	}
	else
	{
		SLTNode* tail = *pphead;
		while (tail->next)
		{
			tail = tail->next;
		}
		tail->next = newnode;
	}
}


void SLTPushFront(SLTNode** pphead, SLTDateType x)
{
	assert(pphead);
	SLTNode* newnode = BuySListNode(x);
	newnode->next = *pphead;
	*pphead = newnode;
}


void SLTPopBack(SLTNode** pphead)
{
	assert(pphead);
	//1.空
	assert(*pphead);

	//2.一個節(jié)點
	//3.多個節(jié)點
	if ((*pphead)->next == NULL)
	{
		(*pphead)->next = NULL;
	}
	else
	{
		SLTNode* tail = *pphead;
		while (tail->next->next)
		{
			tail = tail->next;
		}
		free(tail->next);
		tail->next = NULL;
	}

}


void SLTPopFront(SLTNode** pphead)
{
	assert(pphead);
	//空
	assert(*pphead);
	//非空
	SLTNode* newnode = (*pphead)->next;
	free(*pphead);
	*pphead = newnode;
}

SLTNode* SLTFind(SLTNode* phead, SLTDateType x)
{
	SLTNode* cur = phead;
	while (cur)
	{
		if (cur->date == x)
			return cur;
		cur = cur->next;
	}
	return NULL;
}

void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDateType x)
{
	assert(pphead);
	assert(*pphead);
	if (*pphead == pos)
	{
		SLTPushFront(pphead, x);
	}
	else
	{
		SLTNode* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}
		SLTNode* newnode = BuySListNode(x);
		prev->next = newnode;
		newnode->next = pos;
	}
}



void SLTInsertAfter(SLTNode* pos, SLTDateType x)
{
	assert(pos);

	SLTNode* newnode = BuySListNode(x);
	newnode->next = pos->next;
	pos->next = newnode;
}

void SLTErase(SLTNode** pphead, SLTNode* pos)
{
	assert(pphead);
	assert(pos);

	if (*pphead == pos)
	{
		SLTPopFront(pphead);
	}
	else
	{
		SLTNode* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}

		prev->next = pos->next;
		//free(pos);
	}
}


void SLTEraseAfter(SLTNode* pos)
{
	assert(pos);
	//檢查pos是否為尾節(jié)點
	assert(pos->next);

	SLTNode* posNext = pos->next;
	pos->next = posNext->next;

	free(posNext);
	posNext = NULL;
}

void SLTDestory(SLTNode** pphead)
{
	assert(pphead);

	SLTNode* cur = *pphead;
	while (cur)
	{
		SLTNode* next = cur->next;
		free(cur);
		cur = next;
	}
	*pphead = NULL;
}

【數(shù)據(jù)結(jié)構(gòu)入門指南】單鏈表,數(shù)據(jù)解構(gòu)和C++學(xué)習(xí)分享,數(shù)據(jù)結(jié)構(gòu),學(xué)習(xí),c++,c語言
【數(shù)據(jù)結(jié)構(gòu)入門指南】單鏈表,數(shù)據(jù)解構(gòu)和C++學(xué)習(xí)分享,數(shù)據(jù)結(jié)構(gòu),學(xué)習(xí),c++,c語言文章來源地址http://www.zghlxwxcb.cn/news/detail-632273.html

到了這里,關(guān)于【數(shù)據(jù)結(jié)構(gòu)入門指南】單鏈表的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 【數(shù)據(jù)結(jié)構(gòu)入門指南】二叉樹

    【數(shù)據(jù)結(jié)構(gòu)入門指南】二叉樹

    二叉樹是一棵特殊的樹。一棵二叉樹是結(jié)點的一個有限集合,該節(jié)點: ①:或者為空。 ②: 由一個根節(jié)點加上兩棵別稱為左子樹和右子樹的二叉樹組成。 從上圖可以看出: 二叉樹不存在度大于2的結(jié)點. 二叉樹的子樹有左右之分,次序不能顛倒,因此二叉樹是有序樹。 Tip

    2024年02月11日
    瀏覽(17)
  • C語言筆記 | 數(shù)據(jù)結(jié)構(gòu)入門指南

    文章目錄 0x00 前言 0x01 百雞百錢 0x1 題目描述 0x2 問題分析 0x3 代碼設(shè)計 0x4 完整代碼 0x5 運行效果 0x6 舉一反三 [兔雞百錢] 0x02 借書方案知多少 0x1 題目描述 0x2 問題分析 0x3 代碼設(shè)計 0x4 完整代碼 0x5 運行效果 0x6 舉一反三 [領(lǐng)導(dǎo)小組方案] 0x03 打魚還是曬網(wǎng) 0x1 題目描述 0x2 問題分

    2024年02月08日
    瀏覽(29)
  • Python基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)入門必讀指南

    Python基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)入門必讀指南

    作者主頁:濤哥聊Python 個人網(wǎng)站:濤哥聊Python 大家好,我是濤哥,今天為大家分享的是Python中常見的數(shù)據(jù)結(jié)構(gòu)。 含義:數(shù)組是一種有序的數(shù)據(jù)結(jié)構(gòu),其中的元素可以按照索引來訪問。數(shù)組的大小通常是固定的,一旦創(chuàng)建就不能更改。 基本操作: 含義:列表是Python中內(nèi)置的

    2024年02月07日
    瀏覽(52)
  • 數(shù)據(jù)結(jié)構(gòu)入門指南:帶頭雙向循環(huán)鏈表

    數(shù)據(jù)結(jié)構(gòu)入門指南:帶頭雙向循環(huán)鏈表

    目錄 文章目錄 前言 1.結(jié)構(gòu)與優(yōu)勢 2.鏈表實現(xiàn)? ? ?? 2.1 定義鏈表 2.2 創(chuàng)建頭節(jié)點 2.3 尾插 2.4 輸出鏈表 2.5 尾刪 2.6 頭插 2.7頭刪 2.8?節(jié)點個數(shù) 2.9?查找 2.10?位置插入 2.11 位置刪除 2.12 銷毀鏈表 ?3. 源碼 總結(jié) ? ? ? ? 鏈表一共有8種結(jié)構(gòu),但最常用的就是無頭單向鏈表、和帶頭

    2024年02月14日
    瀏覽(24)
  • 【數(shù)據(jù)結(jié)構(gòu)入門指南】二叉樹順序結(jié)構(gòu): 堆及實現(xiàn)(全程配圖,非常經(jīng)典)

    【數(shù)據(jù)結(jié)構(gòu)入門指南】二叉樹順序結(jié)構(gòu): 堆及實現(xiàn)(全程配圖,非常經(jīng)典)

    普通的二叉樹是不適合用數(shù)組來存儲的,因為可能會存在大量的空間浪費。 而完全二叉樹更適合使用順序結(jié)構(gòu)存儲。 ? 現(xiàn)實中我們通常把堆(一種二叉樹)使用順序結(jié)構(gòu)的數(shù)組來存儲 ,需要注意的是這里的堆和操作系統(tǒng)虛擬進程地址空間中的堆是兩回事,一個是數(shù)據(jù)結(jié)構(gòu),一

    2024年02月12日
    瀏覽(25)
  • 【數(shù)據(jù)結(jié)構(gòu)入門指南】二叉樹鏈式結(jié)構(gòu)的實現(xiàn)(保姆級代碼思路解讀,非常經(jīng)典)

    【數(shù)據(jù)結(jié)構(gòu)入門指南】二叉樹鏈式結(jié)構(gòu)的實現(xiàn)(保姆級代碼思路解讀,非常經(jīng)典)

    其他數(shù)據(jù)結(jié)構(gòu)不同,二叉樹的增刪查改接口實現(xiàn)的意義不大(后續(xù)搜索樹的增刪查改才有意義)。普通初階二叉樹更重要的是學(xué)習(xí)控制結(jié)構(gòu),為后續(xù)的AVL樹、紅黑樹等高級數(shù)據(jù)結(jié)構(gòu)打下基礎(chǔ)。同時大部分OJ題也出在此處。 所謂二叉樹遍歷(Traversal)是按照某種特定的規(guī)則,依次

    2024年02月11日
    瀏覽(26)
  • 【Java--數(shù)據(jù)結(jié)構(gòu)】提升你的編程段位:泛型入門指南,一看就會!

    【Java--數(shù)據(jù)結(jié)構(gòu)】提升你的編程段位:泛型入門指南,一看就會!

    泛型是一種編程概念,它允許我們編寫可以適用于多種數(shù)據(jù)類型的代碼。通過使用泛型,我們可以在編譯時期將具體的 數(shù)據(jù)類型作為參數(shù) 傳遞給代碼,從而實現(xiàn)代碼 的復(fù)用和靈活性 。 在傳統(tǒng)的編程中,我們通常需要為不同的數(shù)據(jù)類型編寫不同的代碼,這樣會導(dǎo)致代碼冗余

    2024年04月26日
    瀏覽(35)
  • 探索數(shù)據(jù)結(jié)構(gòu):單鏈表的實戰(zhàn)指南

    探索數(shù)據(jù)結(jié)構(gòu):單鏈表的實戰(zhàn)指南

    ?? 歡迎大家來到貝蒂大講堂?? ????養(yǎng)成好習(xí)慣,先贊后看哦~???? 所屬專欄:數(shù)據(jù)結(jié)構(gòu)與算法 貝蒂的主頁:Betty‘s blog 在上一章節(jié)中我們講解了數(shù)據(jù)結(jié)構(gòu)中的順序表,知道了順序表的空間是連續(xù)存儲的,這與數(shù)組非常類似,為我們隨機訪問數(shù)據(jù)提供了便利的條件。但

    2024年03月09日
    瀏覽(27)
  • 數(shù)據(jù)結(jié)構(gòu)入門——單鏈表

    目錄 前言 鏈表的定義 鏈表的創(chuàng)建 頭插法創(chuàng)建鏈表 尾插法創(chuàng)建鏈表 鏈表的刪除 在頭部刪除元素 在尾部刪除元素 查找固定元素 在鏈表中插入元素 在pos位置前插入 在pos位置后插入 刪除鏈表結(jié)點 刪除pos位置的結(jié)點 刪除pos后的結(jié)點 鏈表的銷毀 寫在最后 前面我們學(xué)習(xí)了順序表

    2024年02月20日
    瀏覽(20)
  • 數(shù)據(jù)結(jié)構(gòu)入門 — 鏈表詳解_單鏈表

    數(shù)據(jù)結(jié)構(gòu)入門 — 鏈表詳解_單鏈表

    數(shù)據(jù)結(jié)構(gòu)入門 — 單鏈表詳解 * 博客主頁鏈接:https://blog.csdn.net/m0_74014525 關(guān)注博主,后期持續(xù)更新系列文章 文章末尾有源碼 *****感謝觀看,希望對你有所幫助***** 第一篇:數(shù)據(jù)結(jié)構(gòu)入門 — 鏈表詳解_單鏈表 第二篇:數(shù)據(jù)結(jié)構(gòu)入門 — 鏈表詳解_雙向鏈表 第三篇:數(shù)據(jù)結(jié)構(gòu)入門

    2024年02月11日
    瀏覽(84)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包