第三天链表

203.移除链表元素

力扣题目链接(opens new window)

题意:删除链表中等于给定值 val 的所有节点。

示例 1:

输入:head = [1,2,6,3,4,5,6], val = 6

输出:[1,2,3,4,5]

示例 2:

输入:head = [], val = 1

输出:[]

示例 3:

输入:head = [7,7,7,7], val = 7

输出:[]

struct ListNode* removeElements(struct ListNode* head, int val){
    struct ListNode * dummyHead= (struct ListNode *)malloc(sizeof(struct ListNode));
    dummyHead->next = head;//虚拟头结点指向开头
    


    struct ListNode *p = dummyHead;//定一个新的节点来操作链表
    
    
    while(p->next!=NULL)//需要判断head是不是空
    {
        if(p->next->val == val  )//第一次因为head有值,所以需要判断登不等于val
        {
            p->next = p->next->next;//等于的话向后移动直到指向空结束循环
        }
        else//如果不等于直接跳过
        {
            p=p->next;
        }
            
        
    }
    return dummyHead->next;
}

这道题写的时候,刚开始以为head本身是虚拟头结点,直接写然后错误,再删除【7 7 7 7】的时候总是漏一个,后面通过打印发现head有值,是第一个元素的值,所以就需要在申请一个节点来指向head,这样的话就可以操作head了,指向head的这个节点是不能动的,动了的话后面就没法返回了,所以还需要在申请一个节点等于指向头结点的节点,用这个节点来操作链表,当这个节点移动到最后的时候,这时候一开始指向头结点的节点就指向了新的节点了。

707.设计链表

力扣题目链接

采用虚拟头结点的方法,比较简单:

typedef struct MyLinkedList{
    int val;//链表存储的值
    struct  MyLinkedList *next;//用于指向下一个节点

} MyLinkedList;

//创建一个虚拟节点
MyLinkedList* myLinkedListCreate() {
    MyLinkedList *head = (MyLinkedList *)malloc(sizeof(MyLinkedList));//为新链表申请内存空间
    head->next = NULL;//让next指向空
    return head;//返回虚拟头结点

}

//获取链表中index的值,根据提示知道现在的obj是虚拟头结点
int myLinkedListGet(MyLinkedList* obj, int index) {
    MyLinkedList *cur = obj->next;//新建一个节点指向第一个节点;
    for(int i= 0; cur!=NULL;i++)//下标从0开始进行判断指导找到index的位置,如果cur移动到最后不存在返回-1
    {
        if(i == index)判断第一次index是不是0的位置,后面依次加1
        {
            return cur->val;//如果找到index的位置,直接返回cur的值
        }
        cur=cur->next;//i的位置 不是的话,cur更新,i更新
    }
    return -1;

}

//头插法插入一个值,新建一个节点等于val,然后让新节点指向obj的next,再让obj指向新节点
void myLinkedListAddAtHead(MyLinkedList* obj, int val) {
    MyLinkedList *p =  (MyLinkedList *)malloc(sizeof(MyLinkedList));
    p->val = val;
    p->next = obj->next;
    obj->next = p;

}
//尾插法,先找到链表的结尾位置,最后一个位置的节点的next是null
//新建一个节点指向虚拟头结点,然后判断p的next是不是空,不是的话就移动,直到为空为止
//如果p的next为空,则p就是最后一个有值的节点,下面新建一个节点保存val,再让p的next指向这个节点就行了
void myLinkedListAddAtTail(MyLinkedList* obj, int val) {
    MyLinkedList *p =  obj;
    while(p->next!=NULL)
    {
        p=p->next;
    }
    MyLinkedList *tail =  (MyLinkedList *)malloc(sizeof(MyLinkedList));
    tail->val = val;
    tail->next = NULL;
    p->next = tail;
}
//在index(从0开始)为止插入val
//首先判断,如果是0为止就是头插法直接调用
//否则的话需要先找到index前面的那个位置,然后把新节点插入找到位置的下一个。

void myLinkedListAddAtIndex(MyLinkedList* obj, int index, int val) {
    if (index == 0){
        myLinkedListAddAtHead(obj, val);
        return;
    }
    MyLinkedList *cur = obj->next;
    for (int i = 1 ;cur != NULL; i++){
        if (i == index){
            MyLinkedList* newnode = (MyLinkedList *)malloc(sizeof (MyLinkedList));
            newnode->val = val;
            newnode->next = cur->next;
            cur->next = newnode;
            return;
        }
        else{
            cur = cur->next;
        }
    }
}

void myLinkedListDeleteAtIndex(MyLinkedList* obj, int index) {
        if (index == 0){
        MyLinkedList *tmp = obj->next;
        if (tmp != NULL){
            obj->next = tmp->next;
            free(tmp);     
        }
        return;
    }
    MyLinkedList *cur = obj->next;
    for (int i = 1 ;cur != NULL && cur->next != NULL; i++){
        if (i == index){
            MyLinkedList *tmp = cur->next;
            if (tmp != NULL) {
                cur->next = tmp->next;
                free(tmp);
            }
            return;
        }
        else{
            cur = cur->next;
        }
    }

}
//删除所有节点
void myLinkedListFree(MyLinkedList* obj) {
    while(obj != NULL){
        MyLinkedList *tmp = obj;
        obj = obj->next;
        free(tmp);
    }
}

/**
 * Your MyLinkedList struct will be instantiated and called as such:
 * MyLinkedList* obj = myLinkedListCreate();
 * int param_1 = myLinkedListGet(obj, index);
 
 * myLinkedListAddAtHead(obj, val);
 
 * myLinkedListAddAtTail(obj, val);
 
 * myLinkedListAddAtIndex(obj, index, val);
 
 * myLinkedListDeleteAtIndex(obj, index);
 
 * myLinkedListFree(obj);
*/

206.反转链表

力扣题目链接(opens new window)

题意:反转一个单链表。

示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL

struct ListNode* reverseList(struct ListNode* head){
    if(head == NULL || head->next == NULL)
    {
        return head;
    }
    struct ListNode *cur = NULL;
    struct ListNode *p = head;
    while(p!=NULL)
    {
        struct ListNode * t = p->next;
        p->next = cur;
        cur = p;
        p = t;
        
    }
    return cur;

}
struct ListNode* reverseList(struct ListNode* head){
    struct ListNode *temp;//保存当前指针
    struct ListNode *pre = NULL;//指向前一个当前节点的前一个节点
    //因为head本身就有保存值是第一个,所以可以移动head,如果head为空没有值的话直接就返回空
    while(head)
    {
        printf("%d\n",head->val);
        temp = head->next;//指向下一个新节点
        head ->next = pre;//更新第一个节点的下一个节点,第一次需要指向空,后面需要之前前一个
        pre = head;//移动pre
        head = temp;//pre前进
    }
    return pre;

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值