带头节点的单链表-------C语言实现

  1 /*****************************************************
  2 Author:Simon_Kly    Version:0.1    Date:20170520 
  3 Description:带头接点的单链表
  4 Mail:degaullekong@gmail.com
  5 Funcion List: 
  6 *****************************************************/
  7 
  8 #include <stdio.h>
  9 #include <stdlib.h>
 10 
 11 typedef struct node
 12 {
 13     int data;
 14     struct node *next;
 15 }Node, *Link;
 16 
 17 /*判断malloc是否正确执行*/
 18 void is_malloc_ok(Link head)
 19 {
 20     if (head == NULL)
 21     {
 22         printf("malloc error!\n");
 23         exit(-1);
 24     }
 25 }
 26 
 27 /*建立链表*/
 28 void create_link(Link * head)
 29 {
 30     *head = (Link)malloc(sizeof(Node));
 31     is_malloc_ok(*head);
 32     (*head)->next = NULL;
 33 }
 34 
 35 /*创建节点*/
 36 void create_node(Link * new_node)
 37 {
 38     *new_node = (Link)malloc(sizeof(Node));
 39     is_malloc_ok(*new_node);
 40 }
 41 
 42 /*插入节点尾插*/
 43 void insert_node_tail(Link head, Link new_node)
 44 {
 45     Link p = NULL;
 46     
 47     p = head;
 48 
 49     while (p->next != NULL)
 50     {
 51         p = p->next;
 52     }
 53     p->next = new_node;
 54     new_node->next = NULL;
 55 }
 56 
 57 /*插入节点头插*/
 58 void insert_node_head(Link head, Link new_node)
 59 {
 60     Link p = NULL;
 61 
 62     p = head;
 63 
 64     new_node->next = head->next;
 65     head->next = new_node;
 66 }
 67 
 68 /*打印节点*/
 69 void output_link(Link head)
 70 {
 71     Link p = NULL;
 72 
 73 
 74     if (head == NULL)
 75     {//空链
 76         printf("link is empty!\n");
 77         return ;
 78     }
 79 
 80     p = head->next;
 81     while (p != NULL)
 82     {
 83         printf("%d\n", p->data);
 84         p = p->next;
 85     }
 86 }
 87 
 88 /*置空链*/
 89 void make_empty_link(Link *head)
 90 {
 91     Link p = NULL;
 92 
 93     p = (*head)->next;
 94 
 95     while ((*head)->next != NULL)
 96     {
 97         (*head)->next = (*head)->next->next;
 98         free(p);
 99         p = (*head)->next;
100     }
101 }
102 
103 /*释放链表*/
104 void release_link(Link * head)
105 {
106     make_empty_link(head);
107     free(*head);
108     *head = NULL;
109 }
110 
111 int main()
112 {
113     int i;
114 
115     Link head = NULL;
116     Link new_node = NULL;
117 
118     create_link(&head);
119     
120     /*尾插*/
121     for (i = 0; i < 10; i++)
122     {
123         create_node(&new_node);
124         new_node->data = i + 1;
125         insert_node_tail(head, new_node);
126     }
127     output_link(head);
128 
129     /*头插*/
130     create_node(&new_node);
131     new_node->data = 20;
132     insert_node_head(head, new_node);
133     output_link(head);
134 
135     /*释放链表阶段*/
136     release_link(&head);
137     output_link(head);
138     return 0;
139 }

不带头结点代码传送门:http://www.cnblogs.com/SimonKly/p/6890287.html

可以从代码中看出,不带头结点的代码中插入节点的函数insert*中的参数是二级指针,因为头指针的指向可能会发生变化,需要用二级指针带回一级指针的地址。

而在带头结点的代码中在相同的插入节点的函数insert*中的参数是一级指针并没有使用二级指针,因为带头结点的链表中头结点是真真实实存在,在create*中分配空间于它,只是它的值域没有值,改变的是它的指针域的指向,其指针域的地址可以由它自己带回。

带头结点的链表比不带头结点的链表处理起来更加的简单,不要考虑头指针的指向是否发生变化的问题。

posted @ 2017-05-22 17:18  SimonKly  阅读(1606)  评论(0编辑  收藏  举报