首页 > 代码库 > 9.9 链表及其运用

9.9 链表及其运用

单向链表的实现方法:
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. struct list
  4. {
  5. int data;
  6. struct list *next;
  7. };
  8. /*创建一个节点*/
  9. struct list *create_list()
  10. {
  11. return calloc(sizeof(struct list) , 1);
  12. }
  13. /*打印链表的内容*/
  14. void traverse(struct list *p)
  15. {
  16. //循环实现
  17. //p = p->next;//头节点不需要打印
  18. //while(p)
  19. //{
  20. // printf("%d\n" , p->data);
  21. // p = p->next;
  22. //}
  23. //递归实现
  24. if (p->next == NULL)
  25. return;
  26. printf("%d\n" , p->next->data);
  27. traverse(p->next);
  28. }
  29. /*向链表插入一个节点*/
  30. int insert_list(struct list *p , int n , int data)
  31. {
  32. while (p && n--)
  33. p = p->next;
  34. if (p == NULL)
  35. return 0;
  36. struct list *node = create_list();
  37. node->data = data;
  38. node->next = p->next;
  39. p->next = node;
  40. return 1;
  41. }
  42. /*删除链表的一个节点*/
  43. int delete_list(struct list *p , int n)
  44. {
  45. while (p && n--)
  46. p = p->next;
  47. if (p == NULL)
  48. return 0;
  49. struct list *temp = p->next;
  50. if (temp == NULL)
  51. return 0;
  52. p->next = temp->next;
  53. free(temp);
  54. return 1;
  55. }
  56. /*计算链表节点的数量*/
  57. int count_list(struct list *p)
  58. {
  59. int count = 0;
  60. while(p->next)//不计算头节点
  61. {
  62. p = p->next;
  63. count++;
  64. }
  65. return count;
  66. }
  67. /*清空一个链表,只保留头节点*/
  68. void clear_list(struct list *p)
  69. {
  70. struct list *head = p;
  71. p = p->next;
  72. while(p)
  73. {
  74. struct list * tmp = p->next;
  75. free(p);
  76. p = tmp;
  77. }
  78. head->next = NULL;
  79. }
  80. /*判断一个链表是否为空*/
  81. int empty_list(struct list *p)
  82. {
  83. if(p->next != NULL)
  84. return 0;
  85. else
  86. return 1;
  87. }
  88. /*返回链表指定位置的节点*/
  89. struct list *locale_list(struct list *p , int n)
  90. {
  91. p = p->next;
  92. while(p && n--)
  93. {
  94. p = p->next;
  95. }
  96. return p;
  97. }
  98. /*返回数据等于data的节点*/
  99. struct list *data_list(struct list *p , int data)
  100. {
  101. p = p->next;
  102. while(p)
  103. {
  104. if(p->data == data)
  105. return p;
  106. }
  107. return NULL;
  108. }
  109. /*返回数据等于data的节点位置*/
  110. int data_pos(struct list *p , int data)
  111. {
  112. int index = 0;
  113. p = p->next;
  114. while(p)
  115. {
  116. if(p->data == data)
  117. break;
  118. p = p->next;
  119. index++;
  120. }
  121. return index;
  122. }
  123. /*返回链表中最后一个节点*/
  124. struct list *last_list(struct list *p)
  125. {
  126. while(p->next)
  127. {
  128. p = p->next;
  129. }
  130. return p;
  131. }
  132. /*合并两个链表,结果放入第一个链表内*/
  133. void merge_list(struct list *p , struct list *q)
  134. {
  135. struct list *p_last = last_list(p);
  136. p_last->next = q->next;
  137. free(q);
  138. }
  139. /*逆置一个链表*/
  140. struct list *reverse_list(struct list *p)
  141. {
  142. struct list *pre = p;
  143. struct list *cur = p->next;
  144. struct list *next = NULL;
  145. struct list *last = p->next;
  146. while(cur)
  147. {
  148. next = cur->next;
  149. cur->next = pre;
  150. pre = cur;
  151. cur = next;
  152. }
  153. last->next = NULL;
  154. p->next = pre;
  155. }
  156. int main(void)
  157. {
  158. struct list *head = create_list();
  159. int i;
  160. for (i = 0 ; i < 4 ; i++)
  161. {
  162. insert_list(head,i,i);
  163. }
  164. traverse(head);
  165. printf("%d\n",last_list(head)->data);
  166. return 0;
  167. }

head  -> first -> second -> null

优化后的链表程序:
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. struct list
  4. {
  5. int data;
  6. struct list * next;
  7. };
  8. //打印一个链表
  9. void traverse_list(struct list *ls)
  10. {
  11. struct list * p = ls->next;//不打印头节点
  12. while(p)
  13. {
  14. printf("%d\n",p->data);
  15. p = p->next;
  16. }
  17. }
  18. //创建一个节点空间
  19. struct list *create_list()
  20. {
  21. return calloc(sizeof(struct list) , 1);
  22. }
  23. //插入一个节点
  24. struct list *insert_list(struct list * ls , int n , int data)
  25. {
  26. struct list * p = ls;
  27. while(p && n--)
  28. {
  29. p = p->next;
  30. }
  31. if(!p)
  32. return NULL;
  33. struct list *node = create_list();
  34. node->next = p->next;
  35. node->data = data;
  36. p->next = node;
  37. return p;
  38. }
  39. //删除一个节点
  40. int delete_list(struct list *ls , int n)
  41. {
  42. struct list *p = ls;
  43. while (p && n--)
  44. {
  45. p = p->next;
  46. }
  47. struct list *tmp = p->next;
  48. p->next = tmp->next;
  49. free(tmp);
  50. }
  51. //初始化一个链表
  52. struct list *init_list(int n)
  53. {
  54. struct list *head = create_list();
  55. int i;
  56. for(i = 0 ; i < n ; i++)
  57. insert_list(head,i,i);
  58. return head;
  59. }
  60. //统计节点的数量
  61. int count_list(struct list *ls)
  62. {
  63. struct list * p = ls->next;
  64. int count = 0;
  65. while(p)
  66. {
  67. p = p->next;
  68. count++;
  69. }
  70. return count;
  71. }
  72. //清空链表
  73. void clear_list(struct list *ls)
  74. {
  75. struct list * p = ls->next;
  76. while(p)
  77. {
  78. struct list * tmp = p->next;
  79. free(p);
  80. p = tmp;
  81. }
  82. ls->next = NULL;
  83. }
  84. //判断一个链接是否为空
  85. int empty_list(struct list *ls)
  86. {
  87. struct list *p = ls->next;
  88. if (p!=NULL)
  89. return 0;
  90. else
  91. return 1;
  92. }
  93. //返回链表指定位置的节点
  94. struct list *locale_list(struct list *ls , int n)
  95. {
  96. struct list * p = ls->next;
  97. while(p && n--)
  98. {
  99. p = p->next;
  100. }
  101. return p;
  102. }
  103. //返回链接等于data的节点
  104. struct list *data_list(struct list *ls , int data)
  105. {
  106. struct list *p = ls->next;
  107. while (p)
  108. {
  109. if (p->data == data)
  110. break;
  111. p = p->next;
  112. }
  113. return p;
  114. }
  115. //返回链表等于data的位置
  116. int pos_list(struct list *ls , int data)
  117. {
  118. struct list *p = ls->next;
  119. int index = 0;
  120. while (p)
  121. {
  122. if(p->data == data)
  123. break;
  124. p = p->next;
  125. index++;
  126. }
  127. return index;
  128. }
  129. //得到最后一个节点
  130. struct list *last_list(struct list *ls)
  131. {
  132. struct list *p = ls->next;
  133. struct list *pre = p;
  134. while(p)
  135. {
  136. pre = p;
  137. p = p->next;
  138. }
  139. return pre;
  140. }
  141. //合并两个链表,放入第一个链表中
  142. void merge_list(struct list *ls1 , struct list *ls2)
  143. {
  144. struct list *last = last_list(ls1);
  145. last->next = ls2->next;
  146. free(ls2);
  147. }
  148. //链表逆置
  149. void reverse_list(struct list *ls)
  150. {
  151. struct list *pre = ls;
  152. struct list *cur = ls->next;
  153. struct list *next = NULL;
  154. struct list *last = ls->next;
  155. while (cur)
  156. {
  157. next = cur->next;
  158. cur->next = pre;
  159. pre = cur;
  160. cur = next;
  161. }
  162. last->next = NULL;
  163. ls->next = pre;
  164. }
  165. int main(void)
  166. {
  167. struct list *head = init_list(10);
  168. traverse_list(head);
  169. return 0;
  170. }

注重理解下面左值和右值的区别
  1. node->next = p->next;
  2. p->next = node;


把本班的同学读入到结构体数组里,加上序号,利用链表并且冒泡排序。
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <time.h>
  5. struct student
  6. {
  7. int ID;
  8. char name[20];
  9. };
  10. struct list
  11. {
  12. struct student st;
  13. struct list *next;
  14. };
  15. struct list *create_list()
  16. {
  17. return calloc(1,sizeof(struct list));
  18. }
  19. struct list *insert_list(struct list *ls , int n, struct student s)
  20. {
  21. struct list *p = ls;
  22. while (p && n--)
  23. p = p->next;
  24. if(!p)
  25. return NULL;
  26. struct list *node = create_list();
  27. node->st = s;
  28. node->next = p->next;
  29. p->next = node;
  30. return node;
  31. }
  32. void traverse_list(struct list *ls)
  33. {
  34. struct list *p = ls->next;
  35. while(p)
  36. {
  37. printf("%d:%s\n",p->st.ID,p->st.name);
  38. p = p->next;
  39. }
  40. }
  41. void init_list(struct list *ls)
  42. {
  43. struct list *head = ls;
  44. FILE *fp = fopen("student.bin","r");
  45. while(!fp)
  46. return;
  47. struct student st;
  48. int index = 0;
  49. while(fread(&st,sizeof(struct student),1,fp) > 0)
  50. {
  51. insert_list(head,index,st);
  52. index++;
  53. }
  54. }
  55. void sort_list(struct list *ls , int n)
  56. {
  57. struct list *p = NULL;
  58. struct student tmp;
  59. int i,j,min;
  60. for (i = 0; i < n ; i++)
  61. {
  62. p = ls->next;
  63. for (j = 0; j < n-i-1; j++)
  64. {
  65. if (p->st.ID > p->next->st.ID)
  66. {
  67. tmp = p->st;
  68. p->st = p->next->st;
  69. p->next->st = tmp;
  70. }
  71. p = p->next;
  72. }
  73. }
  74. }
  75. void init_stubin()
  76. {
  77. srand((unsigned)time(NULL));
  78. FILE *fp1 = fopen("student.txt","r");
  79. FILE *fp2 = fopen("student.bin","w");
  80. while(!fp1 || !fp2)
  81. return;
  82. char buf[1024];
  83. struct student st;
  84. memset(&st,0,sizeof(st));
  85. int arr[42] = {0};
  86. int pos;
  87. while(fgets(buf,sizeof(buf),fp1) != NULL)
  88. {
  89. if(buf[strlen(buf)-1] == ‘\n‘)
  90. buf[strlen(buf)-1] = ‘\0‘;
  91. pos = rand()%42;
  92. while(arr[pos] == 1)
  93. pos = rand()%42;
  94. arr[pos] = 1;
  95. st.ID = pos;
  96. strcpy(st.name,buf);
  97. fwrite(&st,sizeof(st),1,fp2);
  98. }
  99. fclose(fp1);
  100. fclose(fp2);
  101. }
  102. int main(void)
  103. {
  104. init_stubin();
  105. struct list *head = create_list();
  106. init_list(head);
  107. //traverse_list(head);
  108. sort_list(head,42);
  109. traverse_list(head);
  110. return 0;
  111. }



来自为知笔记(Wiz)


9.9 链表及其运用