zoukankan      html  css  js  c++  java
  • 54. 实现对 有头双向链表的基本操作 创建,插入,查找,删除,遍历,排序,销毁

    1 #include <stdio.h>
    2 #include <stdlib.h>
    3 
    4 typedef struct _dnode
    5 {
    6     int data;
    7     struct _dnode *pre;
    8     struct _dnode *next;
    9 }Dnode;
     1 //创建空链表     //让头结点指向自己,方便以后的操作。
     2 int createDlist(Dnode** head)
     3 {
     4     *head = (Dnode*)malloc(sizeof(Dnode));
     5     if(head == NULL)
     6         return -1;
     7     (*head)->next = *head;
     8     (*head)->pre = *head;
     9     return 0;
    10 }
     1 //插入新节点,头插
     2 //创建链表时让头结点指向自己目的是 :
     3 //功能上不只为一层。为了让多层同样式代码通用化。比如方便实现插入的功能代码。循环要写成通用形式比较难。所以在创建链表时让头节点指向自己,这样可以让空链表状态的插入的功能代码与有节点链表状态的插入的 功能代码一样。
     4 void insertDlist(Dnode *head,int data)
     5 {
     6 
     7     Dnode *newNode = (Dnode*)malloc(sizeof(Dnode));
     8     newNode->data = data;
     9 
    10     /*插入三步曲,*/
    11     //先处理新节点指向 ,连上左右两边的节点
    12     newNode->next = head->next;
    13     newNode->pre = head;
    14 
    15     head->next = newNode;//再处理左节点指向,连上新节点
    16     newNode->next->pre = newNode;//再处理右节点,连上新节点
    17 }
     1 //求链表长度
     2 int getLenDlist(Dnode* head)
     3 {
     4     Dnode* cur = head->next;
     5     int len = 0;
     6     while(cur != head)
     7     {
     8         len++;
     9         cur = cur->next;
    10     }
    11     return len;
    12 }
     1 //查找
     2 //单向查找
     3 Dnode* searchDlist(Dnode* head,int find)
     4 {
     5     Dnode* cur = head->next;
     6     while(cur != head)
     7     {
     8         if(cur->data == find)
     9             return cur;
    10     }
    11     return NULL;
    12 }
    13 
    14 
    15 //双向查找
    16 /*分别从两头往中找,结束时可能会遇见两种情况
    17 情况1 碰头了之后再判断一次,如果仍没找到,停止 。找到直接返回
    18 情况2 交错之后,如果仍没找到,停止。
    19 
    20 
    21 
    22 实现循环中的代码的通用性,就这三条路
    23 实现方式1   让情况1为主包含情况2     无法实现
    24 实现方式2   让情况2为主包含情况1      可以实现   逻辑是 擦肩而过之前一定会相遇
    25 实现方式3   同时包含情况1情况2 ,两种情况平行       使用while(1)把这个也实现下
    26 (把这个实现循环通用化的思想好好总结一下,感觉特别重要,常常会遇见写循环时需要实现有多种情况通用化的合体代码)
    27 */
    28 
    29 //实现方式2
    30 Dnode* searchDlist2(Dnode* head,int find)
    31 {
    32     Dnode* clock = head->next;
    33     Dnode* unclock = head->pre;
    34 
    35     while(clock != unclock->next)//也可以while(unclock != clock->pre) //以情况2为主
    36     {
    37         if(clock->data == find)
    38             return clock;
    39         if(unclock->data == find)
    40             return unclock;
    41 
    42         if(clock == unclock)//以情况1为次
    43             break;
    44 
    45         clock = clock->next;
    46         unclock = unclock->pre;
    47     }
    48     return NULL;
    49 }
    50 //实现方式3    //感觉不对劲,虽然测对了
    51 Dnode* searchDlist3(Dnode* head,int find)
    52 {
    53     Dnode* clock = head->next;
    54     Dnode* unclock = head->pre;
    55 
    56     while(1)
    57     {
    58         if(clock->data == find)
    59             return clock;
    60         if(unclock->data == find)
    61             return unclock;
    62 
    63         if(clock == unclock || clock == unclock->next)
    64             break;
    65 
    66 
    67         clock = clock->next;
    68         unclock = unclock->pre;
    69     }
    70     return NULL;
    71 
    72 }
    1 //删除
    2 //不用像单链表那样找前驱了,双链表可以直接访问到前驱。
    3 void deleteDlistNode(Dnode *deleteNode)
    4 {
    5     deleteNode->pre->next = deleteNode->next;
    6     deleteNode->next->pre = deleteNode->pre;
    7     free(deleteNode);
    8 
    9 }
     1 //销毁   //包括头结点一起销毁,另需将头指针指向NULL
     2 //方式1
     3 void destroyDlist1(Dnode** head)
     4 {
     5     Dnode* cur = (*head)->next;
     6     while(cur != *head)
     7     {
     8         Dnode* temp = cur;
     9         cur = cur->next;
    10         free(temp);
    11     }
    12     free(*head);
    13     *head = NULL;
    14 }
    15 //方式2,先把双向链表废成单向链表,再一一删除
    16 void destroyDlist2(Dnode** head)
    17 {
    18     (*head)->pre->next = NULL;
    19     while(*head)//遍历完后*head==NULL
    20     {
    21         Dnode* temp = *head;
    22         *head = (*head)->next;
    23         free(temp);
    24     }
    25 }
     1 //排序
     2 
     3 
     4 //对数据域进行交换
     5 //用冒泡排序实现
     6 void bubbleSortDlistData(Dnode* head)
     7 {
     8     int len = getLenDlist(head);
     9     Dnode* pcur = head;
    10     Dnode* pnext;
    11     int i,j;
    12     for(i = 0; i < len-1;i++)
    13     {
    14         pcur = head->next;
    15         pnext = pcur->next;
    16         for(j = 0;j<len-1-i;j++)
    17         {
    18 
    19             if(pcur->data > pnext->data)
    20             {
    21                 pcur->data ^= pnext->data;
    22                 pnext->data ^= pcur->data;
    23                 pcur->data ^= pnext->data;
    24             }
    25 
    26             pcur = pcur->next;
    27             pnext = pcur->next;
    28         }
    29     }
    30 }
    31 
    32 //用选择排序实现
    33 void selectSortDlistData(Dnode* head)//升序
    34 {
    35     int len = getLenDlist(head);
    36     Dnode* pcur;
    37     Dnode* pnext;
    38 
    39     for(pcur = head->next; pcur->next != head ;pcur = pcur->next)
    40     {
    41         for(pnext = pcur->next;pnext != head;pnext = pnext->next)
    42         {
    43             if(pcur->data > pnext->data)
    44             {
    45                 pcur->data ^= pnext->data;
    46                 pnext->data ^= pcur->data;
    47                 pcur->data ^= pnext->data;
    48             }
    49         }
    50     }
    51 
    52 
    53 }
    54 
    55 
    56 //对指针域进行交换
    57 //不再像单链表那样专门记录前驱节点地址,因为有pre成员
    58 
    59 
    60 //使用冒泡排序实现
    61 void bubbleSortDlistPointer(Dnode* head)//升序
    62 {
    63     int len = getLenDlist(head);
    64     Dnode* pcur;
    65     Dnode* pnext;
    66 
    67     int i,j;
    68     for(i = 0;i<len-1;i++)
    69     {
    70         pcur = head->next;
    71         pnext = pcur->next;
    72         for(j=0;j<len-1-i;j++)
    73         {
    74             if(pcur->data > pnext->data)
    75             {
    76                 pcur->pre->next = pnext;
    77                 pnext->pre = pcur->pre;
    78 
    79                 pcur->next = pnext->next;
    80                 pnext->next->pre = pnext;
    81 
    82                 pnext->next = pcur;
    83                 pcur->pre = pnext;
    84 
    85 
    86 
    87                 pcur = pcur->pre;
    88             }
    89             pcur = pcur->next;
    90             pnext = pcur->next;
    91         }
    92     }
    93 }
    94 
    95 
    96 //使用选择排序实现
    97 //待补
     1 //遍历
     2 
     3 //遍历节点,向前
     4 void traverseDlistNext(Dnode* head)
     5 {
     6     Dnode* phead = head->next;
     7     while(phead != head)
     8     {
     9         printf("%d ",phead->data);
    10         phead = phead->next;
    11     }
    12     putchar(10);
    13 }
    14 
    15 //遍历节点,向后
    16 void traverseDlistPre(Dnode* head)
    17 {
    18     Dnode* phead = head->pre;
    19     while(phead != head)
    20     {
    21         printf("%d ",phead->data);
    22         phead = phead->pre;
    23     }
    24     putchar(10);
    25 }
  • 相关阅读:
    KL散度(相对熵)和交叉熵的区别
    将模型从 PyTorch 导出到 ONNX 并使用 ONNX Runtime 运行
    Numpy Boolean Indexing Mask(Numpy 布尔索引掩码 )
    python PIL 图像处理库(Pillow)简介
    YOLO v3 网络结构和源码详解
    PyTorch 下使用 Tensorboard
    Python vars() 函数
    python 的 Tqdm 模块
    Pytorch 中的模式设置:model.eval() 和 model.train()
    Pytorch 中的 zero_grad 使用方法
  • 原文地址:https://www.cnblogs.com/ZhuLuoJiGongYuan/p/9544356.html
Copyright © 2011-2022 走看看