数据结构-线性表 Posted on 2018-10-16 | In 数据结构 | 基本操作链表技巧 理解指针或引用的含义 警惕指针丢失和内存泄漏 利用哨兵简化实现难度 重点留意边界条件处理 如果链表为空时,代码是否能正常工作? 如果链表只包含一个结点时,代码是否能正常工作? 如果链表只包含两个结点时,代码是否能正常工作? 代码逻辑在处理头结点和尾节点的时候,是否能正常工作? 举例画图、辅助思考 多写、多练 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475//数据结构#include <stdio.h>#include <stdlib.h>#include <stdbool.h>typedef struct ListNode { struct ListNode *next; int val;}SingleLinkListNode;//带头结点,便于插入和删除统一操作#pragma mark - 链表操作/** 创建头结点 @return 链表 */SingleLinkListNode *single_link_list_create(void);/** 链表是否空 @param head 链表 @return 链表是否空 */bool single_link_list_is_empty(SingleLinkListNode *head);/** 链表遍历 @param head 链表 */void single_link_list_dump_head(SingleLinkListNode *head);/** 链表遍历 不带头结点 @param head 链表 */void single_link_list_dump(SingleLinkListNode *head);/** 头部插入 @param head 链表 @param data 插入数据 */void single_link_list_insert_head(SingleLinkListNode *head, int data);/** 尾部插入 @param head 链表 @param data 插入数据 */void single_link_list_insert_tail(SingleLinkListNode *head, int data);/** 删除头部节点 @param head 链表 @return 删除的节点 */SingleLinkListNode *single_link_list_delete_head(SingleLinkListNode *head);/** 删除尾部节点 @param head 链表 @return 删除的节点 */SingleLinkListNode *single_link_list_delete_tail(SingleLinkListNode *head); 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158//带头结点,便于插入和删除统一操作#pragma mark - 链表操作/** 创建头结点 @return 链表 */SingleLinkListNode *single_link_list_create(){ SingleLinkListNode *head = (SingleLinkListNode *)malloc(sizeof(SingleLinkListNode)); if (head == NULL) { printf("头结点创建失败\n"); return NULL; } head->next = NULL; return head;}/** 链表是否空 @param head 链表 @return 链表是否空 */bool single_link_list_is_empty(SingleLinkListNode *head){ return head->next == NULL;}/** 链表遍历 @param head 链表 */void single_link_list_dump_head(SingleLinkListNode *head){ SingleLinkListNode *p = head->next; printf("带头结点链表:"); while (p != NULL) { printf("%d", p->val); if (p->next != NULL) { printf("->"); } else { printf("\n"); } p = p->next; }}/** 链表遍历 不带头结点 @param head 链表 */void single_link_list_dump(SingleLinkListNode *head){ SingleLinkListNode *p = head; printf("不带头结点链表:"); while (p != NULL) { printf("%d", p->val); if (p->next != NULL) { printf("->"); } else { printf("\n"); } p = p->next; }}/** 头部插入 @param head 链表 @param data 插入数据 */void single_link_list_insert_head(SingleLinkListNode *head, int data){ SingleLinkListNode *p = head; SingleLinkListNode *temp = (SingleLinkListNode *)malloc(sizeof(SingleLinkListNode)); temp->val = data; temp->next = p->next; p->next = temp;}/** 尾部插入 @param head 链表 @param data 插入数据 */void single_link_list_insert_tail(SingleLinkListNode *head, int data){ SingleLinkListNode *p = head; while (p->next != NULL) { p = p->next; } SingleLinkListNode *temp = (SingleLinkListNode *)malloc(sizeof(SingleLinkListNode)); temp->val = data; temp->next = NULL; p->next = temp;}/** 删除头部节点 @param head 链表 @return 删除的节点 */SingleLinkListNode *single_link_list_delete_head(SingleLinkListNode *head){ SingleLinkListNode *p = head; if (!p->next) { return NULL; } SingleLinkListNode *temp = p->next; p->next = temp->next; temp->next = NULL; return temp;}/** 删除尾部节点 @param head 链表 @return 删除的节点 */SingleLinkListNode *single_link_list_delete_tail(SingleLinkListNode *head){ SingleLinkListNode *p = head; if (!p->next) { return NULL; } while (p->next->next != NULL) { p = p->next; } SingleLinkListNode *temp = p->next; p->next = temp->next; temp->next = NULL; return temp;}