欧美free性护士vide0shd,老熟女,一区二区三区,久久久久夜夜夜精品国产,久久久久久综合网天天,欧美成人护士h版

目錄

柚子快報(bào)邀請(qǐng)碼778899分享:數(shù)據(jù)結(jié)構(gòu) 帶頭雙向循環(huán)鏈表

柚子快報(bào)邀請(qǐng)碼778899分享:數(shù)據(jù)結(jié)構(gòu) 帶頭雙向循環(huán)鏈表

http://yzkb.51969.com/

文章目錄

帶頭雙向循環(huán)鏈表定義雙向鏈表的功能雙向鏈表的功能實(shí)現(xiàn)初始化代碼實(shí)現(xiàn)

創(chuàng)建新節(jié)點(diǎn)打印鏈表代碼實(shí)現(xiàn)

頭插代碼實(shí)現(xiàn)

尾插代碼實(shí)現(xiàn)

頭刪代碼實(shí)現(xiàn)

尾刪代碼實(shí)現(xiàn)

銷毀鏈表代碼實(shí)現(xiàn)

查找下標(biāo)代碼實(shí)現(xiàn)

在任意位置之前插入數(shù)據(jù)代碼實(shí)現(xiàn)

刪除任意位置的數(shù)據(jù)代碼實(shí)現(xiàn)

源碼List.hList.ctest.c

前言:當(dāng)我們想要挪動(dòng)大量數(shù)據(jù)的時(shí)候,單鏈表的效率就很低了,比如尾插,要找到尾,通過遍歷的時(shí)間復(fù)雜度最壞情況是O(N),所以我們引進(jìn)結(jié)構(gòu)復(fù)雜但效率高的雙向帶頭循環(huán)鏈表

帶頭雙向循環(huán)鏈表

帶頭雙向循環(huán)鏈表指得是什么呢?就是既存儲(chǔ)了上一個(gè)節(jié)點(diǎn)的地址,又存儲(chǔ)了下一個(gè)節(jié)點(diǎn)的地址,帶有哨兵位,加上哨兵位的頭指向了鏈表的尾,鏈表的尾的下一個(gè)指向了哨兵位的頭

定義

和單鏈表一樣,有指針域和數(shù)據(jù)域,不過比單鏈表多了一個(gè)存儲(chǔ)上一個(gè)節(jié)點(diǎn)的指針

typedef struct ListNode

{

LTDataType data;

struct ListNode* next;

struct ListNode* prev;

}ListNode;

雙向鏈表的功能

和單鏈表大差不差

頭插 尾插 頭刪 尾刪 找到某個(gè)位置的下標(biāo) 在任意位置插入 刪除任意位置的數(shù)據(jù) 銷毀鏈表

標(biāo)明:我們先實(shí)現(xiàn)每個(gè)函數(shù)的接口,插入和刪除用這兩個(gè)函數(shù)(在任意位置插入 ,刪除任意位置的數(shù)據(jù))復(fù)用效率會(huì)快好多

雙向鏈表的功能實(shí)現(xiàn)

初始化

初始化需要傳二級(jí)指針,因?yàn)槌跏蓟枰淖兘Y(jié)構(gòu)體指針,也就是要對(duì)頭進(jìn)行初始化,讓頭指向自己,如果傳一級(jí),就相當(dāng)于傳值調(diào)用,形參的改變并不會(huì)影響實(shí)參,而后面的函數(shù)接口都不用二級(jí),因?yàn)楦淖兊氖墙Y(jié)構(gòu)體,也就是“箭頭”的指向 注:你可以返回結(jié)構(gòu)體指針,也可以傳二級(jí)指針,我們這里采用的是返回結(jié)構(gòu)體指針

代碼實(shí)現(xiàn)

ListNode* ListInit()

{

ListNode* phead = (ListNode*)malloc(sizeof(ListNode));

phead->prev = phead;

phead->next = phead;

return phead;

}

創(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;

}

打印鏈表

代碼實(shí)現(xiàn)

void ListPrint(ListNode* phead)

{

assert(phead);

ListNode* cur = phead->next;

while (cur != phead)

{

printf("%d ", cur->data);

cur = cur->next;

}

printf("\n");

}

頭插

首先創(chuàng)建個(gè)哨兵,也就是新節(jié)點(diǎn),一定要先斷言鏈表不為空哦

代碼實(shí)現(xiàn)

void ListPushFront(ListNode* phead, LTDataType x)

{

assert(phead);

ListNode* newNode = BuyListNode(x);

ListNode* next = phead->next;

phead->next = newNode;

newNode->prev = phead;

newNode->next = next;

next->prev = newNode;

}

尾插

先定義一個(gè)尾指針,使代碼清晰易懂,不用像單鏈表一樣考慮一個(gè)節(jié)點(diǎn),兩個(gè)節(jié)點(diǎn),多個(gè)節(jié)點(diǎn)的問題

代碼實(shí)現(xiàn)

void ListPushBack(ListNode* phead, LTDataType x)

{

assert(phead);

ListNode* newNode = BuyListNode(x);

ListNode* tail = phead->prev;

newNode->prev = tail;

tail->next = newNode;

newNode->next = phead;

phead->prev = newNode;

//ListInsert(phead, x);

}

頭刪

當(dāng)刪到只剩哨兵位的話就不能刪了

代碼實(shí)現(xiàn)

void ListPopFront(ListNode* phead)

{

assert(phead);

assert(phead->next != phead);

ListNode* next = phead->next;

phead->next = next->next;

next->next->prev = phead;

ListNode* nextNext = next->next;

phead->next = nextNext;

nextNext->prev = phead;

free(next);

//ListErase(phead->next);

}

尾刪

刪到最后只剩哨兵位,就不要?jiǎng)h了,鏈表為空,再去解引用就會(huì)報(bào)錯(cuò)

代碼實(shí)現(xiàn)

void ListPopBack(ListNode* phead)

{

assert(phead);

assert(phead->next != phead);

ListNode* tail = phead->prev;

ListNode* tailprev = tail->prev;

free(tail);

phead->prev = tailprev;

tailprev->next = phead;

//ListErase(phead->prev);

}

銷毀鏈表

循環(huán)結(jié)束的條件是當(dāng)遍歷到等于哨兵位時(shí),說明已經(jīng)銷毀完數(shù)據(jù)了,再把哨兵位free掉就好

代碼實(shí)現(xiàn)

void ListDestroy(ListNode* phead)

{

assert(phead);

ListNode* cur = phead->next;

while (cur->next != phead)

{

ListNode* next = cur->next;

free(cur);

cur = next;

}

free(phead);

phead = NULL;

}

查找下標(biāo)

代碼實(shí)現(xiàn)

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;

}

在任意位置之前插入數(shù)據(jù)

代碼實(shí)現(xiàn)

void ListInsert(ListNode* pos, LTDataType x)

{

assert(pos);

ListNode* newNode = BuyListNode(x);

ListNode* posPrev = pos->prev;

posPrev->next = newNode;

newNode->prev = posPrev;

newNode->next = pos;

pos->prev = newNode;

}

刪除任意位置的數(shù)據(jù)

代碼實(shí)現(xiàn)

void ListErase(ListNode* pos)

{

assert(pos);

ListNode* posPre = pos->prev;

ListNode* posNext = pos->next;

posPre->next = posNext;

posNext->prev = posPre;

free(pos);

pos = NULL;

}

源碼

List.h

#pragma once

#include

#include

#include

typedef int LTDataType;

typedef struct ListNode

{

LTDataType data;

struct ListNode* next;

struct ListNode* prev;

}ListNode;

ListNode* ListInit();

void ListPushBack(ListNode* phead, LTDataType x);

void ListPrint(ListNode* phead);

void ListPopBack(ListNode* phead);

void ListPopFront(ListNode* phead);

void ListPushFront(ListNode* phead,LTDataType x);

ListNode* ListFind(ListNode* phead, LTDataType x);

void ListInsert(ListNode* pos, LTDataType x);

void ListErase(ListNode* pos);

void ListDestroy(ListNode* phead);

List.c

#define _CRT_SECURE_NO_WARNINGS

#include"List.h"

ListNode* ListInit()

{

ListNode* phead = (ListNode*)malloc(sizeof(ListNode));

phead->prev = phead;

phead->next = phead;

return phead;

}

ListNode* BuyListNode(LTDataType x)

{

ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));

newNode->data = x;

newNode->next = NULL;

newNode->prev = NULL;

return newNode;

}

void ListPushBack(ListNode* phead, LTDataType x)

{

assert(phead);

ListNode* newNode = BuyListNode(x);

ListNode* tail = phead->prev;

newNode->prev = tail;

tail->next = newNode;

newNode->next = phead;

phead->prev = newNode;

也處理了空鏈表的問題,不用像單鏈表一樣考慮一個(gè)節(jié)點(diǎn),兩個(gè)節(jié)點(diǎn),多個(gè)節(jié)點(diǎn)的問題

//ListInsert(phead, x);

}

void ListPrint(ListNode* phead)

{

assert(phead);

ListNode* cur = phead->next;

while (cur != phead)

{

printf("%d ", cur->data);

cur = cur->next;

}

printf("\n");

}

void ListPopBack(ListNode* phead)

{

assert(phead);

assert(phead->next != phead);//刪到最后只剩哨兵位,就不要?jiǎng)h了,鏈表為空,再去解引用就會(huì)報(bào)錯(cuò)

/*ListNode* tail = phead->prev;

ListNode* tailprev = tail->prev;

free(tail);

phead->prev = tailprev;

tailprev->next = phead;*/

ListErase(phead->prev);

}

void ListPushFront(ListNode* phead, LTDataType x)

{

assert(phead);

ListNode* newNode = BuyListNode(x);

ListNode* next = phead->next;

phead->next = newNode;

newNode->prev = phead;

newNode->next = next;

next->prev = newNode;

//ListInsert(phead->next, x);

}

void ListPopFront(ListNode* phead)

{

assert(phead);

assert(phead->next != phead);

ListNode* next = phead->next;

phead->next = next->next;

next->next->prev = phead;

ListNode* nextNext = next->next;

phead->next = nextNext;

nextNext->prev = phead;

free(next);

//ListErase(phead->next);

}

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;

}

//在pos位置之前插入

void ListInsert(ListNode* pos, LTDataType x)

{

assert(pos);

ListNode* newNode = BuyListNode(x);

ListNode* posPrev = pos->prev;

posPrev->next = newNode;

newNode->prev = posPrev;

newNode->next = pos;

pos->prev = newNode;

}

void ListErase(ListNode* pos)

{

assert(pos);

ListNode* posPre = pos->prev;

ListNode* posNext = pos->next;

posPre->next = posNext;

posNext->prev = posPre;

free(pos);

pos = NULL;

}

void ListDestroy(ListNode* phead)

{

assert(phead);

ListNode* cur = phead->next;

while (cur->next != phead)

{

ListNode* next = cur->next;

free(cur);

cur = next;

}

free(phead);

phead = NULL;

}

test.c

#define _CRT_SECURE_NO_WARNINGS

#include"List.h"

void test2()

{

ListNode* plist = ListInit();

//尾插

ListPushBack(plist, 1);

ListPushBack(plist, 2);

ListPushBack(plist, 3);

ListPushBack(plist, 4);

ListPrint(plist);

//頭插

ListPushFront(plist, 10);

ListPushFront(plist, 18);

ListPushFront(plist, 17);

ListPushFront(plist, 16);

ListPushFront(plist, 15);

ListPrint(plist);

/*

//在pos位置前插入

ListNode* pos1 = ListFind(plist, 3);

if(pos1)

{

ListInsert(pos1,30);

}

ListPrint(plist);

*/

/* //刪除pos位置的數(shù)據(jù)

ListNode* pos = ListFind(plist, 2);

if(pos)

{

ListErase(pos);

}

ListPrint(plist);

*/

頭刪

//ListPopFront(plist);

//ListPopFront(plist);

//ListPrint(plist);

尾刪

//ListPopBack(plist);

//ListPrint(plist);

//ListPopBack(plist);

//ListPrint(plist);

//銷毀

ListDestroy(plist);

plist = NULL;

}

int main()

{

//test1();

test2();

return 0;

}

柚子快報(bào)邀請(qǐng)碼778899分享:數(shù)據(jù)結(jié)構(gòu) 帶頭雙向循環(huán)鏈表

http://yzkb.51969.com/

參考文章

評(píng)論可見,查看隱藏內(nèi)容

本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場(chǎng)。

轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。

本文鏈接:http://gantiao.com.cn/post/18840347.html

發(fā)布評(píng)論

您暫未設(shè)置收款碼

請(qǐng)?jiān)谥黝}配置——文章設(shè)置里上傳

掃描二維碼手機(jī)訪問

文章目錄