【数据结构】线性表(四):链表 之 双向循环链表

﹏ヽ暗。殇╰゛Y 2023-03-02 05:12 92阅读 0赞

文章目录

  • 双向循环链表
    • 一、概念
    • 二、图解
    • 三、实现源码

双向循环链表

一、概念

双向循环链表是指每个结点由三部分组成:数据域、直接前驱结点指针、直接后继结点指针,该链表的最后一个结点的直接后继指针指向头结点,头结点的直接前驱指针指向尾节点。

二、图解

结点图示
在这里插入图片描述

双向循环链表图示
在这里插入图片描述

三、实现源码

常量定义

  1. typedef int ET;

双向循环链表定义

  1. typedef struct Node
  2. {
  3. ET data;
  4. Node* next;
  5. Node* prev;
  6. }Node;
  7. typedef Node* BCList;

获取一个新节点

  1. Node* CreateNode(ET val){
  2. Node* s = (Node*)malloc(sizeof(Node));
  3. assert(s != NULL);
  4. s->data = val;
  5. s->next = s->prev = s;
  6. return s;
  7. }

初始化一个带头结点的双向循环链表

  1. void BCLinkedListInitial(BCList* phead){
  2. *phead = CreateNode(-1);
  3. }

头插法

  1. void BCLinkedListAddFromHead(BCList* phead, ET val){
  2. assert(phead != NULL);
  3. Node* s = CreateNode(val);
  4. Node* p = (*phead)->next;
  5. s->next = p;
  6. s->prev = *phead;
  7. (*phead)->next = s;
  8. p->prev = s;
  9. }

尾插法

  1. void BCLinkedListAddFromBack(BCList* phead, ET val){
  2. assert(phead != NULL);
  3. Node* s = CreateNode(val);
  4. Node* p = (*phead)->prev;
  5. (*phead)->prev = s;
  6. s->next = *phead;
  7. s->prev = p;
  8. p->next = s;
  9. }

显示数据

  1. void BCLinkedListShowData(BCList phead){
  2. Node* p = phead->next;
  3. while (p != phead){
  4. printf("%d ", p->data);
  5. p = p->next;
  6. }
  7. printf("\n");
  8. }

判断表是否为空

  1. bool IsEmpty(BCList* phead){
  2. if ((*phead)->prev == (*phead)){
  3. return true;
  4. }
  5. return false;
  6. }

删除尾部结点

  1. void BCLinkedListDeleteFromBack(BCList* phead){
  2. assert(phead != NULL);
  3. if (IsEmpty(phead)){
  4. printf("表空,无法删除!\n");
  5. return;
  6. }
  7. Node* s = (*phead)->prev;
  8. (*phead)->prev = s->prev;
  9. s->prev->next = *phead;
  10. free(s);
  11. }

删除首元结点

  1. void BCLinkedListDeleteFromHead(BCList* phead){
  2. assert(phead != NULL);
  3. if (IsEmpty(phead)){
  4. printf("表空,无法删除!\n");
  5. return;
  6. }
  7. Node* s = (*phead)->next;
  8. Node* p = s->next;
  9. (*phead)->next = p;
  10. p->prev = *phead;
  11. free(s);
  12. }

获取尾结点

  1. Node* BCLinkedListGetBack(BCList* phead){
  2. assert(phead != NULL);
  3. if (IsEmpty(phead)){
  4. printf("表空,无法获得!\n");
  5. return NULL;
  6. }
  7. return (*phead)->prev;
  8. }

获取首元结点

  1. Node* BCLinkedListGetHead(BCList* phead){
  2. assert(phead != NULL);
  3. if (IsEmpty(phead)){
  4. printf("表空,无法获得!\n");
  5. return NULL;
  6. }
  7. return (*phead)->next;
  8. }

获取表长度

  1. size_t BCLinkedListGetListLength(BCList* phead){
  2. assert(phead != NULL);
  3. Node* p = (*phead)->next;
  4. size_t len = 0;
  5. while (p != (*phead)){
  6. p = p->next;
  7. len++;
  8. }
  9. return len;
  10. }

清空表中数据

  1. void BCLinkedListClear(BCList* phead){
  2. assert(phead != NULL);
  3. Node* p = (*phead)->next;
  4. Node* q = (*phead)->next;
  5. while (q != (*phead)){
  6. q = q->next;
  7. free(p);
  8. p = q;
  9. }
  10. (*phead)->next = *phead;
  11. (*phead)->prev = *phead;
  12. }

摧毁表结构

  1. void BCLinkedListDestroy(BCList* phead){
  2. assert(phead != NULL);
  3. Node* p = (*phead)->next;
  4. Node* q = (*phead)->next;
  5. (*phead)->next = NULL;
  6. while (q != NULL){
  7. q = q->next;
  8. free(p);
  9. p = q;
  10. }
  11. *phead = NULL;
  12. }

按值查找

  1. Node* BCLinkedListFindByValue(BCList* phead, ET key){
  2. assert(phead != NULL);
  3. Node* p = (*phead)->next;
  4. while (p != (*phead) && p->data != key){
  5. p = p->next;
  6. }
  7. if (p == *phead) return NULL;
  8. return p;
  9. }

按值的大小插入

  1. void BCLinkedListInsertByValue(BCList* phead, ET val){
  2. assert(phead != NULL);
  3. Node *p = (*phead)->next;
  4. while (p != *phead && p->data < val){
  5. p = p->next;
  6. }
  7. if (p == *phead){
  8. BCLinkedListAddFromBack(phead, val);
  9. }
  10. else{
  11. Node* s = CreateNode(val);
  12. Node* q = p->prev;
  13. q->next = s;
  14. s->next = p;
  15. p->prev = s;
  16. s->prev = q;
  17. }
  18. }

将表中结点按照数据升序链接

  1. void BCLinkedListSortByData(BCList* phead){
  2. assert(phead != NULL);
  3. Node *p = (*phead)->next->next;
  4. Node *q = (*phead)->next->next;
  5. (*phead)->prev->next = NULL;
  6. (*phead)->next->next = (*phead);
  7. (*phead)->prev = (*phead)->next;
  8. while (q != NULL){
  9. q = q->next;
  10. if ((*phead)->next->data > p->data){
  11. BCLinkedListAddFromHead(phead, p->data);
  12. free(p);
  13. }
  14. else{
  15. Node* temp = (*phead)->next;
  16. while (temp->next != (*phead) && temp->data < p->data){
  17. temp = temp->next;
  18. }
  19. if (temp->next == (*phead)){
  20. BCLinkedListAddFromBack(phead, p->data);
  21. free(p);
  22. }
  23. else{
  24. p->next = temp;
  25. p->prev = temp->prev;
  26. temp->prev->next = p;
  27. temp->prev = p;
  28. }
  29. }
  30. p = q;
  31. }
  32. }

反转链表

  1. void BCLinkedListReverseList(BCList* phead){
  2. assert(phead != NULL);
  3. if (IsEmpty(phead)) return;
  4. Node* p = (*phead)->prev;
  5. Node* q = (*phead)->prev;
  6. (*phead)->next->prev = NULL; //创造循环结束条件
  7. //将头结点置空
  8. (*phead)->next = (*phead)->prev = *phead;
  9. while (q != NULL){
  10. q = q->prev;
  11. BCLinkedListAddFromBack(phead, p->data);
  12. free(p);
  13. p = q;
  14. }
  15. }

发表评论

表情:
评论列表 (有 0 条评论,92人围观)

还没有评论,来说两句吧...

相关阅读