当前位置:   article > 正文

带头的双向循环链表的实现_双向链表尾节点空节点

双向链表尾节点空节点

目录

概述:

初始工作

定义

 功能实现

初始化

获取新节点

头插

尾插

随即插入

头删

尾删

随机删除

修改

查找元素

打印链表

销毁

清空

判断为空

测试


概述:

要实现带头的双向循环链表,我们需要知道什么是头节点,如何循环。

首先,头节点是一个不存任何数据的节点,链表为空,也就是指此链表只有一个头节点。

其次,循环,则是指头指向尾,尾指向头,当链表尾空时,其头节点既是表头,也是表尾。

最后,双向,则是指其可以向前访问,也可以向后访问,这也说明了双向链表是由两个指针的,一个指向头,一个指向尾。

初始工作

定义

接下来我们定义一个双向循环链表,为了更方便的表示,我们对其进行再次封装

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. typedef int LNElemType;
  4. typedef struct ListNode{
  5. LNElemType val;
  6. struct ListNode* prev;
  7. struct ListNode* next;
  8. }ListNode;
  9. typedef struct BidList{
  10. ListNode* head;
  11. size_t size;
  12. }BidList;

考虑到数据的类型时不固定的,所以我们给出函数指针,对于不同的数据类型,由用户进行处理,我们只对基础数据类型进行处理

  1. typedef void(*PRINT)(LNElemType* val);
  2. typedef bool(*COMPARE)(LNElemType* src, LNElemType* des);
  3. typedef void(*ASSIG)(LNElemType* src, LNElemType* des);
  4. void printChar(char* val){
  5. printf("%c", *val);
  6. }
  7. void printShort(short* val){
  8. printf("%h", *val);
  9. }
  10. void printInt(int* val){
  11. printf("%d", *val);
  12. }
  13. void printLong(long* val){
  14. printf("%ld", *val);
  15. }
  16. void printfLongLong(long long* val){
  17. printf("%lld", *val);
  18. }
  19. void printFloat(float* val){
  20. printf("%f", *val);
  21. }
  22. void printDouble(double* val){
  23. printf("%lf", *val);
  24. }
  25. void printString(char** val){
  26. printf("%s", *val);
  27. }
  28. void IsEqual(LNElemType* src, LNElemType* des){
  29. return *src == *des;
  30. }
  31. void MoreThan(LNElemType* src, LNElemType* des){
  32. return *src < *des;
  33. }
  34. void LessThan(LNElemType* src, LNElemType* des){
  35. return *src > *des;
  36. }
  37. void setValue(LNElemType* src, LNElemType* des){
  38. *src = *des;
  39. }

 功能实现

初始化

  1. void BidListInit(BidList* phead)
  2. {
  3. assert(phead != NULL);
  4. phead->head = (ListNode*)malloc(sizeof(ListNode));
  5. if (phead->head == NULL)
  6. {
  7. perror("Init fail");
  8. exit(1);
  9. }
  10. phead->head->next = phead->head;
  11. phead->head->prev = phead->head;
  12. //考虑到链表的初始数据可能会是一个结构,所以我们不为头节点赋初始值,防止发生错误
  13. }

获取新节点

  1. ListNode* BuyNode(){
  2. ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));
  3. assert(newNode);
  4. return newNode;
  5. }

头插

  1. void BidListPushFront(BidList* phead, LNElemType val, ASSIG setValue){
  2. assert(phead != NULL);
  3. //创建节点
  4. ListNode* newNode = BuyNode();
  5. setValue(&newNode->val, &val);
  6. ListNode* first = phead->head->next;
  7. first->prev = newNode;
  8. newNode->next = first;
  9. newNode->prev = phead->head;
  10. phead->head->next = newNode;
  11. phead->size++;
  12. }

尾插

  1. void BidListPushBack(BidList* phead, LNElemType val, ASSIG setValue){
  2. assert(phead != NULL);
  3. ListNode* newNode = BuyNode();
  4. setValue(&newNode->val, &val);
  5. ListNode* tail = phead->head->prev;
  6. tail->next = newNode;
  7. newNode->next = phead->head;
  8. newNode->prev = tail;
  9. phead->head->prev = newNode;
  10. phead->size++;
  11. }

随即插入

  1. void BidListInert(BidList* phead, ListNode* pos, LNElemType val, ASSIG setValue){
  2. assert(pos != NULL);
  3. assert(phead != NULL);
  4. ListNode* newNode = BuyNode();
  5. setValue(&newNode->val, &val);
  6. ListNode* cur = pos->prev;
  7. cur->next = newNode;
  8. newNode->prev = cur;
  9. newNode->next = pos;
  10. pos->prev = newNode;
  11. phead->size++;
  12. }

头删

  1. void BidListPopFront(BidList* phead){
  2. assert(phead != NULL);
  3. if (phead->size == 0)
  4. {
  5. return;
  6. }
  7. ListNode* head = phead->head->next;
  8. phead->head->next = head->next;
  9. head->next->prev = phead->head;
  10. free(head);
  11. phead->size--;
  12. }

尾删

  1. void BidListPopBack(BidList* phead){
  2. assert(phead != NULL);
  3. if (phead->size == 0)
  4. {
  5. return;
  6. }
  7. ListNode* tail = phead->head->prev;
  8. tail->prev->next = phead->head;
  9. phead->head->next = tail->prev;
  10. free(tail);
  11. phead->size--;
  12. }

随机删除

  1. void BidListErase(BidList* phead, ListNode* pos){
  2. assert(pos != NULL);
  3. assert(phead != NULL);
  4. ListNode* next = pos->next;
  5. ListNode* prev = pos->prev;
  6. next->prev = prev;
  7. prev->next = next;
  8. free(pos);
  9. phead->size--;
  10. }

修改

  1. void BidListModify(BidList* phead, LNElemType src, LNElemType des, COMPARE IsEqual, ASSIG setValue){
  2. assert(phead != NULL);
  3. ListNode* p = phead->head->next;
  4. while (p != phead->head){
  5. if (IsEqual(&p->val, &src))
  6. {
  7. setValue(&p->val, &des);
  8. break;
  9. }
  10. p = p->next;
  11. }
  12. }

查找元素

  1. ListNode* BidListFind(BidList* phead, LNElemType val, COMPARE IsEqual){
  2. assert(phead);
  3. ListNode* p = phead->head->next;
  4. while (p != phead->head){
  5. if (IsEqual(&p->val, &val)){
  6. return p;
  7. }
  8. p = p->next;
  9. }
  10. return NULL;
  11. }

打印链表

  1. void BidListPrint(BidList* phead, PRINT print){
  2. assert(phead);
  3. ListNode* head = phead->head->next;
  4. printf("guard<->");
  5. while (head != phead->head){
  6. print(&head->val);
  7. printf("<->");
  8. head = head->next;
  9. }
  10. printf("guard\n");
  11. }

销毁

  1. void BidListDestory(BidList* phead){
  2. assert(phead != NULL);
  3. ListNode* p = phead->head->next;
  4. ListNode* t = p;
  5. while (p->next != phead->head){
  6. p = t->next;
  7. free(t);
  8. t = p;
  9. }
  10. free(phead->head);
  11. phead->head = NULL;
  12. phead->size = 0;
  13. }

清空

  1. void BidListClear(BidList* phead){
  2. assert(phead != NULL);
  3. ListNode* p = phead->head->next;
  4. ListNode* t = p;
  5. while (p->next != phead->head){
  6. p = t->next;
  7. free(t);
  8. t = p;
  9. }
  10. phead->head->next = phead->head;
  11. phead->head->prev = phead->head;
  12. phead->size = 0;
  13. }

判断为空

  1. bool BidListIsEmpty(BidList* phead)
  2. {
  3. assert(phead != NULL);
  4. return phead->size == 0;
  5. }

测试

  1. void test01()
  2. {
  3. BidList list;
  4. BidListInit(&list);
  5. BidListPushBack(&list, 1, setValue);
  6. BidListPushBack(&list, 2, setValue);
  7. BidListPushBack(&list, 3, setValue);
  8. BidListPushFront(&list, 10, setValue);
  9. BidListPushFront(&list, 20, setValue);
  10. BidListPushFront(&list, 30, setValue);
  11. BidListPrint(&list, printInt);
  12. ListNode* pos = BidListFind(&list, 2, IsEqual);
  13. BidListInert(&list, pos, 200, setValue);
  14. BidListErase(&list, pos);
  15. BidListModify(&list, 200, 100, IsEqual, setValue);
  16. BidListPrint(&list, printInt);
  17. BidListClear(&list);
  18. BidListPrint(&list,printInt);
  19. BidListPopBack(&list);
  20. BidListDestory(&list);
  21. }
  22. int main()
  23. {
  24. test01();
  25. system("pause");
  26. return 0;
  27. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/593769
推荐阅读
相关标签
  

闽ICP备14008679号