• C/C++实现单向循环链表(尾指针,带头尾节点)


      C语言实现单向循环链表,主要功能为空链表创建,链表初始化(头插法,尾插法),链表元素读取,按位置插入,(有序链表)按值插入,按位置删除,按值删除,清空链表,销毁链表。

      单向循环链表和单向链表的区别:(1)单向链表为头指针,循环链表为尾指针,头指针指向头结点,尾指针指向终端结点;(2)为统一方便操作,单向链表设置头结点,单向循环链表设置头结点和尾结点;(3)设置尾结点后,尾指针指向尾结点,插入,删除等操作不用移动尾指针。

      关键思路:创建头结点和尾结点。

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 
      4 typedef struct Node{
      5     int data;
      6     struct Node *next;
      7 }Node;
      8 
      9 //空循环链表创建
     10 //创建头结点和尾结点
     11 //链表尾指针指向尾结点,尾结点指向头结点,头结点指向尾结点
     12 void iniCList(Node **CListTail){
     13     *CListTail = (Node *)malloc(sizeof(Node));
     14     Node *CListHead = (Node *)malloc(sizeof(Node));
     15     if (NULL == *CListTail || NULL == CListHead){
     16         exit(0);
     17     }
     18 
     19     (*CListTail)->next = CListHead;
     20     CListHead->next = *CListTail;
     21 }
     22 
     23 //循环链表初始化(头插法)
     24 void iniCListHead(Node **CListTail, int n){
     25     //创建头尾结点
     26     *CListTail = (Node *)malloc(sizeof(Node));
     27     Node *CListHead = (Node *)malloc(sizeof(Node));
     28     if (NULL == *CListTail || NULL == CListHead){
     29         exit(0);
     30     }
     31 
     32     (*CListTail)->next = CListHead;
     33     CListHead->next = *CListTail;
     34 
     35     int i = 0;
     36     while (i < n){
     37 
     38         Node *tmpNode = (Node *)malloc(sizeof(Node));
     39         if (NULL == tmpNode){
     40             exit(0);
     41         }
     42         tmpNode->data = i;
     43         tmpNode->next = CListHead->next;
     44         CListHead->next = tmpNode;
     45         ++i;
     46     }
     47 }
     48 
     49 //循环链表初始化(尾插法)
     50 void iniCListTail(Node **CListTail, int n){
     51     //创建头尾结点
     52     *CListTail = (Node *)malloc(sizeof(Node));
     53     Node *CListHead = (Node *)malloc(sizeof(Node));
     54     if (NULL == *CListTail || NULL == CListHead){
     55         exit(0);
     56     }
     57 
     58     (*CListTail)->next = CListHead;
     59     CListHead->next = *CListTail;
     60 
     61     Node *pCurrent = CListHead;
     62 
     63     int i = 0; 
     64     while (i < n){
     65         Node *tmpNode = (Node *)malloc(sizeof(Node));
     66         if (NULL == tmpNode){
     67             exit(0);
     68         }
     69         tmpNode->data = i;
     70         tmpNode->next = *CListTail;
     71         pCurrent->next = tmpNode;
     72         pCurrent = tmpNode;
     73 
     74         ++i;
     75     }
     76 }
     77 
     78 //循环链表按位置插入
     79 void insertCListPos(Node *CList, int pos, int val){
     80 
     81     Node *pCurrent = CList->next; //指向头结点
     82     int i = 1;
     83     while (pCurrent != CList && i < pos){
     84         pCurrent = pCurrent->next;
     85         ++i;
     86     }
     87 
     88     Node *tmpNode = (Node *)malloc(sizeof(Node));
     89     if (NULL == tmpNode){
     90         exit(0);
     91     }
     92     tmpNode->data = val;
     93     tmpNode->next = pCurrent->next;
     94     pCurrent->next = tmpNode;
     95 
     96 }
     97 
     98 //有序循环链表,按值插入
     99 void insertCListValue(Node *CList, int val){
    100     Node *pCur = CList->next->next;
    101     Node *pPer = CList->next;
    102 
    103     while (pCur != CList && pCur->data < val){
    104         pPer = pCur;
    105         pCur = pCur->next;
    106     }
    107 
    108     Node *tmpNode = (Node *)malloc(sizeof(Node));
    109     if (NULL == tmpNode){
    110         exit(0);
    111     }
    112     tmpNode->data = val;
    113     tmpNode->next = pPer->next;
    114     pPer->next = tmpNode;
    115 }
    116 
    117 //循环链表,按位置删除
    118 void deleteCListPos(Node *CList, int pos){
    119     Node *pCur = CList->next;
    120     
    121     int i = 1;
    122     while (pCur != CList && i < pos){
    123         pCur = pCur->next;
    124         ++i;
    125     }
    126 
    127     Node *tmpNode = pCur->next;
    128     pCur->next = tmpNode->next;
    129     free(tmpNode);
    130 }
    131 
    132 //循环链表,按值删除
    133 //删除空链表为出问题
    134 void deleteCListValue(Node *CList, int val){
    135     Node *pCur = CList->next->next;
    136     Node *pPer = CList->next;
    137 
    138     while (pCur != CList && pCur->data != val){
    139         pPer = pCur;
    140         pCur = pCur->next;
    141     }
    142     if (pCur == CList)
    143         return;
    144     else{
    145         pPer->next = pCur->next;
    146         free(pCur);
    147     }
    148 }
    149 
    150 //循环链表,清空链表
    151 void claerCList(Node *CList){
    152     Node *p = CList->next->next;
    153     Node *q = NULL;
    154 
    155     while (p != CList){ //到达表尾
    156         q = p->next;
    157         free(p);
    158         p = q;
    159     }
    160 
    161     CList->next = CList; //将头结点指向尾结点
    162 }
    163 
    164 //循环链表,销毁链表
    165 void destoryCList(Node **CList){
    166     Node *p = (*CList)->next;
    167     Node *q = NULL;
    168 
    169     while (p != (*CList)->next){ //到达表头
    170         q = p->next;
    171         free(p);
    172         p = q;
    173     }
    174 
    175     *CList = NULL;
    176 }
    177 
    178 //获取元素
    179 void getCList(Node *CList, int pos, int *val){
    180     Node *pCur = CList->next->next;
    181     int i = 1;
    182     while (pCur != CList && i < pos){
    183         pCur = pCur->next;
    184         ++i;
    185     }
    186 
    187     *val = pCur->data;
    188 }
    189 //遍历输出元素
    190 void printCList(Node *CList){
    191     Node * tmpNode = CList->next->next;
    192     while (tmpNode != CList){ //到达表尾
    193         printf("%d
    ", tmpNode->data);
    194         tmpNode = tmpNode->next;
    195     }
    196 }
    197 
    198 
    199 int main(){
    200     Node *CList = NULL;
    201     //iniCListHead(&CList, 8);
    202     //iniCList(&CList);
    203     iniCListTail(&CList, 8);
    204 
    205     //insertCListPos(CList, 1, 2);
    206     //insertCListPos(CList, 2, 4);
    207     //insertCListPos(CList, 3, 6);
    208     //
    209     //insertCListValue(CList, 1);
    210     //
    211     //deleteCListPos(CList, 3);
    212     //
    213     //deleteCListValue(CList, 6);
    214 
    215     //claerCList(CList);
    216 
    217     int a = 0;
    218     getCList(CList, 2, &a);
    219     printf("%d
    ", a);
    220 
    221     printCList(CList);
    222 
    223     printf("%d
    ", CList);
    224     destoryCList(&CList);
    225     printf("%d
    ", CList);
    226 
    227     system("pause");
    228     return 0;
    229 }
    C语言完整代码

      通过C++实现C语言的链表,主要区别:(1)struct可以不通过typedef,直接使用Node;(2)将malloc和free更换为new和delete

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 
      4 struct Node{
      5     int data;
      6     struct Node *next;
      7 };
      8 
      9 //空循环链表创建
     10 //创建头结点和尾结点
     11 //链表尾指针指向尾结点,尾结点指向头结点,头结点指向尾结点
     12 void iniCList(Node **CListTail){
     13     *CListTail = new Node;
     14     Node *CListHead = new Node;
     15 
     16     (*CListTail)->next = CListHead;
     17     CListHead->next = *CListTail;
     18 }
     19 
     20 //循环链表初始化(头插法)
     21 void iniCListHead(Node **CListTail, int n){
     22     //创建头尾结点
     23     *CListTail = new Node;
     24     Node *CListHead = new Node;
     25 
     26     (*CListTail)->next = CListHead;
     27     CListHead->next = *CListTail;
     28 
     29     int i = 0;
     30     while (i < n){
     31         Node *tmpNode = new Node;
     32 
     33         tmpNode->data = i;
     34         tmpNode->next = CListHead->next;
     35         CListHead->next = tmpNode;
     36         ++i;
     37     }
     38 }
     39 
     40 //循环链表初始化(尾插法)
     41 void iniCListTail(Node **CListTail, int n){
     42     //创建头尾结点
     43     *CListTail = new Node;
     44     Node *CListHead = new Node;
     45 
     46     (*CListTail)->next = CListHead;
     47     CListHead->next = *CListTail;
     48 
     49     Node *pCurrent = CListHead;
     50 
     51     int i = 0;
     52     while (i < n){
     53         Node *tmpNode = new Node;
     54 
     55         tmpNode->data = i;
     56         tmpNode->next = *CListTail;
     57         pCurrent->next = tmpNode;
     58         pCurrent = tmpNode;
     59 
     60         ++i;
     61     }
     62 }
     63 
     64 //循环链表按位置插入
     65 void insertCListPos(Node *CList, int pos, int val){
     66 
     67     Node *pCurrent = CList->next; //指向头结点
     68     int i = 1;
     69     while (pCurrent != CList && i < pos){
     70         pCurrent = pCurrent->next;
     71         ++i;
     72     }
     73 
     74     Node *tmpNode = new Node;
     75 
     76     tmpNode->data = val;
     77     tmpNode->next = pCurrent->next;
     78     pCurrent->next = tmpNode;
     79 
     80 }
     81 
     82 //有序循环链表,按值插入
     83 void insertCListValue(Node *CList, int val){
     84     Node *pCur = CList->next->next;
     85     Node *pPer = CList->next;
     86 
     87     while (pCur != CList && pCur->data < val){
     88         pPer = pCur;
     89         pCur = pCur->next;
     90     }
     91 
     92     Node *tmpNode = new Node;
     93 
     94     tmpNode->data = val;
     95     tmpNode->next = pPer->next;
     96     pPer->next = tmpNode;
     97 }
     98 
     99 //循环链表,按位置删除
    100 void deleteCListPos(Node *CList, int pos){
    101     Node *pCur = CList->next;
    102 
    103     int i = 1;
    104     while (pCur != CList && i < pos){
    105         pCur = pCur->next;
    106         ++i;
    107     }
    108 
    109     Node *tmpNode = pCur->next;
    110     pCur->next = tmpNode->next;
    111     delete tmpNode;
    112 }
    113 
    114 //循环链表,按值删除
    115 //删除空链表为出问题
    116 void deleteCListValue(Node *CList, int val){
    117     Node *pCur = CList->next->next;
    118     Node *pPer = CList->next;
    119 
    120     while (pCur != CList && pCur->data != val){
    121         pPer = pCur;
    122         pCur = pCur->next;
    123     }
    124     if (pCur == CList)
    125         return;
    126     else{
    127         pPer->next = pCur->next;
    128         delete pCur;
    129     }
    130 }
    131 
    132 //循环链表,清空链表
    133 void claerCList(Node *CList){
    134     Node *p = CList->next->next;
    135     Node *q = NULL;
    136 
    137     while (p != CList){ //到达表尾
    138         q = p->next;
    139         delete p;
    140         p = q;
    141     }
    142 
    143     CList->next = CList; //将头结点指向尾结点
    144 }
    145 
    146 //循环链表,销毁链表
    147 void destoryCList(Node **CList){
    148     Node *p = (*CList)->next;
    149     Node *q = NULL;
    150 
    151     while (p != (*CList)->next){ //到达表头
    152         q = p->next;
    153         delete p;
    154         p = q;
    155     }
    156 
    157     *CList = NULL;
    158 }
    159 
    160 //获取元素
    161 void getCList(Node *CList, int pos, int *val){
    162     Node *pCur = CList->next->next;
    163     int i = 1;
    164     while (pCur != CList && i < pos){
    165         pCur = pCur->next;
    166         ++i;
    167     }
    168 
    169     *val = pCur->data;
    170 }
    171 //遍历输出元素
    172 void printCList(Node *CList){
    173     Node * tmpNode = CList->next->next;
    174     while (tmpNode != CList){ //到达表尾
    175         printf("%d
    ", tmpNode->data);
    176         tmpNode = tmpNode->next;
    177     }
    178 }
    179 
    180 
    181 int main(){
    182     Node *CList = NULL;
    183     //iniCListHead(&CList, 8);
    184     //iniCList(&CList);
    185     iniCListTail(&CList, 8);
    186 
    187     //insertCListPos(CList, 1, 2);
    188     //insertCListPos(CList, 2, 4);
    189     //insertCListPos(CList, 3, 6);
    190     //
    191     //insertCListValue(CList, 1);
    192     //
    193     //deleteCListPos(CList, 3);
    194     //
    195     //deleteCListValue(CList, 6);
    196 
    197     //claerCList(CList);
    198 
    199     int a = 0;
    200     getCList(CList, 2, &a);
    201     printf("%d
    ", a);
    202 
    203     printCList(CList);
    204 
    205     printf("%d
    ", CList);
    206     destoryCList(&CList);
    207     printf("%d
    ", CList);
    208 
    209     system("pause");
    210     return 0;
    211 }
    C++完整代码

    单向循环链表

       注意:(1)单向循环链表销毁时,需要将头结点和尾结点删除;(2)单向循环链表插入,删除,遍历,清空链表时,条件从头结点或第一节点始,判断指针是否达到尾结点;(3)清空链表时,最后将头结点指向尾结点;(4)销毁链表时,条件从头结点始,判断条件为指针是否到达头结点,最后将指针置空。

    -------------------------------------------------------------------------------------------------------------

    如果上面的资料对你有启发,麻烦点个推荐,让更多人的人看到哦。

    关注公众号【两猿社】,懂点互联网,懂点IC的程序猿,带你丰富项目经验哦。

  • 相关阅读:
    Redis持久化
    Redis进阶——事务、TTL、排序、消息通知、管道
    行为设计模式
    Redis数据类型
    ASP.NET并发处理
    c# 泛型有什么作用?
    IBatisNet 升级到 .Net Framework 4.0 时发现 IBatisNet 一小BUG
    【Python3】用for循环和while循环分别打印出如下格式“九九乘法表”
    Visual Studio 2010 SP1 WPF程序属性重命名BUG,小心!
    为什么用SOA架构?
  • 原文地址:https://www.cnblogs.com/qinguoyi/p/10429632.html
Copyright © 2020-2023  润新知