zoukankan      html  css  js  c++  java
  • 数据结构之链表

    1:有头节点、单向、不循环链表

    对于这种有头节点的单向不循环链表插入数据如下图:

    1)头部插入

     

    2)尾部插入

    代码如下 :

      1   #include "stdafx.h"
      2   #include<iostream>
      3   
      4   using namespace std;
      5   
      6   typedef int DATA;
      7   typedef struct node* LIST;
      8   
      9   struct node
     10   {
     11       DATA data;
     12       struct node* next; //指向下一个节点的指针
     13   };
     14   
     15   //创建头节点
     16   LIST ListCreate()
     17   {
     18       struct node* head = (struct node*) malloc(sizeof(*head));
     19       if (head == NULL)
     20       {
     21           return NULL;
     22       }
     23       //这个时候只有头节点,head->next = null;数据为空
     24       head->next = NULL;
     25       //返回指向头节点的头指针
     26       return head; 
     27   }
     28   
     29   //判断一个链表是否是空链表
     30   int ListIsEmpty( LIST l)
     31   {
     32       return l->next == NULL;
     33   }
     34   
     35   //判断是不是链表的最后一个元素
     36   int ListIsLast(LIST l, struct node* p)
     37   {
     38       return p->next == NULL;
     39   }
     40   
     41   //插入链表元素 其实这个地方主要分为尾部插入,还是头部插入
     42   int ListInsert(LIST l, struct node* prev,const DATA *data ) 
     43   {
     44       struct node* cur = (struct node*)malloc(sizeof(*cur));
     45       if (cur == NULL)
     46       {
     47           return -1;
     48       }
     49       cur->data = *data;
     50       cur->next = prev->next;
     51       prev->next = cur;
     52       return 0;
     53   }
     54   
     55   int ListInsertHead(LIST l, const DATA* data)
     56   {
     57       return ListInsert(l,l,data);
     58   }
     59   
     60   int ListInsertTail( LIST l, const DATA* data )
     61   {
     62       struct node* tail = l;
     63       for (; tail->next != NULL; tail = tail->next); //空循环,找到尾节点
     64       return ListInsert(l,tail,data);
     65   }
     66   
     67   //查找
     68   struct node* ListFind(LIST l,const DATA* data )
     69   {
     70       struct node* p = l->next; //要考虑到空链表的情况就是p != null 从头节点的next开始查找,是因为头节点是不存放数据的,所以从头节点开始查找是没有意义的。
     71       for (; p != NULL && p->data != *data; p = p->next);
     72       return p;
     73   }
     74   
     75   //查找前驱节点
     76   struct node* ListFindPrev(LIST l, const DATA* data)
     77   {
     78       struct node* p = l; //查找前驱的话不能再指向头节点的下一个节点了,如果是一个空链表的话,就没有意义了,
     79   
     80       for (;p->next != NULL && p->next->data != *data; p = p->next);
     81   
     82       return p;
     83   }
     84   
     85   //删除链表元素
     86   int ListDelete(LIST l, const DATA* data)
     87   {
     88       //头节点是不能删除的
     89       struct node* prev = ListFindPrev(l,data); //这里就能处理到找不到或者是头节点的情况
     90       if (!ListIsLast(l, prev)) 
     91       {
     92           struct node *q = prev->next; //即q就是要删除的元素;
     93           prev->next = q->next;
     94           free(q);
     95           return 0;
     96       }
     97       return -1;
     98   }
     99   
    100  //打印列表
    101  void ListDisplay(LIST l)
    102  {
    103      struct node * p = l->next;
    104      while (p != NULL )
    105      {
    106          printf("%d  ", p->data);
    107          p = p->next;
    108      }
    109      printf("
    ");
    110  }
    111  
    112  //销毁链表
    113  void ListDispose(LIST l)
    114  {
    115      struct node *p = l->next;
    116      struct node* q;
    117      while (p != NULL)
    118      {
    119          q = p;
    120          p = p->next;
    121          free(q);
    122      }
    123  
    124      free(l);
    125  }
    126  
    127  int main()
    128  {
    129      int i;
    130      DATA x;
    131  
    132      LIST head = ListCreate();
    133      if (head == NULL)
    134          return -1;
    135  
    136      //插入
    137      for (i = 0; i < 6; i++)
    138      {
    139          x = i + 1;
    140          //ListInsertHead(head,&x);
    141          ListInsertTail(head,&x);
    142      }
    143      printf("链表里面的元素:: ");
    144      ListDisplay(head);
    145  
    146      printf("从链表里面查找元素3
    ");
    147      DATA y = 3;
    148      //查找
    149      struct node* p = ListFind(head,&y);
    150      if (p == NULL)
    151          printf("not find!!!
    ");
    152      else
    153          printf("data = %d
    ", p->data);
    154  
    155      printf("从链表里面删除元素3
    ");
    156      ListDelete(head,&y);
    157      ListDisplay(head);
    158  
    159      //
    160      printf("销毁链表
    ");
    161      ListDispose(head);
    162      system("pause");
    163  
    164      return 0;
    165  }
    View Code

     2:有头节点、单向、循环链表

     1):头部插入

    2)尾部插入

    代码如下:

      1 // test04.cpp : Defines the entry point for the console application.
      2 //有头节点、单向、循环链表
      3 
      4 #include "stdafx.h"
      5 #include<iostream>
      6 
      7 using namespace std;
      8 
      9 struct node;
     10 typedef int DATA;
     11 typedef struct node* LIST;
     12 
     13 struct node
     14 {
     15     DATA data;
     16     struct node* next;
     17 };
     18 
     19 //创建头节点
     20 LIST ListCreate()
     21 {
     22     LIST head = (struct node*)malloc(sizeof(*head));
     23     if ( head == NULL )
     24     {
     25         return NULL;
     26     }
     27 
     28     head->next = head;
     29 
     30     return head;
     31 }
     32 
     33 //插入
     34 int ListInsert( LIST l, struct node* position, const DATA* data )
     35 {
     36     struct node* cur = (struct node*)malloc(sizeof(*cur));
     37     if ( cur == NULL )
     38     {
     39         return 0;
     40     }
     41     cur->data = *data;
     42     cur->next = position->next;
     43     position->next = cur;
     44 
     45     return 0;
     46 }
     47 
     48 //头部插入
     49 int ListHeadInsert(LIST l, const DATA* data)
     50 {
     51     return ListInsert(l,l,data);
     52 }
     53 
     54 //尾部插入
     55 int ListTailHead(LIST l, const DATA* data )
     56 {
     57     struct node* tail = l;
     58     for (; tail->next != l; tail = tail->next);
     59     return ListInsert(l,tail,data);
     60 }
     61 
     62 //查找
     63 struct node* ListFind( LIST l, const DATA* data )
     64 {
     65     struct node* p = l->next;
     66     for (; p != l && p->data != *data; p = p->next);
     67     return p;
     68 }
     69 
     70 struct node* ListFindPrev(LIST l, const DATA* data)
     71 {
     72     struct node* p = l;
     73     for (; p->next != l && p->next->data != *data; p = p->next);
     74     return p;
     75 }
     76 //删除
     77 int ListDelete( LIST l, const DATA* data )
     78 {
     79     struct node* prev = ListFindPrev( l, data );
     80     if ( prev != l) //不是头节点
     81     {
     82         struct node* q = prev->next;
     83         prev->next = q->next;
     84         free(q);
     85     }
     86     return 0;
     87 }
     88 
     89 //打印出来列表
     90 void ListDisplay(LIST l)
     91 {
     92     struct node* p = l->next;
     93     while (p != l)
     94     {
     95         printf("%d  ",p->data);
     96         p = p->next;
     97     }
     98     printf("
    ");
     99 }
    100 
    101 //消耗链表
    102 void ListDispose(LIST l)
    103 {
    104     struct node* p = l->next;
    105     struct node* q;
    106     while (p != l)
    107     {
    108         q = p;
    109         p = p->next;
    110         free(q);
    111     }
    112     free(l);
    113 }
    114 
    115 int main()
    116 {
    117     int i;
    118     DATA x;
    119     LIST head = NULL;
    120     head = ListCreate();
    121     if (head == NULL)
    122     {
    123         return 0;
    124     }
    125 
    126     for (i = 0; i < 6; i++)
    127     {
    128         x = i + 1;
    129         //ListHeadInsert(head,&x);
    130         ListTailHead(head,&x);
    131     }
    132     //
    133     printf("打印链表::
    ");
    134     ListDisplay(head);
    135 
    136     DATA y = 3;
    137     struct node* p = ListFind(head,&y);
    138     if (p == NULL)
    139         printf("not find!!!!");
    140     else
    141         printf("找到元素%d
    ", p->data);
    142 
    143     //删除元素
    144     printf("删除元素之前,删除的元素是3
    ");
    145     ListDelete(head,&y);
    146     printf("删除元素之后
    ");
    147     ListDisplay(head);
    148 
    149     ListDispose(head);
    150 
    151     system("pause");
    152     return 0;
    153 }
    View Code

    输出如下:

    3:有头节点、双向、循环链表

    1):头部插入

    2):尾部插入

    代码如下:

      1 // test02.cpp : Defines the entry point for the console application.
      2 //
      3 
      4 #include "stdafx.h"
      5 #include<iostream>
      6 
      7 using namespace std;
      8 
      9 typedef struct headnode* LIST;
     10 
     11 typedef void print_s(const void*);
     12 typedef int cmp(const void*, const void*);
     13 
     14 #define HEADINSERT 1
     15 #define TAILINSERT 2
     16 #define NAMESIZE 24
     17 //有头节点、双向、循环链表
     18 typedef struct stuinfo
     19 {
     20     int id;
     21     char name[NAMESIZE];
     22     int math;
     23 } DATA;
     24 
     25 struct listnode
     26 {
     27     void* data;
     28     struct listnode* prev;
     29     struct listnode* next;
     30 };
     31 struct headnode
     32 {
     33     int size;  //指向下面要插入数据的大小
     34     struct listnode head; //指向下一个节点的指针
     35 };
     36 
     37 //创建头节点
     38 LIST ListCreate( int size )
     39 {
     40     LIST handle = (struct headnode*)malloc(sizeof(*handle));
     41     if (handle == NULL)
     42     {
     43         return NULL;
     44     }
     45     handle->size = size;
     46     handle->head.data = NULL;
     47     handle->head.prev = handle->head.next = &handle->head;
     48 
     49     return handle;
     50 }
     51 
     52 //插入链表元素 其实这个地方主要分为尾部插入,还是头部插入
     53 int ListInsert( LIST l,const void *data, int mode ) 
     54 {
     55     struct listnode* cur = (struct listnode*)malloc(sizeof(*cur));
     56     if (cur == NULL)
     57     {
     58         return -1;
     59     }
     60     cur->data = malloc(l->size);
     61     if (cur->data == NULL)
     62     {
     63         free(cur);
     64         return -1;
     65     }
     66     memcpy(cur->data,data,l->size);
     67     if (mode == HEADINSERT) //首部插入
     68     {
     69         cur->prev = &l->head;
     70         cur->next = l->head.next;
     71         /////
     72         //cur->prev->next = cur;
     73         //cur->next->prev = cur;
     74     }
     75     else if (mode == TAILINSERT)
     76     {
     77         cur->next = &l->head;
     78         cur->prev = l->head.prev;
     79         ///////
     80         //cur->prev->next = cur;
     81         //cur->next->prev = cur; //可以把相同的两句话提取出来
     82     }
     83     else
     84     {
     85         free(cur->data);
     86         free(cur);
     87         return -1;
     88     }
     89     cur->prev->next = cur;
     90     cur->next->prev = cur;
     91 
     92     return 0;
     93 }
     94 
     95 
     96 //查找
     97 struct listnode* ListFind(LIST l,const void* key,cmp* funp)
     98 {
     99     struct listnode* p = l->head.next; //
    100     for (; p != &l->head && funp(key, p->data); p = p->next);
    101 
    102     return p;
    103 }
    104 
    105 //找到指定的元素
    106 void* listfind(LIST l, const void* key, cmp* funp)
    107 {
    108     return ListFind(l,key,funp)->data;
    109 }
    110 
    111 //删除链表元素
    112 int ListDelete(LIST l, const void* key, cmp* funp )
    113 {
    114     //找到指定的元素删除
    115     struct listnode* p = ListFind(l,key,funp);
    116     if ( p == &l->head ) //头节点不会删除掉
    117     {
    118         return 0;
    119     }
    120 
    121     p->prev->next = p->next;
    122     p->next->prev = p->prev;
    123 
    124     free(p->data);
    125     free(p);
    126 
    127     return 0;
    128 }
    129 
    130 //打印链表
    131 void ListDisplay(LIST l, print_s* funp )
    132 {
    133     struct listnode* p = l->head.next;
    134     while (p != &l->head)
    135     {
    136         funp(p->data);
    137         p = p->next;
    138     }
    139 }
    140 
    141 //销毁链表
    142 void ListDispose( LIST l )
    143 {
    144     struct listnode* p = l->head.next;
    145     struct listnode* q;
    146 
    147     while (p != &l->head)
    148     {
    149         q = p;
    150         p = p->next;
    151 
    152         free(q->data);
    153         free(q);
    154     }
    155     free(l);
    156 }
    157 
    158 static int IdCmp(const void* key, const void* data)
    159 {
    160     const int *id = (const int*)key;
    161     const DATA* stup = (const DATA*)data;
    162 
    163     return (*id - stup->id);
    164 }
    165 
    166 static int NameCmp(const void* key, const void* data )
    167 {
    168     const char* name = (const char*)key;
    169     const DATA* stup = (const DATA*)data;
    170 
    171     return strcmp(name,stup->name);
    172 }
    173 
    174 static void print(const void* data)
    175 {
    176     const DATA* stup = (const DATA*)data;
    177     printf(" id::%d    name::%s   math::%d
    ",stup->id, stup->name, stup->math);
    178 
    179 }
    180 
    181 int main()
    182 {
    183     int i;
    184     int id = 5;
    185     char name[NAMESIZE] = "stu3";
    186     DATA stu;
    187 
    188     LIST handle = NULL;
    189     handle = ListCreate(sizeof(DATA));
    190     if (handle == NULL )
    191         return 0;
    192 
    193     for (i = 0; i < 6; i++ )
    194     {
    195         stu.id = i + 1;
    196         snprintf(stu.name,NAMESIZE,"stu%d",i+1);
    197 
    198         stu.math = 100 - i;
    199         ListInsert(handle,&stu,HEADINSERT);//首部插入
    200     }
    201     printf("打印整个链表
    ");
    202     ListDisplay(handle, print);
    203 
    204     //
    205     printf("从链表查找元素id=5
    
    ");
    206     struct listnode* stup = ListFind(handle,&id,IdCmp);
    207     if (stup == NULL)
    208         printf("not find!!!
    ");
    209     else
    210         print_s(stup);
    211     printf("
    ");
    212 
    213     //删除元素
    214     printf("删除元素之前,删除的元素是id=5
    ");
    215     ListDelete(handle, &id, IdCmp);
    216     printf("删除元素之后
    ");
    217     ListDisplay(handle,print);
    218 
    219     printf("删除元素之前,删除的元素是name=stu3
    ");
    220     ListDelete(handle,name,NameCmp);
    221     printf("删除元素之后
    ");
    222     ListDisplay(handle, print);
    223 
    224     ListDispose(handle);
    225     
    226     system("pause");
    227     return 0;
    228 }
    View Code

    输出的结果为

    4:有头节点、双向、不循环列表

    1)头部插入

    2)尾部插入

    代码如下

      1 // test02.cpp : Defines the entry point for the console application.
      2 //
      3 
      4 #include "stdafx.h"
      5 #include<iostream>
      6 
      7 using namespace std;
      8 
      9 typedef struct headnode* LIST;
     10 
     11 typedef void print_s(const void*);
     12 typedef int cmp(const void*, const void*);
     13 
     14 #define HEADINSERT 1
     15 #define TAILINSERT 2
     16 #define NAMESIZE 24
     17 //有头节点、双向、不循环链表
     18 typedef struct stuinfo
     19 {
     20     int id;
     21     char name[NAMESIZE];
     22     int math;
     23 } DATA;
     24 
     25 struct listnode
     26 {
     27     void* data;
     28     struct listnode* prev;
     29     struct listnode* next;
     30 };
     31 
     32 struct headnode
     33 {
     34     int size;  //指向下面要插入数据的大小
     35     struct listnode head; //指向下一个节点的指针
     36 };
     37 
     38 //创建头节点
     39 LIST ListCreate( int size )
     40 {
     41     LIST handle = (struct headnode*)malloc(sizeof(*handle));
     42     if (handle == NULL)
     43     {
     44         return NULL;
     45     }
     46     handle->size = size;
     47     handle->head.data = NULL;
     48     handle->head.next = NULL;
     49     handle->head.prev = NULL;
     50 
     51     return handle;
     52 }
     53 
     54 //插入链表元素 其实这个地方主要分为尾部插入,还是头部插入
     55 int ListInsert( LIST l, struct listnode* position, const void *data ) 
     56 {
     57     struct listnode* cur = (struct listnode*)malloc(sizeof(*cur));
     58     if (cur == NULL)
     59     {
     60         return -1;
     61     }
     62     cur->data = malloc(l->size);
     63     if (cur->data == NULL)
     64     {
     65         free(cur);
     66         return -1;
     67     }
     68     memcpy(cur->data, data, l->size);
     69     cur->next = position->next;
     70     cur->prev = position;
     71     if(cur->next != NULL)
     72         cur->next->prev = cur;
     73     cur->prev->next = cur;
     74 
     75     return 0;
     76 }
     77 
     78 int ListHeadInsert( LIST l, const void* data )
     79 {
     80     return ListInsert(l,&l->head,data);
     81 }
     82 
     83 int ListTailInsert(LIST l, const void* data)
     84 {
     85     struct listnode* tail = &l->head;
     86     for (; tail->next != NULL; tail = tail->next);
     87     return ListInsert(l,tail,data);
     88 }
     89 
     90 struct listnode* ListFind(LIST l,const void* key,cmp* funp)
     91 {
     92     struct listnode* p = l->head.next; //
     93     for (; p != NULL && funp(key, p->data); p = p->next);
     94 
     95     return p;
     96 }
     97 
     98 //找到指定的元素
     99 void* listfind(LIST l, const void* key, cmp* funp)
    100 {
    101     return ListFind(l,key,funp)->data;
    102 }
    103 
    104 //删除链表元素
    105 int ListDelete(LIST l, const void* key, cmp* funp )
    106 {
    107     //找到指定的元素删除
    108     struct listnode* p = ListFind(l,key,funp);
    109     if (p == NULL)
    110     {
    111         return 0;
    112     }
    113     const DATA* stup = (const DATA*)(p->data);
    114     cout << stup->name << endl;
    115     if (p->next == NULL)
    116     {
    117         p->prev->next = NULL;
    118     }
    119     else
    120     {
    121         p->prev->next = p->next;
    122         p->next->prev = p->prev;
    123     }
    124     free(p->data);
    125     free(p);
    126     return 0;
    127 }
    128 
    129 //打印链表
    130 void ListDisplay(LIST l, print_s* funp )
    131 {
    132     struct listnode* p = l->head.next;
    133     while ( p != NULL )
    134     {
    135         funp(p->data);
    136         p = p->next;
    137     }
    138 }
    139 
    140 //销毁链表
    141 void ListDispose( LIST l )
    142 {
    143     struct listnode* p = l->head.next;
    144     struct listnode* q;
    145 
    146     while (p != NULL )
    147     {
    148         q = p;
    149         p = p->next;
    150 
    151         free(q->data);
    152         free(q);
    153     }
    154     free(l);
    155 }
    156 
    157 static int IdCmp(const void* key, const void* data)
    158 {
    159     const int *id = (const int*)key;
    160     const DATA* stup = (const DATA*)data;
    161 
    162     return (*id - stup->id);
    163 }
    164 
    165 static int NameCmp(const void* key, const void* data )
    166 {
    167     const char* name = (const char*)key;
    168     const DATA* stup = (const DATA*)data;
    169 
    170     return strcmp(name,stup->name);
    171 }
    172 
    173 static void print(const void* data)
    174 {
    175     const DATA* stup = (const DATA*)data;
    176     printf(" id::%d    name::%s   math::%d
    ",stup->id, stup->name, stup->math);
    177 
    178 }
    179 
    180 int main()
    181 {
    182     int i;
    183     int id = 5;
    184     char name[NAMESIZE] = "stu3";
    185     DATA stu;
    186 
    187     LIST handle = NULL;
    188     handle = ListCreate(sizeof(DATA));
    189     if (handle == NULL )
    190         return 0;
    191 
    192     for (i = 0; i < 6; i++ )
    193     {
    194         stu.id = i + 1;
    195         snprintf(stu.name,NAMESIZE,"stu%d",i+1);
    196 
    197         stu.math = 100 - i;
    198         ListHeadInsert(handle,&stu);//首部插入
    199     }
    200     printf("打印整个链表
    ");
    201     ListDisplay(handle, print);
    202 
    203     //
    204     printf("从链表查找元素id=5
    
    ");
    205     struct listnode* stup = ListFind(handle,&id,IdCmp);
    206     if (stup == NULL)
    207         printf("not find!!!
    ");
    208     else
    209         print(stup->data);
    210     printf("
    ");
    211 
    212     //删除元素
    213     printf("删除元素之前,删除的元素是id=5
    ");
    214     ListDelete(handle, &id, IdCmp);
    215     
    216     
    217     printf("删除元素之后
    ");
    218     ListDisplay(handle,print);
    219 
    220     printf("删除元素之前,删除的元素是name=stu3
    ");
    221     ListDelete(handle,name,NameCmp);
    222     printf("删除元素之后
    ");
    223     ListDisplay(handle, print);
    224 
    225     ListDispose(handle);
    226     
    227     system("pause");
    228     return 0;
    229 }
    View Code

    输出结果为:

  • 相关阅读:
    Ztree下拉框多选
    FullCalendar日程插件
    viscose 前端常用插件
    一些词
    关于require()和export引入依赖的区别
    关于CMD/AMD和Common.js/Sea.js/Require.js
    vue中的双向数据绑定原理简单理解
    Vue-cli简单使用
    webpack简单配置
    vuex基础
  • 原文地址:https://www.cnblogs.com/cxq0017/p/6602758.html
Copyright © 2011-2022 走看看