代码随想录算法训练营第三天|203 移除链表元素、707 设计链表、206 反转链表

一、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);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值