一、203 移除链表元素
struct ListNode* removeElements(struct ListNode* head, int val) {
//原链表删除操作
//如果删除的为头节点
while (head != NULL && head->val == val)
head = head->next;
//删除的非链表头结点
struct ListNode *cur = head;
while (cur != NULL && cur->next != NULL)
{
if (cur->next->val == val)
{
cur->next = cur->next->next;
}
else
cur = cur->next;
}
return head;
//使用虚拟头结点(有一点小错误,因为没有free)
struct ListNode *dummyhead;
dummyhead=(struct ListNode*)malloc(sizeof(struct ListNode));
dummyhead->next = head;
struct ListNode *cur = dummyhead;
while(cur->next!=NULL)
{
if(cur->next->val==val)
cur->next=cur->next->next;
else
cur = cur->next;
}
return dummyhead->next;
}
//使用虚拟头节点的完全正确版本
struct ListNode* removeElements(struct ListNode* head, int val) {
//力扣中所有的链表都是不带头节点,先加个头节点
struct ListNode newhead;//头节点
newhead.next = head;
for(struct ListNode*p=&newhead;p->next!=NULL; )//删除需要前驱
{
if(p->next->val == val){
struct ListNode *q = p->next;//保存需要删除的节点
p->next = q->next;//把q从链表中剔除
free(q);//释放p
}
else //没有删除节点,p后移
p = p->next;
}
return newhead.next;
}
小编在这里放了三段代码,第一段和第三段是完全正确的,那小编为什么还要放第二段代码呢?
因为第二段代码是小编在没有参照的情况下认真完成的,虽然有些小瑕疵,但是可以正确运行,所以小编决定还是让它见一见外面的世界(其实是小编想展示自己的努力成果,嘿嘿)
二、707 设计链表
首先,在这里,小编要提醒大家,这道题的代码是有问题的,有几个函数的思路和代码随想录教的有一点不同,之所以把它放在这里是因为想让大家帮忙找一找问题在哪里(主要是Get函数运行的结果不正确),当然,也是为了展示小编真的认真完成了(3h!!!)。这道题也是让小编感受到学会了和学废了的区别!!!
typedef struct Node{
int val;//值
struct Node*next;//指向下一个的指针
}Node;
typedef struct{
int size;//记录链表中有效元素的数量
Node *data;//指向虚拟头结点的指针
} MyLinkedList;
MyLinkedList* myLinkedListCreate() {
//分配内存
MyLinkedList* obj = (MyLinkedList*)malloc(sizeof(MyLinkedList));
//创建虚拟头节点
Node*dummyhead = (Node*)malloc(sizeof(Node));
dummyhead->next = NULL;
obj->data = dummyhead;
obj->size = 0;//初始化链表元素为0
return obj;
}
int myLinkedListGet(MyLinkedList* obj, int index) {
Node*cur=obj->data;
assert(cur!=NULL);
if(cur==NULL)
return -1;
if(index<0||index>=obj->size)
return -1;
Node*p = cur;
int i=0;
while(p!=NULL)
{
if(i == index)
return p->val;
p = p->next;
i++;
}
return -1;
}
void myLinkedListAddAtHead(MyLinkedList* obj, int val) {
Node*cur=obj->data;
assert(cur!=NULL);
if(cur==NULL)
return;
Node*p = (Node*)malloc(sizeof(Node));
p->val = val;
p->next = cur->next;
cur->next = p;
obj->size++;
}
void myLinkedListAddAtTail(MyLinkedList* obj, int val) {
Node*cur=obj->data;
assert(cur!=NULL);
if(cur==NULL)
return;
//找尾结点
Node*p;
for(p=cur;p->next!=NULL;p=p->next)
;
//创建新节点
Node*q=(Node*)malloc(sizeof(Node));
q->val = val;
q->next = p->next;
p->next = q;
obj->size++;
}
void myLinkedListAddAtIndex(MyLinkedList* obj, int index, int val) {
Node*cur=obj->data;
assert(cur!=NULL);
if(cur==NULL)
return;
if(index<0||index>obj->size)
return;
if(index==obj->size)//尾插
myLinkedListAddAtTail(obj,val);
return;
if(index>=0)
{
//找到index位置
Node*p;
p=cur->next;
for(int i=0;i<index&&p!=NULL;i++,p=p->next)
;
//创建新节点
Node*q = (Node*)malloc(sizeof(Node));
q->val = val;
//从后插入
q->next = p->next;
p->next = q;
//交换
int tmp = q->val;
p->val=q->val;
p->val = tmp;
}
obj->size++;
}
void myLinkedListDeleteAtIndex(MyLinkedList* obj, int index) {
Node*cur=obj->data;
assert(cur!=NULL);
if(cur==NULL)
return;
if(index<0||index>=obj->size)
return;
Node*p;
int i;
for(p=cur,i=0;i<index;i++,p=p->next)
;
Node *q = p->next;
p->next = q->next;
free(q);
obj->size++;
}
void myLinkedListFree(MyLinkedList* obj) {
Node*tmp = obj->data;
while(tmp!=NULL){
Node*n=tmp;
tmp=tmp->next;
free(n);
}
free(obj);
}
三、206 反转链表
在这道题,大家一定要熟悉双指针写法,然后再看递归写法!!!(这道题是来给小编报恩的嘛,知道小编今天心情起起落落!)
//双指针写法
struct ListNode* reverseList(struct ListNode* head) {
struct ListNode*cur=head;
struct ListNode*pre=NULL;
while(cur!=NULL)
{
struct ListNode*tmp = cur->next;
cur->next = pre;
pre = cur;
cur = tmp;
}
return pre;
}
//递归写法
struct ListNode *Reverse(struct ListNode *cur,struct ListNode *pre)
{
if(cur==NULL)
return pre;
struct ListNode *tmp = cur->next;
cur->next = pre;
return Reverse(tmp,cur);
}
struct ListNode* reverseList(struct ListNode* head) {
return Reverse(head,NULL);
}