zoukankan      html  css  js  c++  java
  • 17.环形链表,以及用环形链表解决约瑟夫问题

    • 运行结果
    • 链表定义
      typedef struct LinkNode
      {
          int data;
          struct LinkNode *pNext;
      }node,*PNODE;
    • 环形链表尾部添加
       1 //尾部添加
       2 PNODE addback(PNODE phead, int data)
       3 {
       4     //分配空间
       5     PNODE pnew = (PNODE)malloc(sizeof(node));
       6     pnew->data = data;
       7     if (phead == NULL)
       8     {
       9         phead = pnew;
      10         pnew->pNext = phead;
      11     }
      12     else
      13     {
      14         //循环到尾部
      15         PNODE p = phead;
      16         while (p->pNext != phead)
      17         {
      18             p = p->pNext;
      19         }
      20         p->pNext = pnew;
      21         //头尾相连
      22         pnew->pNext = phead;
      23     }
      24 
      25     return phead;
      26 }
    • 环形链表头部添加
       1 //头部添加
       2 PNODE addfront(PNODE phead, int data)
       3 {
       4     //分配空间
       5     PNODE pnew = (PNODE)malloc(sizeof(node));
       6     pnew->data = data;
       7     if (phead == NULL)
       8     {
       9         phead = pnew;
      10         pnew->pNext = phead;
      11     }
      12     else
      13     {
      14         PNODE p = phead;
      15         while (p->pNext != phead)
      16         {
      17             p = p->pNext;
      18         }
      19         //新的结点插在头结点之前
      20         pnew->pNext = phead;
      21         //尾结点指向头结点
      22         p->pNext = pnew;
      23         //新的结点赋值给头结点
      24         phead = pnew;
      25     }
      26     return phead;
      27 }
    • 显示数据
       1 void showall(PNODE phead)
       2 {
       3     if (phead == NULL)
       4     {
       5         return;
       6     }
       7     else if (phead->pNext == phead)
       8     {
       9         printf("%d,%p,%p
      ", phead->data, phead, phead->pNext);
      10     }
      11     else
      12     {
      13         PNODE p = phead;
      14         while (p->pNext != phead)
      15         {
      16             printf("%d,%p,%p
      ", p->data, p, p->pNext);
      17             p = p->pNext;
      18         }
      19         printf("%d,%p,%p
      ", p->data, p, p->pNext);
      20     }
      21 }
    • 查找第一个指定元素
      PNODE findfirst(PNODE phead, int data)
      {
          if (phead == NULL)
          {
              return NULL;
          }
          else if (phead->pNext == phead)
          {
              if (phead->data == data)
              {
                  return phead;
              }
          }
          else
          {
              PNODE p = phead;
              while (p->pNext != phead)
              {
                  if (p->data == data)
                  {
                      return p;
                  }
                  p = p->pNext;
              }
              if (p->data == data)
              {
                  return p;
              }
          }
      
          return NULL;
      }
    • 删除指定结点  判断有几个结点1.1个 2.大于一个(大于一个要判断是否是头结点)
       1 PNODE deletefirst(PNODE phead, int data)
       2 {
       3     //p2用于保存p1的前一个位置
       4     PNODE p1 = NULL;
       5     PNODE p2 = NULL;
       6     p1 = phead;
       7 
       8     //如果只有 一个结点
       9     if (p1->pNext == phead)
      10     {
      11         if (p1->data == data)
      12         {
      13             return NULL;
      14         }
      15         else
      16         {
      17             return phead;
      18          }
      19     }
      20     //如果结点数大于一个
      21     else
      22     {
      23         //先判断头结点,如果头结点是则要删除头结点
      24         if (phead->data == data)
      25         {
      26             //遍历到尾部
      27             while (p1->pNext != phead)
      28             {
      29                 p1 = p1->pNext;
      30             }
      31             //尾部的后一个结点是头结点的后一个结点
      32             p1->pNext = phead->pNext;
      33             //释放头结点
      34             free(phead);
      35             //把尾接电脑的后一个赋给phead
      36             phead = p1->pNext;
      37         }
      38         else
      39         {
      40             //如果头结点不是要删除的结点,则从后一个开始遍历,p2保存p1移动前的位置
      41             p2 = p1;
      42             p1 = phead->pNext;
      43             //遍历到头结点
      44             while (p1 != phead)
      45             {
      46                 if (p1->data == data)
      47                 {
      48                     break;
      49                 }
      50                 else
      51                 {
      52                     p2 = p1;
      53                     p1 = p1->pNext;
      54                 }
      55             }
      56             //判断是否找到结点
      57             if (p1 != phead)
      58             {
      59                 p2->pNext = p1->pNext;
      60                 free(p1);
      61             }
      62         }
      63         return phead;
      64     }    
      65 }
    • 统计有多少个结点
       1 int getnum(PNODE phead)
       2 {
       3     if (phead == NULL)
       4     {
       5         return 0;
       6     }
       7     else
       8     {
       9         int num = 1;
      10         PNODE p = phead;
      11         while (p->pNext != phead)
      12         {
      13             num++;
      14             p = p->pNext;
      15         }
      16         return num;
      17     }
      18 }
    • 在指定元素之后插入一个数据 先判断有几个结点 1.1个  2.大于1个
       1 PNODE insertfirst(PNODE phead, int finddata, int data)
       2 {
       3     PNODE pnew = (PNODE)malloc(sizeof(node));
       4     pnew->data = data;
       5 
       6     if (phead == NULL)
       7     {
       8         return NULL;
       9     }
      10     //如果只有一个结点
      11     else if (phead->pNext == phead)
      12     {
      13         if (phead->data == finddata)
      14         {
      15             phead->pNext = pnew;
      16             pnew->pNext = phead;
      17             return phead;
      18         }
      19     }
      20     else
      21     {
      22         PNODE p = phead;
      23         while (p->pNext != phead)
      24         {
      25             if (p->data == finddata)
      26             {
      27                 pnew->pNext = p->pNext;
      28                 p->pNext = pnew;
      29                 return phead;
      30             }
      31             p = p->pNext;
      32         }
      33         if (p->data == finddata)
      34         {
      35             p->pNext = pnew;
      36             pnew->pNext = phead;
      37             return phead;
      38         }
      39     }
      40 
      41 }
    • 完整代码:
        1 #include <stdio.h>
        2 #include <stdlib.h>
        3 
        4 typedef struct LinkNode
        5 {
        6     int data;
        7     struct LinkNode *pNext;
        8 }node,*PNODE;
        9 
       10 //尾部添加
       11 PNODE addback(PNODE phead, int data)
       12 {
       13     //分配空间
       14     PNODE pnew = (PNODE)malloc(sizeof(node));
       15     pnew->data = data;
       16     if (phead == NULL)
       17     {
       18         phead = pnew;
       19         pnew->pNext = phead;
       20     }
       21     else
       22     {
       23         //循环到尾部
       24         PNODE p = phead;
       25         while (p->pNext != phead)
       26         {
       27             p = p->pNext;
       28         }
       29         p->pNext = pnew;
       30         //头尾相连
       31         pnew->pNext = phead;
       32     }
       33 
       34     return phead;
       35 }
       36 
       37 //头部添加
       38 PNODE addfront(PNODE phead, int data)
       39 {
       40     //分配空间
       41     PNODE pnew = (PNODE)malloc(sizeof(node));
       42     pnew->data = data;
       43     if (phead == NULL)
       44     {
       45         phead = pnew;
       46         pnew->pNext = phead;
       47     }
       48     else
       49     {
       50         PNODE p = phead;
       51         while (p->pNext != phead)
       52         {
       53             p = p->pNext;
       54         }
       55         //新的结点插在头结点之前
       56         pnew->pNext = phead;
       57         //尾结点指向头结点
       58         p->pNext = pnew;
       59         //新的结点赋值给头结点
       60         phead = pnew;
       61     }
       62     return phead;
       63 }
       64 
       65 //显示数据
       66 void showall(PNODE phead)
       67 {
       68     if (phead == NULL)
       69     {
       70         return;
       71     }
       72     else if (phead->pNext == phead)
       73     {
       74         printf("%d,%p,%p
      ", phead->data, phead, phead->pNext);
       75     }
       76     else
       77     {
       78         PNODE p = phead;
       79         while (p->pNext != phead)
       80         {
       81             printf("%d,%p,%p
      ", p->data, p, p->pNext);
       82             p = p->pNext;
       83         }
       84         printf("%d,%p,%p
      ", p->data, p, p->pNext);
       85     }
       86 }
       87 
       88 //查找第一个指定元素
       89 PNODE findfirst(PNODE phead, int data)
       90 {
       91     if (phead == NULL)
       92     {
       93         return NULL;
       94     }
       95     else if (phead->pNext == phead)
       96     {
       97         if (phead->data == data)
       98         {
       99             return phead;
      100         }
      101     }
      102     else
      103     {
      104         PNODE p = phead;
      105         while (p->pNext != phead)
      106         {
      107             if (p->data == data)
      108             {
      109                 return p;
      110             }
      111             p = p->pNext;
      112         }
      113         if (p->data == data)
      114         {
      115             return p;
      116         }
      117     }
      118 
      119     return NULL;
      120 }
      121 
      122 //删除指定结点  判断有几个结点1.1个 2.大于一个(大于一个要判断是否是头结点)
      123 PNODE deletefirst(PNODE phead, int data)
      124 {
      125     //p2用于保存p1的前一个位置
      126     PNODE p1 = NULL;
      127     PNODE p2 = NULL;
      128     p1 = phead;
      129 
      130     //如果只有 一个结点
      131     if (p1->pNext == phead)
      132     {
      133         if (p1->data == data)
      134         {
      135             return NULL;
      136         }
      137         else
      138         {
      139             return phead;
      140          }
      141     }
      142     //如果结点数大于一个
      143     else
      144     {
      145         //先判断头结点,如果头结点是则要删除头结点
      146         if (phead->data == data)
      147         {
      148             //遍历到尾部
      149             while (p1->pNext != phead)
      150             {
      151                 p1 = p1->pNext;
      152             }
      153             //尾部的后一个结点是头结点的后一个结点
      154             p1->pNext = phead->pNext;
      155             //释放头结点
      156             free(phead);
      157             //把尾接电脑的后一个赋给phead
      158             phead = p1->pNext;
      159         }
      160         else
      161         {
      162             //如果头结点不是要删除的结点,则从后一个开始遍历,p2保存p1移动前的位置
      163             p2 = p1;
      164             p1 = phead->pNext;
      165             //遍历到头结点
      166             while (p1 != phead)
      167             {
      168                 if (p1->data == data)
      169                 {
      170                     break;
      171                 }
      172                 else
      173                 {
      174                     p2 = p1;
      175                     p1 = p1->pNext;
      176                 }
      177             }
      178             //判断是否找到结点
      179             if (p1 != phead)
      180             {
      181                 p2->pNext = p1->pNext;
      182                 free(p1);
      183             }
      184         }
      185         return phead;
      186     }    
      187 }
      188 
      189 //统计有多少个结点
      190 int getnum(PNODE phead)
      191 {
      192     if (phead == NULL)
      193     {
      194         return 0;
      195     }
      196     else
      197     {
      198         int num = 1;
      199         PNODE p = phead;
      200         while (p->pNext != phead)
      201         {
      202             num++;
      203             p = p->pNext;
      204         }
      205         return num;
      206     }
      207 }
      208 
      209 //在指定元素之后插入一个数据 先判断有几个结点 1.1个  2.大于1个
      210 PNODE insertfirst(PNODE phead, int finddata, int data)
      211 {
      212     PNODE pnew = (PNODE)malloc(sizeof(node));
      213     pnew->data = data;
      214 
      215     if (phead == NULL)
      216     {
      217         return NULL;
      218     }
      219     //如果只有一个结点
      220     else if (phead->pNext == phead)
      221     {
      222         if (phead->data == finddata)
      223         {
      224             phead->pNext = pnew;
      225             pnew->pNext = phead;
      226             return phead;
      227         }
      228     }
      229     else
      230     {
      231         PNODE p = phead;
      232         while (p->pNext != phead)
      233         {
      234             if (p->data == finddata)
      235             {
      236                 pnew->pNext = p->pNext;
      237                 p->pNext = pnew;
      238                 return phead;
      239             }
      240             p = p->pNext;
      241         }
      242         if (p->data == finddata)
      243         {
      244             p->pNext = pnew;
      245             pnew->pNext = phead;
      246             return phead;
      247         }
      248     }
      249 
      250 }
      251 
      252 void main()
      253 {
      254     PNODE phead = NULL;//头结点
      255 
      256     //添加
      257     for (int i = 1; i <= 10; i++)
      258     {
      259         phead = addback(phead, i);//插入数据
      260     }
      261     showall(phead);
      262     printf("
      
      ");
      263 
      264     ////查找
      265     //PNODE pfind = findfirst(phead, 6);
      266     //pfind->data = 30;
      267 
      268     //删除
      269     /*phead = deletefirst(phead, 1);
      270     showall(phead);
      271     printf("
      
      ");*/
      272 
      273     //printf("结点个数:%d
      ", getnum(phead));
      274 
      275     //指定元素之后插入数据
      276     /*phead = insertfirst(phead, 0,100);
      277     showall(phead);
      278     printf("
      
      ");*/
      279     //p是首地址
      280     PNODE p = phead;
      281     while (getnum(phead) != 1)
      282     {
      283         //往后数四下,然后删除
      284         for (int i = 0; i < 4; i++)
      285         {
      286             p = p->pNext;
      287         }
      288         PNODE pback = p->pNext;//备份p的后一个结点的位置,否则删除后p就被回收,不能再使用了
      289         phead = deletefirst(phead, p->data);
      290         p = pback;
      291 
      292         showall(phead);
      293         printf("
      
      ");
      294     }
      295     system("pause");
      296 }
  • 相关阅读:
    (转载)正向代理与反向代理的区别
    Java设计模式系列之装饰者模式
    工作中使用到的技术和工具分享
    Springboot+mybatis整合
    云计算入门和实践
    tesseract系列(1) -- tesseract用vs编译成库
    nodepad++ 让所有的加号收缩折叠展开的快捷键
    tesseract系列(4) -- tesseract训练问题总结
    tessereact的链接收藏
    菜鸟cmake使用
  • 原文地址:https://www.cnblogs.com/xiaochi/p/8398184.html
Copyright © 2011-2022 走看看