数据结构-线性表之带头结点的双向循环链表
文章目錄
- 前言
- 實現(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)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 周总结(第六周)
- 下一篇: 1 Orchard 入门篇-Orchar