最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C語言實現(xiàn)帶頭雙向環(huán)形鏈表

 更新時間:2021年11月26日 17:29:07   作者:aiyubaobei  
這篇文章主要為大家詳細介紹了C語言實現(xiàn)帶頭雙向環(huán)形鏈表,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

雙向循環(huán)鏈表

上一次我們講了單向無頭非循環(huán)鏈表的實現(xiàn),單向無頭非循環(huán)鏈表的特點是:結(jié)構(gòu)簡單,一般不會單獨用來存數(shù)據(jù)。實際中更多是作為其他數(shù)據(jù)結(jié)構(gòu)的子結(jié)構(gòu)。而帶頭雙向循環(huán)鏈表則恰恰與無頭單向非循環(huán)鏈表相反,它的結(jié)構(gòu)最復(fù)雜,一般用來單獨存儲數(shù)據(jù)。這個結(jié)構(gòu)雖然復(fù)雜,但是使用單嗎實現(xiàn)后會發(fā)現(xiàn),這個結(jié)構(gòu)用起來很簡單。

結(jié)構(gòu)示意圖

帶頭雙向循環(huán)鏈表在邏輯上大概就是這樣的一個樣子,鏈表的最后一個節(jié)點的后繼指向的是頭結(jié)點。而頭結(jié)點的前驅(qū)則是指向鏈表的最后一個結(jié)點。所以,一個空的帶頭雙向循環(huán)鏈表的邏輯結(jié)構(gòu)應(yīng)該是這樣的:

它的前驅(qū)和后繼都是指向的頭結(jié)點。

實現(xiàn)帶頭雙向循環(huán)鏈表

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int LTDataType;
// 定義鏈表的節(jié)點
typedef struct ListNode {
 LTDataType data;
 struct ListNode* prev;
 struct ListNode* next;
}LTNode;

// 創(chuàng)建返回鏈表的頭結(jié)點.
LTNode* ListCreate();
// 雙向鏈表銷毀
void ListDestory(LTNode* pHead);
// 雙向鏈表打印
void ListPrint(LTNode* pHead);
// 雙向鏈表尾插
void ListPushBack(LTNode* pHead, LTDataType x);
// 雙向鏈表尾刪
void ListPopBack(LTNode* pHead);
// 雙向鏈表頭插
void ListPushFront(LTNode* pHead, LTDataType x);
// 雙向鏈表頭刪
void ListPopFront(LTNode* pHead);
// 雙向鏈表查找
LTNode* ListFind(LTNode* pHead, LTDataType x);
// 雙向鏈表在pos的前面進行插入
void ListInsert(LTNode* pos, LTDataType x);
// 雙向鏈表刪除pos位置的節(jié)點
void ListErase(LTNode* pos);

首先我們得定義一個結(jié)點的結(jié)構(gòu),它由前驅(qū)指針、后繼指針和數(shù)據(jù)這三部分組成。

// 定義鏈表的節(jié)點
typedef struct ListNode {
 LTDataType data;
 struct ListNode* prev;
 struct ListNode* next;
}LTNode;

定義好之后,我們要創(chuàng)建一個頭結(jié)點。我們把創(chuàng)建頭結(jié)點的過程也封裝成一個函數(shù),這個函數(shù)的返回值就是頭結(jié)點的指針。我們在使用的時候就創(chuàng)建一個變量來接收這個指針。

**注意:**頭結(jié)點創(chuàng)建的時候,它的data部分是不存數(shù)據(jù)的,它的前驅(qū)和后繼都是指向它自己

LTNode* ListCreate() {
 LTNode* head = (LTNode*)malloc(sizeof(LTNode));
 head->next = head;
 head->prev = head;
 return head;
}
// 在main函數(shù)中是這樣使用的
int main(){
    LTNode* head = ListCreate();
    return 0;
}

創(chuàng)建好頭結(jié)點之后就可以向鏈表中插入數(shù)據(jù)了,首先實現(xiàn)尾插,就是在鏈表的最后一個結(jié)點后面再插入一個結(jié)點。然后就是頭插法,頭插法就是在頭結(jié)點的后面插入一個新節(jié)點。

// 雙向鏈表尾插
void ListPushBack(LTNode* pHead, LTDataType x) {
 assert(pHead);
 LTNode* newnode = (LTNode*)malloc(sizeof(LTNode)); // 創(chuàng)建的新節(jié)點
 newnode->data = x;
    // 將新節(jié)點插入到鏈表中
 LTNode* prev = pHead->prev;
 prev->next = newnode;
 newnode->prev = prev;
 newnode->next = pHead;
 pHead->prev = newnode;

}
// 雙向鏈表頭插
void ListPushFront(LTNode* pHead, LTDataType x) {
 assert(pHead);
    // 創(chuàng)建新節(jié)點
 LTNode* newnode = (LTNode*)malloc(sizeof(LTNode));
 newnode->data = x;
    //將新節(jié)點插入鏈表
 LTNode* next = pHead->next;
 pHead->next = newnode;
 newnode->prev = pHead;
 newnode->next = next;
 next->prev = newnode;
}

有插入數(shù)據(jù)就有刪除數(shù)據(jù),同樣的刪除數(shù)據(jù)也有兩種,一個是頭刪一個是尾刪。頭刪就是將頭結(jié)點的next指向的那個結(jié)點刪除。尾刪,就是將最后一個節(jié)點刪掉。帶頭雙向循環(huán)鏈表,在我們尾刪的時候就很方便。因為頭結(jié)點的前驅(qū)指向的節(jié)點就是鏈表的最后一個節(jié)點,就不需要我們再遍歷鏈表去找最后一個節(jié)點的地址。

// 雙向鏈表頭刪
void ListPopFront(LTNode* pHead) {
 assert(pHead);
 assert(pHead->next != pHead);
    // 定義一個臨時變量來保存我們要刪掉的節(jié)點的位置
 LTNode* popnode = pHead->next;
    // 將要刪除節(jié)點的鏈都斷掉
 LTNode* next = popnode->next;
 pHead->next = popnode->next;
 next->prev = pHead;
    // free掉那個節(jié)點
 free(popnode);
 popnode = NULL;
}
// 雙向鏈表尾刪
void ListPopBack(LTNode* pHead) {
 assert(pHead);
 assert(pHead->prev != pHead);
 LTNode* popnode = pHead->prev;
 LTNode* prev = popnode->prev;
 prev->next = pHead;
 pHead->prev = prev;
 free(popnode);
 popnode = NULL;
}

在實現(xiàn)了增加和刪除節(jié)點之后,我們就實現(xiàn)查找結(jié)點。方法也是遍歷整個鏈表,如果有一個節(jié)點的data的值和x相同就返回這個節(jié)點的地址。如果沒找到就返回空。

// 雙向鏈表查找
LTNode* ListFind(LTNode* pHead, LTDataType x) {
 if (pHead->next == pHead) {
  return NULL;
 }
 LTNode* find = pHead->next;
 while (find != pHead) {
  if (find->data == x) {
   return find;
  }
  find = find->next;
 }
 return NULL;
}

實現(xiàn)隨機插入數(shù)據(jù),這里的隨機插入的意思是,我們把新節(jié)點插入到我們指定的節(jié)點的后面一個或前面一個。這個節(jié)點可以是在鏈表的任何一個地方。我們這個函數(shù)會傳入一個節(jié)點的地址,通過那個地址可以找到要出入的那個節(jié)點,把新節(jié)點連接到那個節(jié)點后面就可以了

// 雙向鏈表刪除pos位置的節(jié)點
void ListErase(LTNode* pos) {
 assert(pos);
 LTNode* prev = pos->prev;
 LTNode* next = pos->next;
 prev->next = next;
 next->prev = prev;
 free(pos);
 pos = NULL;
}

打印雙向循環(huán)鏈表,也是通過遍歷鏈表來打印

// 雙向鏈表打印
void ListPrint(LTNode* pHead) {
 assert(pHead);
 LTNode* tail = pHead->next;
 while (tail != pHead) {
  printf("%d->", tail->data);
  tail = tail->next;
 }
}

在我們使用完鏈表后,要記得銷毀鏈表,防止內(nèi)存泄漏

// 雙向鏈表銷毀
void ListDestory(LTNode* pHead) {
 assert(pHead);
 LTNode* tail = pHead->next;
 while (tail != pHead) {
  LTNode* tmp = tail->next;
  free(tail);
  tail = tmp;
 }
 free(pHead);
 pHead = NULL;
}

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 深入jaxb xjc編碼問題的詳細介紹

    深入jaxb xjc編碼問題的詳細介紹

    本篇文章是對jaxb xjc編碼的問題進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • C++選擇排序算法實例詳解

    C++選擇排序算法實例詳解

    這篇文章主要為大家詳細介紹了C++選擇排序算法實例,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • Opencv實現(xiàn)畫筆功能

    Opencv實現(xiàn)畫筆功能

    這篇文章主要為大家詳細介紹了Opencv實現(xiàn)畫筆功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-08-08
  • C++ 實現(xiàn)球迷 今日頭條面試題

    C++ 實現(xiàn)球迷 今日頭條面試題

    這篇文章主要介紹了C++實現(xiàn)球迷今日頭條面試題功能,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-08-08
  • C語言算法積累加tag的循環(huán)隊列

    C語言算法積累加tag的循環(huán)隊列

    這篇文章主要為大家介紹了C語言算法積累加tag的循環(huán)隊列的解題思路,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • C語言銀行系統(tǒng)課程設(shè)計

    C語言銀行系統(tǒng)課程設(shè)計

    這篇文章主要為大家詳細介紹了C語言銀行系統(tǒng)課程設(shè)計,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • 淺談 C++17 里的 Visitor 模式

    淺談 C++17 里的 Visitor 模式

    Visitor模式經(jīng)常用于將更新的設(shè)計封裝在一個類中,并且由待更改的類提供一個接受接口,其關(guān)鍵技術(shù)在于雙分派技術(shù),本文主要介紹 C++17 里的 Visitor 模式的相關(guān)資料,需要的朋友可以參考下面文章的具體內(nèi)容
    2021-09-09
  • C語言函數(shù)的遞歸調(diào)用詳情

    C語言函數(shù)的遞歸調(diào)用詳情

    這篇文章主要介紹了C語言函數(shù)的遞歸調(diào)用詳情,遞歸做為一種算法在程序設(shè)計語言中廣泛應(yīng)用,主要的思考方式就是大事化小,下文具體的相關(guān)介紹,需要的小伙伴可以參考一下
    2022-04-04
  • C語言實現(xiàn)學(xué)生信息管理系統(tǒng)(文件版)

    C語言實現(xiàn)學(xué)生信息管理系統(tǒng)(文件版)

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)學(xué)生信息管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-07-07
  • C語言多文件編寫詳解

    C語言多文件編寫詳解

    這篇文章主要介紹了C語言多文件編寫,是C語言入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下,希望能夠給你帶來幫助
    2021-09-09

最新評論

利津县| 胶南市| 梅河口市| 邮箱| 崇义县| 青浦区| 灵石县| 宁安市| 磐石市| 奈曼旗| 日喀则市| 沙湾县| 固阳县| 东城区| 庆安县| 苏尼特左旗| 东源县| 会理县| 竹溪县| 定边县| 华池县| 大足县| 霍林郭勒市| 泸溪县| 集贤县| 洪江市| 绥中县| 资中县| 苏尼特右旗| 健康| 西平县| 济阳县| 白水县| 惠安县| 平原县| 开原市| 嘉祥县| 平顶山市| 台湾省| 武宣县| 玛多县|