题目链接:203. 移除链表元素 - 力扣(LeetCode)
上学期的数据结构与算法有在学这些基本结构,一看到题目其实大概有个思路,但是因为代码能力不够强,对代码掌握不熟,过程还是有点坎坷的。要加油哦!!
思路:这里我只想说第二种方法:虚拟节点 其实它的本质就是将这个链表变成一个有头节点的链表,原来的头节点实际上就是首元节点。
代码复现:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* removeElements(struct ListNode* head, int val){
struct ListNode* newhead,*temp;
newhead = malloc(struct ListNode*)(sizeof(struct ListNode);
newhead = head; //注意这里!!一定要记得赋值
struct ListNode* cur = newhead; //为什么不是head->next 是因为这是单链表的删除
//开始在链表中查询比对删除
while( cur->next!=NULL ){
//如果下一个结点不是空结点并且所储存的元素的值是要删除的val值
if( cur->next!=NULL && cur->val==val){
//注意要删除的结点不是cur结点而是cur所指的下一结点
temp = cur->next;
cur->next = cur->next->next;
free(temp);
}
//不用删除就直接后移继续查找后面的结点
else{
cur = cur->next;
}
}
head = newhead->next;
free(newhead);
return head;
}
其实最后也可以直接
return newhead->next;
但是做好空间管理占用内存会更少一点
题目链接:707. 设计链表 - 力扣(LeetCode)
啊啊啊好麻烦一个题。。。好吧是我太垃的原因吗
注意:
- 删除链表最后一个元素时,就直接先遍历一边链表门将一个指针指向最后一个元素就好
- 插入元素时,先判断插入位置,如果是要插在第一个位置就调用头部插入的函数就好
- 删除元素时,一定也要分情况讨论,分删除第一个元素和其他元素
void myLinkedListDeleteAtIndex(MyLinkedList* obj, int index) { MyLinkedList *p = obj->next,*temp; //如果要删除的是首元结点 if( index == 0){ temp = obj->next; if( temp!=NULL ){ obj = obj->next; free(temp); } else{ int i = 1; while( p!=NULL ){ if(i == index){ //保留要删除的结点 temp = p->next; //一定要判断该结点是否为空 if(temp != NULL){ p->next = temp->next; free(temp); } } else{ p = p->next; } i++; } }
题目链接:206. 反转链表 - 力扣(LeetCode)
不难捏,但是我老是把一个简单的事情搞复杂
首先我是想一边遍历一边反转的,但是后来我又想把一个指针放在链表头部,一个指针放在链表尾部。然后弄不出,其实这样还需要在遍历一遍根本没必(这也是单链表的一个小缺点)。就用类似双指针的思想就好了。
双指针代码:
struct ListNode* reverseList(struct ListNode* head){
struct ListNode *slow,*fast,*temp;
fast = head;
slow = NULL;
while(fast != NULL){
temp = fast->next; //保存原链表指向
//反转链表指向
fast->next = slow;
//移动指针
slow = fast;
fast = temp;
}
return slow;
}
看到随想录上还有虚拟结点头插法和用栈解决的方法,想把第二题解决后再实现这两种方法。
头插法:可以认为利用原结点和头插法,建造一个新链表(不是全部真的新链表,只开辟了新的头结点)
代码复现:
struct ListNode* reverseList(struct ListNode* head){
struct ListNode *L = (struct ListNode*)malloc(sizeof(struct ListNode));
L->next = NULL;
struct ListNode *p,*q;
p = head;
while(p){
//q保留p指针所指位置,否则待会反转链表被重新赋值后找不到,陷入死循环
q = p-> next;
p -> next = L->next;
L -> next = p;
//p返回原来链表
p = q;
}
//注意不是return L;而是首元结点
return L->next;
}
栈方法:
我试试学了C++或者Java之后能不能利用一些库函数和容器做。。。。