zoukankan      html  css  js  c++  java
  • 手把手写数据结构之单向循环链表操作

      1 /**************************头文件***************************/
      2 
      3 #ifndef _LINK_H_
      4 #define _LINK_H_
      5 
      6 #include <stdio.h>
      7 #include <stdlib.h>
      8 #include <time.h>
      9 
     10 
     11 #define Test(arg)     if(arg == NULL){
     12         printf("Invalid arg!
    ");
     13         return -1;
     14     }
     15 
     16 /*单链表的实现可以各有不同,只要该实现,符合链表的定义即可。
     17  *单链表最重要的数据结构是元素结点,
     18  *最重要的操作是插入结点,删除结点和遍历。
     19  *其它的操作基本上是这3个操作的组合,依据具体的要求而定。
     20 */
     21 
     22 /*切记作为非空循环链表: 恒成立(tail->next == head)*/
     23 
     24 /*******************************************
     25 *单向循环链表结点信息
     26 *
     27 *数据域:    可以是普通类型,也可以是封装类型
     28 *指针域:    next指针
     29 *
     30 *********************************************/
     31 typedef struct node
     32 {
     33     int num;            //数据域
     34     struct node *next;    //指针域
     35 }NODE;
     36 
     37 /*******************************************
     38 *单向循环链表信息
     39 *
     40 *链表的属性信息: 链表的作用描述,链表当前节点个数等等
     41 *指针信息:        一般必须有表头指针,也可以有尾结点指针
     42 *
     43 *********************************************/
     44 typedef struct list_info
     45 {
     46     int max;            //结点个数
     47     NODE *head;            //头结点指针
     48     NODE *tail;            //尾结点指针
     49 }LIST_INFO;
     50 
     51 
     52 /*******************************************
     53 *Des:    单向循环链表初始化操作,即创建链表
     54 *Ret:    成功返回0,失败返回-1
     55 *********************************************/
     56 int Init_Link(LIST_INFO **plist);
     57 
     58 
     59 /*******************************************
     60 *Des:    判断链表是否为空
     61 *Ret:    真空返回1,假空返回0
     62 *********************************************/
     63 int IS_Empty_Link(LIST_INFO *plist);
     64 
     65 /*******************************************
     66 *Des:    清空链表
     67 *Ret:    成功返回0, 失败返回-1
     68 *********************************************/
     69 int Empty_Link(LIST_INFO *plist);
     70 
     71 /*******************************************
     72 *Des:    插入结点到表头(与在表尾操作类似)
     73 *Ret:    成功返回0,失败返回-1
     74 *********************************************/
     75 int Insert_to_Head(LIST_INFO *plist, int num);
     76 
     77 /*******************************************
     78 *Des:    删除数据域为num的结点
     79 *Ret:    成功返回0,失败返回-1
     80 *********************************************/
     81 int Delete_Node_Num(LIST_INFO *plist, int num);
     82 
     83 
     84 
     85 /*******************************************
     86 *Des:    销毁链表
     87 *Ret:    成功返回0,失败返回-1
     88 *********************************************/
     89 int Destory_Link(LIST_INFO **plist);
     90 
     91 /*******************************************
     92 *Des:    遍历链表
     93 *Ret:    成功返回0,失败返回-1
     94 *********************************************/
     95 int Traverse_Link(LIST_INFO *plist);
     96 
     97 #endif
     98 
     99 
    100 
    101 /*************************循环链表API接口函数实现*************************/
    102 
    103 
    104 #include "sc_link.h"
    105 
    106 /*******************************************
    107 *Des:    创建结点
    108 *Ret:    成功返回结点,失败返回NULL
    109 *********************************************/
    110 static NODE *__Create_Node__(int num)
    111 {
    112     NODE *new_node = (NODE *)malloc(sizeof(NODE));
    113     if(NULL == new_node)
    114     {
    115         perror("Create Node");
    116         return NULL;
    117     }
    118 
    119     new_node->next = NULL;
    120     new_node->num = num;
    121 
    122     return new_node;
    123 }
    124 
    125 
    126 /*******************************************
    127 *Des:    单向循环链表初始化操作,即创建链表
    128 *Ret:    成功返回0,失败返回-1
    129 *********************************************/
    130 int Init_Link(LIST_INFO ** plist)
    131 {
    132     Test(plist);//参数有效性检测
    133 
    134     //创建链表
    135     *plist = (LIST_INFO *)malloc(sizeof(LIST_INFO));
    136     if(NULL == *plist)
    137     {
    138         perror("Create List");
    139         return -1;
    140     }
    141 
    142     //初始化链表
    143     (*plist)->head = (*plist)->tail = NULL;
    144     (*plist)->max = 0;
    145 
    146     return 0;
    147 }
    148 
    149 /*******************************************
    150 *Des:    判断链表是否为空
    151 *Ret:    真空返回1,假空返回0
    152 *********************************************/
    153 int IS_Empty_Link(LIST_INFO *plist)
    154 {
    155     return (NULL == plist->head);
    156 }
    157 
    158 /*******************************************
    159 *Des:    清空链表
    160 *Ret:    成功返回0, 失败返回-1
    161 *********************************************/
    162 int Empty_Link(LIST_INFO *plist)
    163 {
    164     Test(plist);//参数有效性检测
    165 
    166     //判断是否已经为空
    167     if(IS_Empty_Link(plist))
    168     {
    169         printf("The list is empty!
    ");
    170         return -1;
    171     }
    172 
    173     NODE *fnode = NULL, *pnode = plist->head;
    174     while(plist->tail != pnode)
    175     {
    176         fnode = pnode;
    177         pnode = pnode->next;
    178         free(fnode);
    179     }
    180     fnode = plist->tail;
    181     free(fnode);
    182 
    183     plist->head = plist->tail = NULL;
    184     plist->max = 0;
    185     
    186     return 0;
    187 }
    188 
    189 /*******************************************
    190 *Des:    销毁链表
    191 *Ret:    成功返回0,失败返回-1
    192 *********************************************/
    193 int Destory_Link(LIST_INFO **plist) 
    194 {
    195     Test(plist);//函数入口检测
    196 
    197     //清空链表
    198     if(Empty_Link(*plist) < 0)
    199         return -1;
    200 
    201     free(*plist);
    202 
    203     *plist = NULL;
    204 
    205     return 0;
    206 }
    207 
    208 
    209 
    210 /*******************************************
    211 *Des:    插入结点到表头(与在表尾操作类似)
    212 *Ret:    成功返回0,失败返回-1
    213 *********************************************/
    214 int Insert_to_Head(LIST_INFO *plist, int num)
    215 {
    216     Test(plist);//参数有效性检测
    217 
    218     NODE *new_node = __Create_Node__(num);
    219     if(NULL == new_node)
    220         return -1;
    221 
    222     if(IS_Empty_Link(plist))//当链表为空
    223     {
    224         plist->head = plist->tail = new_node;
    225         plist->head->next = plist->tail;
    226         plist->tail->next = plist->head;
    227     }
    228     else
    229     {
    230         plist->tail->next = new_node;
    231         new_node->next = plist->head;
    232         plist->head = new_node;
    233     }
    234 
    235     plist->max++;
    236 
    237     return 0;
    238 }
    239 
    240 /*******************************************
    241 *Des:    删除数据域为num的结点
    242 *Ret:    成功返回0,失败返回-1
    243 *********************************************/
    244 int Delete_Node_Num(LIST_INFO *plist, int num)
    245 {
    246     Test(plist);
    247 
    248     NODE *fnode = NULL, *tmpnode = NULL, *pnode = NULL;
    249 
    250     //判断链表是否为空
    251     if(IS_Empty_Link(plist))
    252     {
    253         printf("The list is empty!
    ");
    254         return -1;
    255     }
    256 
    257     //查找结点是否有符合的
    258     pnode = plist->head;
    259     while(pnode != plist->tail)
    260     {
    261         if(pnode->num == num)
    262             break;
    263         tmpnode = pnode;
    264         pnode = pnode->next;
    265     }
    266     if(pnode == plist->tail)//结束条件为到了链表的尽头
    267     {
    268         if(pnode->num == num)//如果尾结点是的
    269         {
    270             fnode = pnode;
    271             if(plist->max == 1)//只有一个节点
    272             {
    273                 plist->head = plist->tail = NULL;
    274             }
    275             else
    276             {
    277                 tmpnode->next = plist->head;
    278                 plist->tail = tmpnode;
    279             }
    280         }
    281         else
    282         {
    283             printf("Have no such Node!
    ");
    284             return -1;
    285         }
    286     }
    287     else//循环条件因为找到符合的结点而结束的
    288     {
    289         if(NULL == tmpnode)//如果是头结点
    290         {
    291             fnode = plist->head;
    292             plist->tail->next = fnode->next;
    293             plist->head = fnode->next;
    294         }
    295         else
    296         {
    297             fnode = tmpnode->next;
    298             tmpnode->next = fnode->next;
    299         }
    300     }
    301 
    302     free(fnode);
    303     plist->max--;
    304 
    305     return 0;
    306 }
    307 
    308 /*******************************************
    309 *Des:    遍历链表
    310 *Ret:    成功返回0,失败返回-1
    311 *********************************************/
    312 int Traverse_Link(LIST_INFO *plist)
    313 {
    314     Test(plist);//参数有效性检测
    315     
    316     if(IS_Empty_Link(plist))//判断链表是否为空
    317     {
    318         printf("The list is empty!
    ");
    319         return -1;
    320     }
    321 
    322     printf("The count of Node: %d
    ", plist->max);
    323     NODE *pnode = plist->head;
    324     while(pnode != plist->tail)
    325     {
    326         printf("%-5d", pnode->num);
    327         pnode =pnode->next;
    328     }
    329     printf("%-5d", pnode->num);
    330 
    331     printf("
    
    ");
    332 
    333     return 0;
    334 }
    335 
    336 
    337 
    338 /**************************测试代码***************************/
    339 
    340 #include "sc_link.h"
    341 #define RANDOM rand()%10
    342 
    343 int main()
    344 {
    345 
    346     srand(time(NULL));
    347     
    348     int i, num;
    349     LIST_INFO *plist = NULL;
    350 
    351     //初始化链表操作
    352     Init_Link(&plist);
    353 
    354     //添加结点
    355     //for(i = 0; i < 5; i++)
    356     //{
    357     //    num = RANDOM;
    358     //    printf("%5d", num);
    359         Insert_to_Head(plist, 8);
    360     //}
    361     printf("
    
    ");
    362 
    363     Traverse_Link(plist);
    364 
    365     //清空链表操作
    366     //Empty_Link(plist);
    367 
    368     Delete_Node_Num(plist, 8);
    369 
    370     Traverse_Link(plist);
    371 
    372     return 0;
    373 }
  • 相关阅读:
    JAVA爬虫实践(实践三:爬虫框架webMagic和csdnBlog爬虫)
    JAVA爬虫实践(实践一:知乎)
    JAVA爬虫实践(实践二:博客园)
    SpringMVC框架学习笔记(5)——数据处理
    SpringMVC框架学习笔记——各种异常、报错解决
    SpringMVC框架学习笔记(1)——HelloWorld
    angularjs springMVC 交互
    存储过程存放数据方式
    存储过程总结
    cssie7.0兼容
  • 原文地址:https://www.cnblogs.com/xuyh/p/3232671.html
Copyright © 2011-2022 走看看