单链表的创建、插入、删除、查找

  #返回上一级

@Author: 张海拔

@Update: 2014-01-23

@Link: http://www.cnblogs.com/zhanghaiba/p/3530532.html

 

  1 /*

  2  *Author: ZhangHaiba

  3  *Date: 2014-1-22

  4  *File: single_linked_list.c

  5  *

  6  *single linked list demo

  7  */

  8 

  9 #include <stdio.h>

 10 #include <stdbool.h>

 11 #include <stdlib.h>

 12 #define INF 0x7fffffff

 13 #define CMD_LNE 128

 14 

 15 typedef struct node* link;

 16 typedef struct node {

 17     int item;

 18     link next;

 19 }node;

 20 

 21 //public

 22 link NODE(int item, link next);

 23 link list_create(int n);

 24 link list_reverse_create(int n);

 25 bool list_insert(link head, int pos, int item);

 26 bool list_delete(link head, int pos);

 27 link list_search(link head, int item);

 28 void list_travel(link head);

 29 int list_length(link head);

 30 void list_destroy(link head);

 31 

 32 

 33 int main(void)

 34 {

 35     int n;

 36     int pos, item;

 37     char cmd[CMD_LNE];

 38 

 39     printf("Create list reversely enter '1', or naturally enter '0'.\n");

 40     int creation_mode;

 41     scanf("%d", &creation_mode);

 42     printf("Now we are gonna create list_a made by n nodes, please assign value of n:\n");

 43     scanf("%d", &n);

 44     printf("Enter values of n items: \n");

 45     link list_a = creation_mode == 1 ? list_reverse_create(n) : list_create(n);

 46     printf("The length of list_a is %d\n", list_length(list_a));

 47     printf("Now you can operate link_a by using command line.\n");

 48     bool flag = true;

 49     while(flag) {

 50         scanf("%s", cmd);

 51         switch(cmd[0]) {

 52             case 'i':

 53             scanf("%d%d", &pos, &item);

 54             if (list_insert(list_a, pos, item))

 55                   printf("Inserted successfully!\n");

 56             else

 57                 printf("Insert failed! -- check pos\n");

 58             break;

 59             case 'd':

 60             scanf("%d", &item);

 61             if (list_delete(list_a, item))

 62                 printf("Delete successfully!\n");

 63             else

 64                 printf("Delete failed! -- check pos\n");

 65             break;

 66             case 's':

 67             scanf("%d", &item);

 68             link ans = list_search(list_a, item);

 69             ans == NULL ? printf("Not found!\n") : printf("Found item %d\n", ans->item); 

 70             break;

 71             case 't':

 72             list_travel(list_a);

 73             break;

 74             case 'q':

 75             list_destroy(list_a);

 76             printf("list_a have been destroy!\n");

 77             flag = false;

 78             break;

 79             default:

 80             break;

 81         }

 82     } //while

 83     return 0;

 84 }

 85 

 86 

 87 link NODE(int item, link next)

 88 {

 89     link born = malloc(sizeof (node));

 90     born->item = item;

 91     born->next = next;

 92     return born;

 93 }

 94 

 95 //create by 'tail insert'

 96 link list_create(int n)

 97 {

 98     int i, item;

 99     link head = NODE(INF, NULL);

100     link tail = head;

101 

102     for (i = 0; i < n; ++i) {

103         scanf("%d", &item);

104         tail->next = NODE(item, NULL);

105         tail = tail->next;

106     }

107     return head;

108 }

109 

110 //create by 'head insert'

111 link list_reverse_create(int n)

112 {

113     int i, item;

114     link head = NODE(INF, NULL), tmp;

115 

116     for (i = 0; i < n; ++i) {

117         scanf("%d", &item);

118         tmp = head->next;

119         head->next = NODE(item, tmp);

120     }

121     return head;

122 }

123 

124 int list_length(link head)

125 {

126     int cnt = 0;

127 

128     for (head = head->next; head != NULL; head = head->next)

129         ++cnt;

130     return cnt;

131 }

132 

133 bool list_insert(link head, int pos, int item)

134 {

135     //illegal position: insert nothing

136     if (pos < 0 || pos > list_length(head))

137         return false;

138     while (pos--)

139         head = head->next;

140     link tmp = head->next;

141     head->next = NODE(item, tmp);

142     return true;

143 }

144 

145 bool list_delete(link head, int pos)

146 {

147     //illegal position: delete nothing

148     if (pos < 0 || pos > list_length(head)-1)

149         return false;

150     while (pos--)

151         head = head->next;

152     link save = head->next;

153     head->next = save->next;

154     free(save);

155     return true;

156 }

157 

158 link list_search(link head, int item)

159 {

160     for (head = head->next; head != NULL; head = head->next)

161         if (head->item == item)

162             return head;

163     return NULL;

164 }

165 

166 void list_travel(link head)

167 {

168     for (head = head->next; head != NULL; head = head->next)

169         printf(head->next == NULL ? "%d\n" : "%d ", head->item);

170 }

171 

172 void list_destroy(link head)

173 {

174     head->next == NULL ? free(head) : list_destroy(head->next);

175 }

 

测试示范:

ZhangHaiba-MacBook-Pro:code apple$ ./a.out

Create list reversely enter '1', or naturally enter '0'.

1

Now we are gonna create list_a made by n nodes, please assign value of n:

6

Enter values of n items: 

534 31 525 62 12 68

The length of list_a is 6

Now you can operate link_a by user command.

t

68 12 62 525 31 534

i 0 44

Inserted successfully!

t

44 68 12 62 525 31 534

i 8 99

Insert failed! -- check pos

i 7 99

Inserted successfully!

t

44 68 12 62 525 31 534 99

d -1

Delete failed! -- check pos

d 0

Delete successfully!

t

68 12 62 525 31 534 99

d 7

Delete failed! -- check pos

d 6

Delete successfully!

t

68 12 62 525 31 534

s 11

Not found!

s 68

Found item 68

s 534

Found item 534

q

list_a have been destroy!

 

 

对于带头节点的单链表的实现,值得注意的是,头插法和尾插法是相对创建方式而言,没有单独成为一个方法(函数)的必要。

而且这里提供了支持任意位置插入的函数list_insert()。

链式数据结构都是动态分配的空间,所有必须提供销毁函数(类似C++的析构函数)。这里的销毁函数联系到二叉树,可以看做是一叉树的后根(后序)遍历。

上述实现只有销毁函数是递归实现的,而其他函数都是迭代实现的,尽管递归实现也很自然,但考虑到用户空间栈有限,容易迭代实现的一律优先用迭代实现。

list_insert()和list_delete()函数返回bool类型是考虑到要对pos做边界检查。另外,C99的_Bool类型实在不怎么好看,而且没有定义true/false,所以还是用<stdbool>。

对于位置参数pos,其正确性应该由客户端或说API调用者负责。

 

 

   #返回上一级

你可能感兴趣的:(单链表)