C 单链表
C 单链表(Singly Linked List)
/* * singly_linked_list.c * 单向链表 * sll = singly_linked_list * */ #include <stdio.h> #include <stdlib.h> #include <stdbool.h> /* * 节点结构 head -> |value|next| -> ... * */ typedef struct sll { int value; struct sll *next; } sll; void init_sll(sll **head); void add_sll_node(sll **head, int value); void add_sll_nodes(sll **head, int values[], int len); bool del_sll_node(sll **head, int index); sll *get_sll_node(sll *head, int index); sll *locate_sll_node(sll *head, int value); bool insert_sll_node(sll **head, int index, int value); void traverse_sll(sll *head); int length_sll(sll *head); int main(int argc, char *argv[]) { sll *head; init_sll(&head); add_sll_node(&head, 1); int values[] = {1, 2, 3, 5, 8, 13}; add_sll_nodes(&head, values, 6); traverse_sll(head); del_sll_node(&head, 0); del_sll_node(&head, 3); traverse_sll(head); printf("The %d node is %p\n", 4, get_sll_node(head, 4)); printf("The node with value %d is %p\n", 13, locate_sll_node(head, 13)); printf("Length of List: %d\n", length_sll(head)); insert_sll_node(&head, 0, 0); insert_sll_node(&head, length_sll(head), 21); traverse_sll(head); del_sll_node(&head, 4); traverse_sll(head); return 0; } /* * 初始化链表 * 要求传入一个链表指针的地址,以便在函数中对这个指针做出更改 * */ void init_sll(sll **head) { *head = NULL; } /* * 添加节点 * */ void add_sll_node(sll **head, int value) { /* 新建一个节点 */ sll *node = (sll *)malloc(sizeof(sll)); node->value = value; node->next = NULL; sll *last = *head; if (!last) { /* 如果head节点是空的,说明链表为空 */ *head = node; } else { /* 找到链表尾部,将last节点的next指向sll节点 */ while (last->next) { last = last->next; } last->next = node; } } /* * 增加多个节点 * */ void add_sll_nodes(sll **head, int values[], int len) { for (int i = 0; i < len; i++) { add_sll_node(head, values[i]); } } /* * 根据索引删除节点 * 删除成功返回true,否则返回false * */ bool del_sll_node(sll **head, int index) { /* 如果删除索引大于等于列表长度 */ if (index >= length_sll(*head)) return false; /* 删除首节点 */ if(index==0) { sll *first = *head; sll *second = first->next; free(first); first = NULL; *head = second; return true; } else { /* 遍历到index的前一位后执行删除操作 */ int count = 0; for (sll *p=*head; p; p=p->next) { count++; if (count == index) { sll *n = p->next; p->next = n->next; free(n); n = NULL; return true; } } } return false; } /* * 根据索引查找节点 * 从0开始算起 * */ sll *get_sll_node(sll *head, int index) { /* 重复往下寻找index次,找到第index个节点,返回节点地址,否则NULL */ sll *node = head; int j = 0; while (node->next != NULL && j < index) { node = node->next; j++; } if (j == index) return node; else return NULL; } /* * 后插法:找到index-1位置,将节点插入到index中去 * 在index位置插入value * */ bool insert_sll_node(sll **head, int index, int value) { /* * 如果index为0,需要改变head指向 * */ if (index == 0) { sll *node = (sll *)malloc(sizeof(sll)); node->value = value; node->next = *head; *head = node; return true; } /* * 找到index-1位置的节点,如果节点不存在,不能插入 * */ sll *p, *s; p = get_sll_node(*head, index-1); if (p == NULL) { printf("wrong index\n"); return false; } else { /* * 新建节点s * s->next指向原先p->next * p->next指向s * */ s = (sll *)malloc(sizeof(sll)); s->value = value; s->next = p->next; p->next = s; return true; } } /* * 根据值查找节点 * */ sll *locate_sll_node(sll *head, int value) { for (sll *p=head; p; p=p->next) { if (p->value == value) return p; } return NULL; } /* * 遍历打印链表 * */ void traverse_sll(sll *head) { for (sll *p=head; p; p=p->next) { printf("%d -> ", p->value); } printf("NULL\n"); } /* * 链表长度 * */ int length_sll(sll *head) { int len = 0; for (sll *p=head; p; p=p->next) { len++; } return len; }
Resistance is Futile!