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

數(shù)據(jù)結(jié)構(gòu)---雙向鏈表

這篇具有很好參考價(jià)值的文章主要介紹了數(shù)據(jù)結(jié)構(gòu)---雙向鏈表。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。


前言

1.概念

單向鏈表:一塊內(nèi)存指向下一個(gè)內(nèi)存。
單鏈表存在一些缺陷:
1.查找速度慢。
2.不能從后往前找。
3.找不到前驅(qū)。
鏈表的結(jié)構(gòu)分為8種:
1.單向和雙向
2.帶頭和不帶頭
帶頭的鏈表有一個(gè)帶哨兵位的頭結(jié)點(diǎn),這個(gè)節(jié)點(diǎn)不存儲(chǔ)有效數(shù)據(jù)。
好處:尾插更方便,不需要二級(jí)指針了,帶頭結(jié)點(diǎn)不需要改變傳過來的指針,,也就意味著不需要傳二級(jí)指針
3.循環(huán)和不循環(huán)
不循環(huán):尾是指向空的
循環(huán):尾是指針頭的
一、無頭單向肺循環(huán)鏈表:結(jié)構(gòu)簡(jiǎn)單,一般不會(huì)單獨(dú)用來存數(shù)據(jù)。實(shí)際中更多是作為其他數(shù)據(jù)結(jié)構(gòu)的子結(jié)構(gòu),如哈希桶、圖的領(lǐng)接表等等。
另外這種結(jié)構(gòu)在筆試面試中出現(xiàn)很多。
二、帶頭雙向循環(huán)鏈表:結(jié)構(gòu)復(fù)雜,一般用在單獨(dú)存儲(chǔ)數(shù)據(jù)。實(shí)際中使用的鏈表數(shù)據(jù)結(jié)構(gòu),都是帶頭雙向循環(huán)鏈表,另外這個(gè)結(jié)構(gòu)雖然結(jié)構(gòu)復(fù)雜,
但是使用代碼實(shí)現(xiàn)以后會(huì)發(fā)現(xiàn)帶來很多優(yōu)勢(shì),實(shí)現(xiàn)反而簡(jiǎn)單了。

2.初始化

typedef struct ListNode
{
	struct ListNode* next;
	struct ListNode* prev;
	LTDataType data;
}ListNode;

next表示指向下一個(gè)節(jié)點(diǎn)
prev表示前驅(qū)指針,指向上一個(gè)節(jié)點(diǎn)


一、雙向鏈表的應(yīng)用

1.打印鏈表和創(chuàng)建新的節(jié)點(diǎn)

//創(chuàng)建新的節(jié)點(diǎn)
ListNode* BuyListNode(LTDataType x)
{
	ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));
	newnode->data = x;
	newnode->next = NULL;
	newnode->prev = NULL;
	return newnode;
}

//打印鏈表
void ListPrint(ListNode* phead)
{
	ListNode* cur = phead->next;
	while (cur!= phead)
	{
		printf("%d ", cur->data);
		cur = cur->next;
	}
	printf("\n");
}

2.鏈表的初始化和銷毀

//初始化
ListNode* ListInit()
{
	ListNode* phead = BuyListNode(0);
	phead->next = phead;
	phead->prev = phead;
	return phead;
}
//銷毀
void ListDestory(ListNode* phead)
{
	assert(phead);
	ListNode* cur = phead->next;
	while (cur != phead)
	{
		ListNode* next = cur->next;
		free(cur);
		cur = next;
	}
	free(phead);
	phead = NULL;
}

3.鏈表的首插和尾插

//尾插
void ListPushBack(ListNode* phead, LTDataType x)
{
	assert(phead);
	ListNode* tail = phead->prev;
	ListNode* newnode = BuyListNode(x);
	tail->next = newnode;
	newnode->prev = tail;
	newnode->next = phead;
	phead->prev = newnode;
}
//上面的尾插針對(duì)空鏈表也是成立的,可以畫個(gè)圖理解一下
//雙向帶頭循環(huán)鏈表結(jié)構(gòu)雖然復(fù)雜了,但是操作反而簡(jiǎn)單了。
//結(jié)構(gòu)設(shè)計(jì)的優(yōu)勢(shì)
//內(nèi)存占用增加,每個(gè)節(jié)點(diǎn)多了一個(gè)前驅(qū)指針
//STL中的List原碼就是這個(gè)結(jié)構(gòu)

//頭插
void ListPushfront(ListNode* phead, LTDataType x)
{
	assert(phead);
	ListNode* newnode = BuyListNode(x);
	ListNode* first = phead->next;
	phead->next = newnode;
	newnode->prev = phead;
	newnode->next = first;
	first->prev = newnode;
}

4.鏈表的尾刪和頭刪

//尾刪
void ListPopBack(ListNode* phead)
{
	assert(phead);
	assert(phead->next != phead);
	ListNode* tail = phead->prev;
	ListNode* last = tail->prev;
	free(tail);
	last->next = phead;
	phead->prev = last;
	tail = NULL;
}

//頭刪
void ListPopFront(ListNode* phead)
{
	assert(phead);
	assert(phead->next != phead);
	ListNode* first = phead->next;
	ListNode* second = first->next;
	free(first);
	phead->next = second;
	second->prev = phead;
	first = NULL;
}

5.鏈表的查找和指定位置的插入刪除

//查找
ListNode* ListFind(ListNode* phead, LTDataType x)
{
	assert(phead);
	ListNode* cur = phead->next;
	while (cur!=phead)
	{
		if (cur->data == x)
		{
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
}

//插入
void ListInsert(ListNode* phead, ListNode* pos, LTDataType x)
{
	assert(pos);
	ListNode* last = pos->prev;
	ListNode* newnode = BuyListNode(x);
	last->next = newnode;
	newnode->prev = last;
	newnode->next = pos;
	pos->prev = newnode;
}

//刪除pos位置的數(shù)
void ListErase(ListNode* plist, ListNode* pos)
{
	assert(pos);
	ListNode* last = pos->prev;
	ListNode* following = pos->next;
	free(pos);
	last->next = following;
	following->prev = last;
	pos = NULL;
}

二、封裝文件

注:以上函數(shù)封裝在List.c中

1. List.h文件

#pragma once
//雙向鏈表定義
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int LTDataType;
typedef struct ListNode
{
	struct ListNode* next;
	struct ListNode* prev;
	LTDataType data;
}ListNode;


ListNode* ListInit();
void ListPrint(ListNode* plist);
void ListDestory(ListNode* plist);
void ListPushBack(ListNode* plist, LTDataType x);
void ListPushfront(ListNode* plist, LTDataType x);
void ListPopBack(ListNode* plist);
void ListPopFront(ListNode* plist);
ListNode* ListFind(ListNode* plist, LTDataType x);
//在pos位置之前插入一個(gè)值
void ListInsert(ListNode* plist, ListNode* pos, LTDataType x);
//刪除pos位置的值
void ListErase(ListNode* plist, ListNode* pos);

2.測(cè)試函數(shù)

#include "List.h"

void TestList1()
{
	ListNode* plist = ListInit();

	ListPushBack(plist, 1);
	ListPushBack(plist, 2);
	ListPushBack(plist, 3);
	ListPushBack(plist, 4);

	ListPrint(plist);
	ListDestory(plist);
}
void TestList2()
{
	ListNode* plist = ListInit();

	ListPushfront(plist, 1);
	ListPushfront(plist, 2);
	ListPushfront(plist, 3);
	ListPushfront(plist, 4);

	ListPrint(plist);
	ListDestory(plist);
}
void TestList3()
{
	ListNode* plist = ListInit();

	ListPushfront(plist, 1);
	ListPushfront(plist, 2);
	ListPushfront(plist, 3);
	ListPushfront(plist, 4);

	ListPrint(plist);
	printf("\n");
	ListPopBack(plist);
	ListPrint(plist);
	ListDestory(plist);
}

void TestList4()
{
	ListNode* plist = ListInit();

	ListPushfront(plist, 1);
	ListPushfront(plist, 2);
	ListPushfront(plist, 3);
	ListPushfront(plist, 4);

	ListPrint(plist);
	printf("\n");
	ListPopFront(plist);
	ListPrint(plist);
	ListDestory(plist);
}

void TestList5()
{
	ListNode* plist = ListInit();

	ListPushfront(plist, 1);
	ListPushfront(plist, 2);
	ListPushfront(plist, 3);
	ListPushfront(plist, 4);
	ListPrint(plist);
	ListNode* pos = ListFind(plist, 3);
	if (pos)
	{
		//查找同時(shí)可以附帶修改
		printf("找到了");
		pos->data = pos->data * 10;
	}
	else
	{
		printf("沒有找到");
	}
}
void TestList6()
{
	ListNode* plist = ListInit();

	ListPushfront(plist, 1);
	ListPushfront(plist, 2);
	ListPushfront(plist, 3);
	ListPushfront(plist, 4);
	ListPrint(plist);
	printf("\n");
	ListNode* pos = ListFind(plist, 3);
	if (pos)
	{
		ListInsert(plist, pos, 100);
		ListErase(plist, pos->prev);
	}
	ListPrint(plist);
}
int main()
{
	TestList6();
	return 0;
}

用以上函數(shù)進(jìn)行測(cè)試


總結(jié)

雖然雙向鏈表結(jié)構(gòu)付咱,但是理解其結(jié)構(gòu)可發(fā)現(xiàn)各個(gè)接口比單向鏈表的接口寫起來更加簡(jiǎn)單,更加容易上手文章來源地址http://www.zghlxwxcb.cn/news/detail-783662.html

到了這里,關(guān)于數(shù)據(jù)結(jié)構(gòu)---雙向鏈表的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

  • 【數(shù)據(jù)結(jié)構(gòu)】—C語言實(shí)現(xiàn)雙向鏈表(超詳細(xì)!)

    【數(shù)據(jù)結(jié)構(gòu)】—C語言實(shí)現(xiàn)雙向鏈表(超詳細(xì)!)

    ??????????????????????????????? ??? ? 食用指南:本文在有C基礎(chǔ)的情況下食用更佳 ? ????????????????????????????? ??? ? ?? 這就不得不推薦此專欄了:C語言 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? 雙向鏈表 前 置知識(shí) :?jiǎn)捂湵?? ? ?

    2024年02月13日
    瀏覽(23)
  • 【數(shù)據(jù)結(jié)構(gòu)】C語言實(shí)現(xiàn)雙向鏈表(帶頭結(jié)點(diǎn)、循環(huán))

    【數(shù)據(jù)結(jié)構(gòu)】C語言實(shí)現(xiàn)雙向鏈表(帶頭結(jié)點(diǎn)、循環(huán))

    結(jié)點(diǎn)定義: 接口定義: 我們將申請(qǐng)結(jié)點(diǎn)的代碼封裝成函數(shù),方便后續(xù)使用 由于是帶頭結(jié)點(diǎn)的雙向鏈表,因此在使用鏈表前,我們需要對(duì)鏈表進(jìn)行初始化。 遍歷鏈表,值得說的是,帶頭結(jié)點(diǎn)的雙向鏈表的循環(huán)結(jié)束條件是 cur != phead 尾插時(shí),需要先找到尾結(jié)點(diǎn),然后將新結(jié)點(diǎn)插

    2024年02月03日
    瀏覽(96)
  • 【數(shù)據(jù)結(jié)構(gòu)初階】四、線性表里的鏈表(帶頭+雙向+循環(huán) 鏈表 -- C語言實(shí)現(xiàn))

    【數(shù)據(jù)結(jié)構(gòu)初階】四、線性表里的鏈表(帶頭+雙向+循環(huán) 鏈表 -- C語言實(shí)現(xiàn))

    ========================================================================= 相關(guān)代碼gitee自取 : C語言學(xué)習(xí)日記: 加油努力 (gitee.com) ?========================================================================= 接上期 : 【數(shù)據(jù)結(jié)構(gòu)初階】三、 線性表里的鏈表(無頭+單向+非循環(huán)鏈表 -- C語言實(shí)現(xiàn))-CSDN博客 ?====

    2024年02月08日
    瀏覽(30)
  • 『初階數(shù)據(jù)結(jié)構(gòu) ? C語言』⑨ - 基于結(jié)點(diǎn)的數(shù)據(jù)結(jié)構(gòu)——鏈表(單鏈表&&雙向循環(huán)鏈表)附完整源碼

    『初階數(shù)據(jù)結(jié)構(gòu) ? C語言』⑨ - 基于結(jié)點(diǎn)的數(shù)據(jù)結(jié)構(gòu)——鏈表(單鏈表&&雙向循環(huán)鏈表)附完整源碼

    ? 本章內(nèi)容 1.什么是鏈表 2.鏈表常見幾種形式 3.無頭單向非循環(huán)鏈表的實(shí)現(xiàn) 3.1結(jié)點(diǎn)結(jié)構(gòu)的定義 3.2函數(shù)接口的實(shí)現(xiàn) 3.2.1尾插 3.2.2尾刪 4. 帶頭雙向循環(huán)鏈表的實(shí)現(xiàn) 4.1結(jié)點(diǎn)結(jié)構(gòu)的定義 4.2函數(shù)接口的實(shí)現(xiàn) 5.兩種鏈表的差異 ①尾插與尾刪的時(shí)間復(fù)雜度 ②頭插與頭刪的時(shí)間復(fù)雜度 ③

    2024年02月16日
    瀏覽(95)
  • 鏈接未來:深入理解鏈表數(shù)據(jù)結(jié)構(gòu)(二.c語言實(shí)現(xiàn)帶頭雙向循環(huán)鏈表)

    鏈接未來:深入理解鏈表數(shù)據(jù)結(jié)構(gòu)(二.c語言實(shí)現(xiàn)帶頭雙向循環(huán)鏈表)

    上篇文章簡(jiǎn)述講解了鏈表的基本概念并且實(shí)現(xiàn)了無頭單向不循環(huán)鏈表:鏈接未來:深入理解鏈表數(shù)據(jù)結(jié)構(gòu)(一.c語言實(shí)現(xiàn)無頭單向非循環(huán)鏈表)-CSDN博客 那今天接著給大家?guī)韼ь^雙向循環(huán)鏈表的實(shí)現(xiàn) : 頭文件DoubleList.h:用來基礎(chǔ)準(zhǔn)備(常量定義,typedef),鏈表表的基本框架

    2024年01月16日
    瀏覽(58)
  • 數(shù)據(jù)結(jié)構(gòu)_鏈表_雙向循環(huán)鏈表的初始化、插入、刪除、修改、查詢打?。ɑ贑語言實(shí)現(xiàn))

    數(shù)據(jù)結(jié)構(gòu)_鏈表_雙向循環(huán)鏈表的初始化、插入、刪除、修改、查詢打?。ɑ贑語言實(shí)現(xiàn))

    版本: 2024年4月26日 V1.0 發(fā)布于博客園 目錄 目錄 雙向循環(huán)鏈表公式 初始化雙向循環(huán)鏈表 構(gòu)建雙向循環(huán)鏈表結(jié)點(diǎn) 創(chuàng)建一個(gè)空鏈表(僅頭結(jié)點(diǎn)) 創(chuàng)建一個(gè)新結(jié)點(diǎn) 插入數(shù)據(jù) 頭插 中插 尾插 刪除數(shù)據(jù) 頭刪 中刪 尾刪 查詢打印數(shù)據(jù) 遍歷打印 測(cè)試 測(cè)試結(jié)果: 完整代碼 DoubleCirLList.h

    2024年04月27日
    瀏覽(36)
  • 數(shù)據(jù)結(jié)構(gòu)-鏈表結(jié)構(gòu)-雙向鏈表

    數(shù)據(jù)結(jié)構(gòu)-鏈表結(jié)構(gòu)-雙向鏈表

    雙向鏈表也叫雙鏈表,與單向鏈表不同的是,每一個(gè)節(jié)點(diǎn)有三個(gè)區(qū)域組成:兩個(gè)指針域,一個(gè)數(shù)據(jù)域 前一個(gè)指針域:存儲(chǔ)前驅(qū)節(jié)點(diǎn)的內(nèi)存地址 后一個(gè)指針域:存儲(chǔ)后繼節(jié)點(diǎn)的內(nèi)存地址 數(shù)據(jù)域:存儲(chǔ)節(jié)點(diǎn)數(shù)據(jù) 以下就是雙向鏈表的最基本單位 節(jié)點(diǎn)的前指針域指向前驅(qū),后指針

    2024年02月04日
    瀏覽(31)
  • 【數(shù)據(jù)結(jié)構(gòu)】雙向奔赴的愛戀 --- 雙向鏈表

    【數(shù)據(jù)結(jié)構(gòu)】雙向奔赴的愛戀 --- 雙向鏈表

    關(guān)注小莊 頓頓解饞????? 引言:上回我們講解了單鏈表(單向不循環(huán)不帶頭鏈表),我們可以發(fā)現(xiàn)他是存在一定缺陷的,比如尾刪的時(shí)候需要遍歷一遍鏈表,這會(huì)大大降低我們的性能,再比如對(duì)于鏈表中的一個(gè)結(jié)點(diǎn)我們是無法直接訪問它的上一個(gè)結(jié)點(diǎn),那有什么解決方法呢

    2024年04月08日
    瀏覽(27)
  • 數(shù)據(jù)結(jié)構(gòu)—雙向鏈表

    數(shù)據(jù)結(jié)構(gòu)—雙向鏈表

    目錄 1.? 鏈表的種類 2.? 最實(shí)用的兩種鏈表類型 3.? 實(shí)現(xiàn)雙向帶頭循環(huán)鏈表 ? ? ? ? ? ? ? ? ? 3.1 創(chuàng)建頭節(jié)點(diǎn) ????????3.2 實(shí)現(xiàn)雙向循環(huán)功能—返回頭指針 ????????3.3? 尾插?? ????????3.4 頭插 ????????3.5 尾刪 ????????3.6 頭刪 4.? 實(shí)現(xiàn)兩個(gè)重要接口函數(shù) ?

    2023年04月23日
    瀏覽(28)
  • 數(shù)據(jù)結(jié)構(gòu) - 雙向鏈表

    數(shù)據(jù)結(jié)構(gòu) - 雙向鏈表

    文章目錄 目錄 文章目錄 前言 一、什么是雙向鏈表? 雙向鏈表有什么優(yōu)勢(shì)? 二、雙向鏈表的設(shè)計(jì)和實(shí)現(xiàn) 1.設(shè)計(jì)思想 尾增 : 在鏈表的末尾添加新的元素 ?頭插 : 在鏈表頭部插入節(jié)點(diǎn) ?刪除 : 根據(jù)val的值刪除節(jié)點(diǎn) ?查找 : 根據(jù)索引的值查找并返回節(jié)點(diǎn) 總結(jié) 大家好,今天給大家講解

    2024年02月09日
    瀏覽(27)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包