链表
移除链表元素
- 前提
- 无头单向链表
- 要点
- 插入一个fake头统一操作
- 指针停留在前节点,用curNode->next->val来判断值,修改curNode->next来删除节点
- 注意区分不同情况指针如何移动
- 释放内存
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* removeElements(struct ListNode* head, int val) {
struct ListNode *fakeHead = malloc(sizeof(struct ListNode));
fakeHead -> next = head;
struct ListNode *curNode = fakeHead;
struct ListNode *tmpNode;
while (curNode -> next != NULL){
if (curNode -> next -> val == val){
tmpNode = curNode -> next;
curNode -> next = curNode -> next -> next;
free(tmpNode);
}
else{
curNode = curNode -> next;
}
}
head = fakeHead -> next;
free(fakeHead);
return head;
}
设计链表
- 前提
- 要点
- 根据myLinkedListAddAtHead的特性,要有虚拟头结点
- 循环条件是(curNode != NULL)还是(curNode->next != NULL)由循环体内的操作决定,要保证不访问到空指针。
typedef struct MyLinkedList{
int val;
struct MyLinkedList* next;
} MyLinkedList;
MyLinkedList* myLinkedListCreate() {
MyLinkedList* head = malloc(sizeof(MyLinkedList));
head -> next = NULL;
return head;
}
int myLinkedListGet(MyLinkedList* obj, int index) {
int i = 0;
MyLinkedList* curNode = obj;
while(curNode -> next != NULL && i <= index){
curNode = curNode -> next;
i++;
}
if (i > index){
return curNode -> val;
}
return -1;
}
void myLinkedListAddAtHead(MyLinkedList* obj, int val) {
MyLinkedList* nhead = malloc(sizeof(MyLinkedList));
nhead -> val = val;
nhead -> next = obj -> next;
obj -> next = nhead;
}
void myLinkedListAddAtTail(MyLinkedList* obj, int val) {
MyLinkedList* tail = malloc(sizeof(MyLinkedList));
MyLinkedList* curNode = obj;
while(curNode->next != NULL){
curNode = curNode -> next;
}
curNode -> next = tail;
tail -> val = val;
tail -> next = NULL;
}
void myLinkedListAddAtIndex(MyLinkedList* obj, int index, int val) {
MyLinkedList* insert = malloc(sizeof(MyLinkedList));
MyLinkedList* curNode = obj;
int i = 0;
while(curNode->next != NULL && i < index){
curNode = curNode-> next;
i++;
}
if (i == index){
insert -> val = val;
insert -> next = curNode -> next;
curNode -> next = insert;
}
}
void myLinkedListDeleteAtIndex(MyLinkedList* obj, int index) {
MyLinkedList* curNode = obj;
MyLinkedList* tmpNode = NULL;
int i = 0;
while(curNode->next->next != NULL && i < index){
curNode = curNode-> next;
i++;
}
if (i == index){
tmpNode = curNode -> next;
curNode -> next = curNode -> next -> next;
free(tmpNode);
}
}
void myLinkedListFree(MyLinkedList* obj) {
MyLinkedList* curNode = obj;
MyLinkedList* tmpNode = NULL;
while(curNode != NULL){
tmpNode = curNode -> next;
free(curNode);
curNode = tmpNode;
}
}
void MyLinkedListShow(MyLinkedList* obj){
MyLinkedList* curNode = obj -> next;
while(curNode != NULL){
printf("%d ", curNode->val);
curNode = curNode->next;
}
printf("\n");
}
反转链表
- 要点
- 假装链表头有一个虚拟空节点(NULL)
双指针法
preNode + curNode
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* reverseList(struct ListNode* head) {
struct ListNode* preNode = NULL;
struct ListNode* curNode = head;
struct ListNode* nextNode = NULL;
while (curNode != NULL){
nextNode = curNode -> next;
curNode -> next = preNode;
preNode = curNode;
curNode = nextNode;
}
return preNode;
}
递归法
被绕晕了