数据结构之——链表
闲来无事温习一下基本的数据结构,一个简单的单链表实现
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <errno.h> 4 5 //#define LIST_DEBUG 6 7 8 typedef struct _int_list { 9 struct _int_list *next; 10 int item; 11 } int_list_node_t; 12 13 int_list_node_t *int_list_create(void) { 14 int_list_node_t *node; 15 node = calloc(1, sizeof(int_list_node_t)); 16 if (NULL == node) { 17 return NULL; 18 } 19 20 node->next = NULL; 21 22 return node; 23 } 24 25 void int_list_print(int_list_node_t *head) { 26 27 int_list_node_t *node; 28 int_list_node_t *node_pre; 29 node = head->next; 30 node_pre = head; 31 if (NULL == node) { 32 printf("empty list\n"); 33 } 34 while(node) { 35 printf("node: %p, node->next: %p, value: %d\n", node, node->next, node->item); 36 node_pre = node; 37 node = node->next; 38 } 39 printf("\n"); 40 } 41 42 int int_list_add(int_list_node_t *head, int value) { 43 44 int_list_node_t *node; 45 node = calloc(1, sizeof(int_list_node_t)); 46 if (NULL == node) { 47 return -ENOMEM; 48 } 49 node->item = value; 50 51 int_list_node_t *node1; 52 node1 = head->next; 53 head->next = node; 54 node->next = node1; 55 56 return 0; 57 } 58 59 int int_list_delete(int_list_node_t *head, int value) { 60 61 int_list_node_t *node; 62 int_list_node_t *node_pre; 63 node = head->next; 64 node_pre = head; 65 while(node) { 66 if (node->item == value) { 67 node_pre->next = node->next; 68 free(node); 69 return 0; 70 } else { 71 node_pre = node; 72 node = node->next; 73 } 74 } 75 76 return -1; 77 } 78 79 int int_list_delete_1(int_list_node_t *head, int value) { 80 81 if (NULL == head || NULL == head->next) { 82 return -1; 83 } 84 85 int_list_node_t **pp = &head->next; 86 int_list_node_t *entry = head->next; 87 #ifdef LIST_DEBUG 88 int_list_node_t *entry_pre = head; 89 fprintf(stdout, "\nInitial status:\n"); 90 fprintf(stdout, "pp point to head %p's next\n" 91 "and *pp is : %p\n", entry_pre, *pp); 92 fprintf(stdout, "To process node@%p whit value: %d\n", entry, entry->item); 93 #endif 94 while(entry) { 95 if(entry->item == value) { 96 *pp = entry->next; 97 #ifdef LIST_DEBUG 98 fprintf(stdout, "\nTarget found:" 99 "\nchange node %p's next field to node@%p\n\n", 100 entry_pre, *pp); 101 #endif 102 free(entry); 103 return 0; 104 } 105 106 #ifdef LIST_DEBUG 107 entry_pre = entry; 108 #endif 109 pp = &entry->next; 110 entry = entry->next; 111 #ifdef LIST_DEBUG 112 fprintf(stdout, "\nStatus changed, pp is updated:\n"); 113 fprintf(stdout, "pp point to node %p's next field\n" 114 "now *pp is : %p\n", entry_pre, *pp); 115 fprintf(stdout, "To process node@%p whit value: %d\n", entry, entry->item); 116 #endif 117 } 118 119 return 0; 120 } 121 122 int_list_node_t* int_list_from_array(int array[], int n) { 123 int_list_node_t *node; 124 node = int_list_create(); 125 if (NULL == node) { 126 return NULL; 127 } 128 129 int i; 130 for (i = 0; i < n; i++) { 131 int_list_add(node, array[i]); 132 } 133 134 return node; 135 } 136 137 int_list_node_t* int_list_from_cmd_line(int argc, char *argv[]) { 138 int_list_node_t *node; 139 node = int_list_create(); 140 if (NULL == node) { 141 return NULL; 142 } 143 144 int i; 145 for (i = 0; i < argc; i++) { 146 int_list_add(node, strtol(argv[i], NULL, 0)); 147 } 148 149 return node; 150 } 151 152 void int_list_reverse(int_list_node_t *head) { 153 int_list_node_t *node; 154 int_list_node_t *node_next; 155 int_list_node_t *node_tmp; 156 node = head->next; 157 node_next = node ? node->next : NULL; 158 if (NULL == node) { 159 return; 160 } 161 162 while(node && node_next) { 163 node_tmp = node_next->next; 164 node_next->next = node; 165 node = node_next; 166 node_next = node_tmp; 167 } 168 169 //The old first element will be the last 170 head->next->next = NULL; 171 //set the new first element 172 head->next = node; 173 174 } 175 176 void int_list_reverse_1(int_list_node_t *head) { 177 int_list_node_t *node_cur = head->next; 178 int_list_node_t *node_pre = NULL; 179 int_list_node_t *node_next; 180 181 if (NULL == node_cur) { 182 return; 183 } 184 185 for(; 186 node_cur; 187 node_next = node_cur->next, node_cur->next = node_pre, 188 node_pre = node_cur, node_cur = node_next); 189 190 head->next = node_pre; 191 } 192 193 int main(int argc, char *argv[]) 194 { 195 int_list_node_t *head; 196 if (argc > 1) { 197 head = int_list_from_cmd_line(argc - 1, &argv[1]); 198 } else { 199 int array[] = { 1, 2, 3}; 200 #define ARRAY_SIZE(a) (sizeof(a) /sizeof(a[0])) 201 head = int_list_from_array(array, ARRAY_SIZE(array)); 202 } 203 int_list_print(head); 204 int_list_reverse_1(head); 205 int_list_print(head); 206 int_list_delete_1(head, 2); 207 int_list_print(head); 208 return 0; 209 }
没什么好说的,链表反转(逆序),在面试时总可以遇到,今天自己实现一下。
记得去年什么时候,大神linus说好多程序员不懂指针的指针,在进行链表操作时,不够简练。今天试着理解了一下,使用二级指针
来实现了链表的删除操作。
浙公网安备 33010602011771号