日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数据结构-线性表之带头结点的双向循环链表

發(fā)布時間:2025/3/15 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构-线性表之带头结点的双向循环链表 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

  • 前言
  • 實現(xiàn)
    • (1)結(jié)構(gòu)定義
    • (2)基本函數(shù)
    • (3)操作實現(xiàn)
  • 測試
  • 代碼

前言

鏈表的類型有很多種(根據(jù)帶頭或不帶頭,循環(huán)或非循環(huán)等等),但是我們重點研究的只有兩種,一種結(jié)構(gòu)非常簡單是無頭單向非循環(huán)鏈表,有關(guān)它的操作見

數(shù)據(jù)結(jié)構(gòu)-線性表之單鏈表

這種結(jié)果在開發(fā)中基本不會使用,因為因為結(jié)構(gòu)簡單往往意味著操作復(fù)雜,比如在OJ題,有關(guān)鏈表的題使用的都是這種結(jié)構(gòu),關(guān)于這些OJ題感興趣的見

鏈表經(jīng)典題

另一種則是鏈表中結(jié)構(gòu)最為復(fù)雜的——帶頭結(jié)點的雙向循環(huán)鏈表

這種鏈表結(jié)構(gòu)復(fù)雜,但卻操作很簡單,比如最常用的尾插操作,其時間復(fù)雜度為O(1)。同時C++中STL中的list就是這種結(jié)構(gòu)
對于這種結(jié)構(gòu),由于它帶了頭結(jié)點(也稱為哨兵結(jié)點),所以很多操作不用像單鏈表那樣還要額外處理第一個結(jié)點為空的情況,而又因為它帶了尾節(jié)點,所以也方便尾插等操作

注意其鏈表的空的判斷情況

head->prev=head haed->next=head

實現(xiàn)

(1)結(jié)構(gòu)定義

typedef struct DListNode {struct ListNode* next;//指向前一個結(jié)點struct ListNode* prev;//指向后一個結(jié)點DLdatatype val; }DListNode;

(2)基本函數(shù)

1:申請結(jié)點、

2:打印
對于打印稍加注意,在這種結(jié)構(gòu)中是沒有NULL的,也就是判斷結(jié)束的條件不能去找NULL,而是要找頭

(3)操作實現(xiàn)

1:尾插


2:尾刪


3:頭插


4:頭刪

5:找結(jié)點


6:任意位置插入(某節(jié)點之后)

7:在任意位置插入(某節(jié)點之前)

8:任意位置刪除

9:銷毀

測試

代碼

Dlist.h

#pragma once #include <stdio.h> #include <assert.h> #include <stdlib.h>typedef int DLdatatype; typedef struct DListNode {struct DListNode* next;struct DListNode* prev;DLdatatype val;}DListNode;void printlist(DListNode* head);//打印 DListNode* CreatNode(DLdatatype x);//申請結(jié)點void ListPushBack(DListNode* head, DLdatatype x);//尾插 void ListPopBack(DListNode* head);//尾刪 void listPushFront(DListNode* head, DLdatatype x);//頭插 void listPopFront(DListNode* head);//頭刪DListNode* find(DListNode* head, DLdatatype x);//找某個元素 void listinseret_behind(DListNode* head,DLdatatype pos, DLdatatype x);//任意位置插入(后面) void listinseret_front(DListNode* head,DLdatatype pos, DLdatatype x);//任意位置插入(前面) void listdelete(DListNode* head,DLdatatype pos);//任意位置刪除void listdestory(DListNode* head);//鏈表銷毀

Dlist.c

#include "DList.h"DListNode* CreatNode(DLdatatype x) {DListNode* NewNode = (DListNode*)malloc(sizeof(DListNode));NewNode->val = x;NewNode->next = NULL;NewNode->prev = NULL;return NewNode; }void printlist(DListNode* head) {assert(head);DListNode* cur = head->next;while (cur!=head){printf("%d->", cur->val);cur = cur->next;}if (head->next == head)printf("NULL");}void ListPushBack(DListNode* head, DLdatatype x) {assert(head);DListNode* NewNode=CreatNode(x);NewNode->next = head;(head->prev)->next = NewNode;NewNode->prev = head->prev;head->prev = NewNode; }void ListPopBack(DListNode* head) {assert(head);assert(head->next != head);//如果鏈表為空,斷言DListNode* delelte = head->prev;head->prev = delelte->prev;delelte->prev->next = head;free(delelte); }void listPushFront(DListNode* head, DLdatatype x) {assert(head);DListNode* NewNode = CreatNode(x);NewNode->next = head->next;NewNode->prev = head;head->next->prev = NewNode;head->next = NewNode;} void listPopFront(DListNode* head) {assert(head);assert(head->next != head);DListNode* first = head->next;first->next->prev = head;head->next = first->next;free(first);}DListNode* find(DListNode* head, DLdatatype x) {assert(head);DListNode* cur = head->next;while (cur->next != head && cur->val != x){cur = cur->next;}if (cur->next == head && cur->val!=x){return NULL;//未找到}else{return cur;//否則返回}}void listinseret_behind(DListNode* head, DLdatatype pos, DLdatatype x) {assert(head);DListNode* insert = find(head, pos);if (insert == NULL){printf("%d不存在\n", pos);}else{DListNode* NewNode = CreatNode(x);NewNode->next = insert->next;NewNode->prev = insert;insert->next->prev = NewNode;insert->next = NewNode;}}void listinseret_front(DListNode* head, DLdatatype pos, DLdatatype x) {assert(head);DListNode* insert = find(head, pos);if (insert == NULL){printf("%d不存在\n", pos);}{DListNode* NewNode = CreatNode(x);NewNode->next = insert;NewNode->prev = insert->prev;NewNode->prev->next = NewNode;insert->prev = NewNode;}}void listdelete(DListNode* head, DLdatatype pos) {assert(head);assert(pos != head);DListNode* delete = find(head, pos);if (delete == NULL){printf("%d不存在\n", pos);}else{delete->prev->next = delete->next;delete->next->prev = delete->prev;free(delete);}}void listdestory(DListNode* head) {assert(head);DListNode* cur = head->next;DListNode* pre = NULL;while (cur->next != head){pre = cur;cur = cur->next;free(pre);}head->next =head;head->prev = head;}

test.c

#include "DList.h"void test() {DListNode* head=(DListNode*)malloc(sizeof(DListNode));head->prev = head;head->next = head;printf("尾插4個結(jié)點\n");ListPushBack(head, 1);ListPushBack(head, 2);ListPushBack(head, 3);ListPushBack(head, 4);printlist(head);printf("\n");printf("\n");printf("尾刪2個結(jié)點\n");ListPopBack(head);ListPopBack(head);printlist(head);printf("\n");printf("\n");printf("頭插4個結(jié)點\n");listPushFront(head, 5);listPushFront(head, 6);listPushFront(head, 7);listPushFront(head, 8);printlist(head);printf("\n");printf("\n");printf("頭刪2個結(jié)點\n");listPopFront(head);listPopFront(head);printlist(head);printf("\n");printf("\n");printf("在5后面插入7\n");listinseret_behind(head, 5, 7);printlist(head);printf("\n");printf("\n");printf("刪除1\n");listdelete(head, 1);printlist(head);printf("\n");printf("\n");printf("銷毀\n");listdestory(head);printlist(head);printf("\n");printf("\n");}int main() {test(); }

總結(jié)

以上是生活随笔為你收集整理的数据结构-线性表之带头结点的双向循环链表的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。