• 23.双向环形链表


    运行截图:

    • 结点结构体
      1 typedef struct LinkNode
      2 {
      3     int data;
      4     struct LinkNode *pPre;
      5     struct LinkNode *pNext;
      6 }node,*PNODE;
    • 创建一个结构体保存头部和尾部
      typedef struct info
      {
          node *head;//指向头部
          node *tail;//指向尾部
      }DList;
    • 初始化环形链表
      1 void init(DList *p)
      2 {
      3     p->head = NULL;
      4     p->tail = NULL;
      5 }
    •  1 //在链表尾部插入数据
       2 void addDataBack(DList *p, int data)
       3 {
       4     //创建一个新的结点
       5     node *pnew = (node *)malloc(sizeof(node));
       6     pnew->data = data;
       7     pnew->pNext = NULL;
       8     pnew->pPre = NULL;
       9 
      10     //如果链表为空
      11     if (p->head == NULL || p->tail == NULL)
      12     {
      13         //插入一个结点
      14         p->tail = p->head = pnew;
      15         pnew->pPre = pnew->pNext = pnew;
      16     }
      17     //如果只有一个结点
      18     else if(p->head == p->tail)
      19     {
      20         p->head->pPre = pnew;
      21         p->head->pNext = pnew;
      22 
      23         pnew->pPre = p->head;
      24         pnew->pNext = p->head;
      25 
      26         p->tail = pnew;//保存尾部
      27     }
      28     //如果大于一个结点
      29     else
      30     {
      31         pnew->pPre = p->tail;
      32         pnew->pNext = p->head;
      33 
      34         p->tail->pNext = pnew;
      35         p->head->pPre = pnew;
      36 
      37         p->tail = pnew;
      38     }
      39 }
    • 在链表头部插入数据
       1 void addDataHead(DList *p, int data)
       2 {
       3     //创建一个新的结点
       4     PNODE pnew = (PNODE)malloc(sizeof(node));
       5     pnew->data = data;
       6     pnew->pNext = NULL;
       7     pnew->pPre = NULL;
       8 
       9     //如果链表为空
      10     if (p->head == NULL && p->tail == NULL)
      11     {
      12         p->tail = p->head = pnew;
      13         pnew->pPre = pnew->pNext = pnew;
      14     }
      15     //如果只有一个结点
      16     else if (p->head == p->tail)
      17     {
      18         pnew->pPre = pnew->pNext = p->head;
      19         p->head->pNext = p->head->pPre = pnew;
      20 
      21         p->head = pnew;
      22     }
      23     //如果大于一个结点
      24     else
      25     {
      26         pnew->pPre = p->tail;
      27         pnew->pNext = p->head;
      28 
      29         p->head->pPre = pnew;
      30         p->tail->pNext = pnew;
      31 
      32         p->head = pnew;
      33     }
      34 }
    • 查询数据
       1 //查询数据
       2 PNODE find(DList *p, int data)
       3 {
       4     if (p->head == NULL || p->tail == NULL)
       5     {
       6         return NULL;
       7     }
       8     else if (p->head == p->tail)
       9     {
      10         PNODE pl = p->head;
      11         if (pl->data == data)
      12         {
      13             return pl;
      14         }
      15         else
      16         {
      17             return NULL;
      18         }
      19     }
      20     else
      21     {
      22         PNODE pl = p->head;
      23         for (; pl->pNext != p->head; pl = pl->pNext)
      24         {
      25             if (pl->data == data)
      26             {
      27                 return pl;
      28             }
      29         }
      30         //尾部补充一个
      31         if (pl->data == data)
      32         {
      33             return pl;
      34         }
      35         else
      36         {
      37             return NULL;
      38         }
      39     }
      40 }
    • 改变一个结点的数据
      void change(DList *p, int data,int newdata)
      {
          if (p->head == NULL || p->tail == NULL)
          {
              return;
          }
          //如果只有一个结点
          else if (p->head == p->tail)
          {
              PNODE pl = p->head;
              if (pl->data == data)
              {
                  pl->data == newdata;
              }
          }
          //如果大于一个结点
          else
          {
              PNODE pl = p->head;
              for (; pl->pNext != p->head; pl = pl->pNext)
              {
                  if (pl->data == data)
                  {
                      pl->data == newdata;
                  }
              }
              //尾部补充一个
              if (pl->data == data)
              {
                  pl->data == newdata;
              }
          }
      }
    • 删除一个结点
       1 void deleteData(DList *p, int data)
       2 {
       3     //先判断只有一个结点的情况
       4     if (p->head == p->tail)
       5     {
       6         if (p->head->data == data)
       7         {
       8             free(p->head);
       9             p->head = NULL;
      10             p->tail = NULL;
      11         }
      12     }
      13     //结点个数大于1
      14     else
      15     {
      16         //备份头结点
      17         PNODE pl = p->head;
      18         //先判断是不是头结点
      19         if (pl->data == data)
      20         {
      21             pl->pNext->pPre = p->tail;
      22             p->tail->pNext = pl->pNext;
      23             p->head = pl->pNext;
      24             free(pl);
      25         }
      26         //如果不是头结点
      27         else
      28         {
      29             //一直从后一个遍历到结束
      30             pl = pl->pNext;
      31             while (pl != p->head)
      32             {
      33                 if (pl->data == data)
      34                 {
      35                     break;
      36                 }
      37                 else
      38                 {
      39                     pl = pl->pNext;
      40                 }
      41             }
      42             //如果找到了
      43             if (pl != p->head)
      44             {
      45                 //如果循环到尾部
      46                 if (pl == p->tail)
      47                 {
      48                     pl->pPre->pNext = p->head;
      49                     p->head->pPre = pl->pPre;
      50 
      51                     p->tail = pl->pPre;
      52                     free(pl);
      53                 }
      54                 //如果在中间
      55                 else
      56                 {
      57                     pl->pNext->pPre = pl->pPre;
      58                     pl->pPre->pNext = pl->pNext;
      59                     free(pl);
      60                 }
      61             }
      62         }
      63     }
      64     
      65 }

    完整代码:

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 
      4 //双链表节点
      5 typedef struct LinkNode
      6 {
      7     int data;
      8     struct LinkNode *pPre;
      9     struct LinkNode *pNext;
     10 }node,*PNODE;
     11 
     12 //创建一个结构体保存头部和尾部
     13 typedef struct info
     14 {
     15     node *head;//指向头部
     16     node *tail;//指向尾部
     17 }DList;
     18 
     19 void init(DList *p)
     20 {
     21     p->head = NULL;
     22     p->tail = NULL;
     23 }
     24 
     25 //在链表尾部插入数据
     26 void addDataBack(DList *p, int data)
     27 {
     28     //创建一个新的结点
     29     node *pnew = (node *)malloc(sizeof(node));
     30     pnew->data = data;
     31     pnew->pNext = NULL;
     32     pnew->pPre = NULL;
     33 
     34     //如果链表为空
     35     if (p->head == NULL || p->tail == NULL)
     36     {
     37         //插入一个结点
     38         p->tail = p->head = pnew;
     39         pnew->pPre = pnew->pNext = pnew;
     40     }
     41     //如果只有一个结点
     42     else if(p->head == p->tail)
     43     {
     44         p->head->pPre = pnew;
     45         p->head->pNext = pnew;
     46 
     47         pnew->pPre = p->head;
     48         pnew->pNext = p->head;
     49 
     50         p->tail = pnew;
     51     }
     52     //如果大于一个结点
     53     else
     54     {
     55         pnew->pPre = p->tail;
     56         pnew->pNext = p->head;
     57 
     58         p->tail->pNext = pnew;
     59         p->head->pPre = pnew;
     60 
     61         p->tail = pnew;
     62     }
     63 }
     64 
     65 //在链表头部插入数据
     66 void addDataHead(DList *p, int data)
     67 {
     68     //创建一个新的结点
     69     PNODE pnew = (PNODE)malloc(sizeof(node));
     70     pnew->data = data;
     71     pnew->pNext = NULL;
     72     pnew->pPre = NULL;
     73 
     74     //如果链表为空
     75     if (p->head == NULL && p->tail == NULL)
     76     {
     77         p->tail = p->head = pnew;
     78         pnew->pPre = pnew->pNext = pnew;
     79     }
     80     //如果只有一个结点
     81     else if (p->head == p->tail)
     82     {
     83         pnew->pPre = pnew->pNext = p->head;
     84         p->head->pNext = p->head->pPre = pnew;
     85 
     86         p->head = pnew;
     87     }
     88     //如果大于一个结点
     89     else
     90     {
     91         pnew->pPre = p->tail;
     92         pnew->pNext = p->head;
     93 
     94         p->head->pPre = pnew;
     95         p->tail->pNext = pnew;
     96 
     97         p->head = pnew;
     98     }
     99 }
    100 
    101 //查询数据
    102 PNODE find(DList *p, int data)
    103 {
    104     if (p->head == NULL || p->tail == NULL)
    105     {
    106         return NULL;
    107     }
    108     else if (p->head == p->tail)
    109     {
    110         PNODE pl = p->head;
    111         if (pl->data == data)
    112         {
    113             return pl;
    114         }
    115         else
    116         {
    117             return NULL;
    118         }
    119     }
    120     else
    121     {
    122         PNODE pl = p->head;
    123         for (; pl->pNext != p->head; pl = pl->pNext)
    124         {
    125             if (pl->data == data)
    126             {
    127                 return pl;
    128             }
    129         }
    130         //尾部补充一个
    131         if (pl->data == data)
    132         {
    133             return pl;
    134         }
    135         else
    136         {
    137             return NULL;
    138         }
    139     }
    140 }
    141 
    142 //改变一个结点的数据
    143 void change(DList *p, int data,int newdata)
    144 {
    145     if (p->head == NULL || p->tail == NULL)
    146     {
    147         return;
    148     }
    149     //如果只有一个结点
    150     else if (p->head == p->tail)
    151     {
    152         PNODE pl = p->head;
    153         if (pl->data == data)
    154         {
    155             pl->data == newdata;
    156         }
    157     }
    158     //如果大于一个结点
    159     else
    160     {
    161         PNODE pl = p->head;
    162         for (; pl->pNext != p->head; pl = pl->pNext)
    163         {
    164             if (pl->data == data)
    165             {
    166                 pl->data == newdata;
    167             }
    168         }
    169         //尾部补充一个
    170         if (pl->data == data)
    171         {
    172             pl->data == newdata;
    173         }
    174     }
    175 }
    176 
    177 //删除一个结点
    178 void deleteData(DList *p, int data)
    179 {
    180     //先判断只有一个结点的情况
    181     if (p->head == p->tail)
    182     {
    183         if (p->head->data == data)
    184         {
    185             free(p->head);
    186             p->head = NULL;
    187             p->tail = NULL;
    188         }
    189     }
    190     //结点个数大于1
    191     else
    192     {
    193         //备份头结点
    194         PNODE pl = p->head;
    195         //先判断是不是头结点
    196         if (pl->data == data)
    197         {
    198             pl->pNext->pPre = p->tail;
    199             p->tail->pNext = pl->pNext;
    200             p->head = pl->pNext;
    201             free(pl);
    202         }
    203         //如果不是头结点
    204         else
    205         {
    206             //一直从后一个遍历到结束
    207             pl = pl->pNext;
    208             while (pl != p->head)
    209             {
    210                 if (pl->data == data)
    211                 {
    212                     break;
    213                 }
    214                 else
    215                 {
    216                     pl = pl->pNext;
    217                 }
    218             }
    219             //如果找到了
    220             if (pl != p->head)
    221             {
    222                 //如果循环到尾部
    223                 if (pl == p->tail)
    224                 {
    225                     pl->pPre->pNext = p->head;
    226                     p->head->pPre = pl->pPre;
    227 
    228                     p->tail = pl->pPre;
    229                     free(pl);
    230                 }
    231                 //如果在中间
    232                 else
    233                 {
    234                     pl->pNext->pPre = pl->pPre;
    235                     pl->pPre->pNext = pl->pNext;
    236                     free(pl);
    237                 }
    238             }
    239         }
    240     }
    241     
    242 }
    243 
    244 void insert(DList *p, int data, int newdata)
    245 {
    246     PNODE pnew = (PNODE)malloc(sizeof(node));//开辟节点
    247     pnew->data = newdata;
    248     pnew->pNext = NULL;
    249     pnew->pPre = NULL;
    250 
    251     //从头结点开始向后找    
    252     PNODE pl = p->head;
    253     while (pl->pNext != p->head)
    254     {
    255         if (pl->data == data)
    256         {
    257             break;
    258         }
    259         else
    260         {
    261             pl = pl->pNext;
    262         }
    263     }
    264     //后面插入
    265     //无论最后一个结点是不是要找的结点都插在后面
    266     //只有一个结点,插在尾部
    267     if (pl == p->head && p->tail == pl)
    268     {
    269         pnew->pPre = pnew->pNext = p->head;
    270         p->head->pNext = p->head->pPre = pnew;
    271         p->tail = pnew;
    272     }
    273     //如果遍历到尾部结点
    274     else if (pl == p->tail && pl != p->head)
    275     {
    276         pnew->pNext = p->head;
    277         pnew->pPre = p->tail;
    278 
    279         p->tail->pNext = pnew;
    280         p->head->pPre = pnew;
    281 
    282         p->tail = pnew;
    283     }
    284     //如果不在尾结点
    285     else
    286     {
    287         pnew->pPre = pl;
    288         pnew->pNext = pl->pNext;
    289         
    290         pl->pNext->pPre = pnew;
    291         pl->pNext = pnew;
    292     }
    293 }
    294 
    295 
    296 //显示链表的数据
    297 void show(DList *p)
    298 {
    299 
    300     if (p->head == NULL || p->tail == NULL)
    301     {
    302         return;
    303     }
    304     else if (p->head == p->tail)
    305     {
    306         PNODE pl = p->head;
    307         printf("%d,(CurAddr)%p,(PreAddr)%p,(NextAddr)%p
    ", pl->data, pl, pl->pPre, pl->pNext);
    308     }
    309     else
    310     {
    311         PNODE pl = p->head;
    312         for (; pl->pNext != p->head; pl = pl->pNext)
    313         {
    314             printf("%d,(CurAddr)%p,(PreAddr)%p,(NextAddr)%p
    ", pl->data, pl, pl->pPre, pl->pNext);
    315         }
    316         //尾部补充一个
    317         printf("%d,(CurAddr)%p,(PreAddr)%p,(NextAddr)%p
    ", pl->data, pl, pl->pPre, pl->pNext);
    318     }
    319 }
    320 
    321 
    322 
    323 void main()
    324 {
    325     DList dlist;
    326     init(&dlist);
    327 
    328     for (int i = 0; i < 5; i++)
    329     {
    330         addDataHead(&dlist,i);
    331         //addDataBack(&dlist, i);
    332         printf("
    
    ");
    333         show(&dlist);
    334     }
    335 
    336     //查询数据并修改
    337     PNODE px = find(&dlist, 3);
    338     px->data = 19;
    339     printf("
    
    ");
    340 
    341     //后插数据
    342     insert(&dlist, 1, 100);
    343     printf("
    
    ");
    344     show(&dlist);
    345 
    346     //删除数据
    347     deleteData(&dlist, 4);
    348     printf("
    
    ");
    349     show(&dlist);
    350     system("pause");
    351 }
  • 相关阅读:
    Python 描述符(descriptor) 杂记
    Celery 使用简介
    异步任务神器 Celery 简明笔记
    高性能框架gevent和gunicorn在web上的应用及性能测试
    Flask + Gunicorn + Nginx 部署
    Mysql查看最大连接数和修改最大连接数
    配置 influxDB 鉴权及 HTTP API 写数据的方法
    Java 字符串拼接 五种方法的性能比较分析 从执行100次到90万次
    linux端口开放指定端口的两种方法
    java自带的监控工具VisualVM一
  • 原文地址:https://www.cnblogs.com/xiaochi/p/8405077.html
Copyright © 2020-2023  润新知