链表, 一种抽象数据类型(ADT)的存储方式.
通过链式的动态存储, 用的时候创建节省空间.
想要删除某一个不想要的数据也更简单. 当找到这个节点的时候, 通过找到前驱节点, 将前驱节点与后继节点相连
再把当前节点释放掉就可以了.
同样数据增改也很轻松.
遍历, 不需要修改数据, 所以使用一级指针遍历就可以了
void
TransList(struct ListNode* header) {struct ListNode* walker = header;while (walker) {// printf("%d %s\n", walker->key, walker->value);walker = walker->next;}
}
头插法, 需要修改数据, 所以可以使用二级指针, 也可以使用一级指针(需要返回值)
void
InsertHead_ptrToptr(struct ListNode** hptr,struct ListNode* node) {struct ListNode** header = hptr;node->next = *header;*header = node;
}struct ListNode*
InsertHead_ptr(struct ListNode* hptr,struct ListNode* node) {struct ListNode* header = hptr;node->next = header;header = node;return header;
}
尾插法, 需要修改数据, 所以可以使用二级指针, 也可以使用一级指针(因为要修改next的内容,
next是一级指针保存了要修改的节点的首地址, 所以不需要返回值, 我在这里加上了返回值)
void
InsertTail_ptrToptr(struct ListNode** hptr,struct ListNode* node) {struct ListNode** walker = hptr;while (*walker) {walker = &((*walker)->next);}node->next = NULL;*walker = node;
}struct ListNode*
InsertTail_ptr(struct ListNode* hptr,struct ListNode* node) {struct ListNode* walker = hptr;while (walker->next) {walker = walker->next;}node->next = NULL;walker->next = node;return hptr;
}
删除节点元素, 遍历整个链表, 找到要删除的节点的前驱节点, 前驱节点的next指向删除的元素的后继节点.
我给出一级指针和二级指针的两种方法, 可以好好理解一下两种方法执行过程.
struct ListNode*
RemoveElement_ptr(struct ListNode* hptr,struct ListNode* node) {struct ListNode* walker = hptr;while (walker->next) {if (walker->next == node) {struct ListNode* deleteElem = walker->next;walker->next = deleteElem->next;deleteElem->next = NULL;}walker = walker->next;}return hptr;
}void
RemoveElement_ptrToptr(struct ListNode** hptr,struct ListNode* node) {struct ListNode** walker = hptr;while (*walker) {if (*walker == node) {struct ListNode* deleteElem = *walker;*walker = ((*walker)->next);deleteElem->next = NULL;}walker = &((*walker)->next);}
}