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

链表

理论基础

移除链表元素

leetcode

代码随想录

  • 前提
    • 无头单向链表
  • 要点
    • 插入一个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;
}

设计链表

leetcode

代码随想录

  • 前提
  • 要点
    • 根据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");
}

反转链表

leetcode

代码随想录

  • 要点
    • 假装链表头有一个虚拟空节点(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;
}

递归法

被绕晕了

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值