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 }
原文地址:https://www.cnblogs.com/xiaochi/p/8398184.html