代码随想录算法训练营第3天 | 链表 |虚拟头哨兵

链表理论基础

链表节点的定义

struct ListNode {
    int val;  // 节点上存储的元素
    ListNode *next;  // 指向下一个节点的指针
    ListNode(int x) : val(x), next(NULL) {}  // 节点的构造函数
};

==如果不自己定义构造函数,就无法通过ListNode p(5);来初始化


203删除链表元素

class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        // 删除头结点
        while (head != NULL && head->val == val) { // 注意这里不是if
            ListNode* tmp = head;
            head = head->next;
            delete tmp;
        }

        // 删除非头结点
        ListNode* cur = head;
        while (cur != NULL && cur->next!= NULL) {
            if (cur->next->val == val) {
                ListNode* tmp = cur->next;
                cur->next = cur->next->next;
                delete tmp;
            } else {
                cur = cur->next;
            }
        }
        return head;
    }
};

虚拟头结点(哨兵)

class Solution {
public:
  ListNode* removeElements(ListNode* head, int val) {
    
    ListNode* shead = new ListNode();
    shead->next = head;   //引入头哨兵结点

    ListNode* cur = shead;

    while (cur->next != NULL) {
        if (cur->next->val == val)
        {
            ListNode* tmp = cur->next;
            cur->next = cur->next->next;
            delete tmp;
        }
        else
            cur = cur->next;
    }

    head= shead->next;
    delete shead;
    return head;
}
};

707设计链表

  • 单链表
class MyLinkedList {
public:
    struct LinkedNode
    {
        LinkedNode* next;
        int val;
        LinkedNode(int val) :val(val), next(nullptr) {}
    };

    MyLinkedList() {
        shead = new LinkedNode(0);
        size = 0;
    }

    int get(int index) {
        if (index > (size - 1) || index < 0)
            return -1;
        LinkedNode* cur = shead->next;
        for (int i = 0; i < index; i++)
            cur = cur->next;
        return cur->val;
    }

    void addAtHead(int val) {
        LinkedNode* newNode = new LinkedNode(val);
        newNode->next = shead->next;
        shead->next = newNode; 
        size++;
    }

    void addAtTail(int val) {
        LinkedNode* newNode = new LinkedNode(val);
        LinkedNode* cur = shead;
        while (cur->next != nullptr) {
            cur = cur->next;
        }
        cur->next = newNode;
        size++;
    }

    void addAtIndex(int index, int val) {
        if (index > size)return;
        else if (index < 0) index = 0;
        LinkedNode* newNode = new LinkedNode(val);
        LinkedNode* cur = shead;
        while (index--) 
            cur = cur->next;
        newNode->next = cur->next;
        cur->next = newNode;
        size++;
    }

    void deleteAtIndex(int index) {
        if (index >= size || index < 0) {
            return;
        }
        LinkedNode* cur = shead;
        while (index--)
            cur = cur->next;
        LinkedNode* tmp = cur->next;;
        cur->next = cur->next->next;
        delete tmp;
        tmp = nullptr;  //如果不再加上一句tmp=nullptr,tmp会成为乱指的野指针,指向难以预想的内存空间
        size--;
    }
   
private:
    LinkedNode* shead;
    int size;
};

注意delete后的野指针问题

  • 双向链表
class MyLinkedList {
public:
    struct DoubleLinked {
        int val;
        DoubleLinked* prev;
        DoubleLinked* next;
        DoubleLinked(int val) :val(val), prev(nullptr), next(nullptr) {}
    };

    MyLinkedList() {
        size = 0;
        shead = new DoubleLinked(0);
    }

    int get(int index) {
        if (index >= size || index < 0)
            return -1;
        DoubleLinked* cur = shead->next;
        while (index--)
            cur = cur->next;
        return cur->val;
    }

    void addAtHead(int val) {
        DoubleLinked* newNode = new DoubleLinked(val);
        if (shead->next)
        {
            shead->next->prev = newNode;
            newNode->next = shead->next;
        }

        shead->next = newNode;
        newNode->prev = shead;

        size++;
    }

    void addAtTail(int val) {
        DoubleLinked* cur = shead;
        for (int i = 0; i < size; i++)
            cur = cur->next;
        DoubleLinked* newNode = new DoubleLinked(val);
        cur->next = newNode;
        newNode->prev = cur;

        size++;
    }

    void addAtIndex(int index, int val) {
        if (index > size)return;
        if (index < 0)index = 0;

        DoubleLinked* cur = shead;
        while (index--)
            cur = cur->next;
        DoubleLinked* newNode = new DoubleLinked(val);
        if (cur->next)
            cur->next->prev = newNode;
        newNode->next = cur->next;
        cur->next = newNode;
        newNode->prev = cur;

        size++;
    }

    void deleteAtIndex(int index) {
        if (index < 0 || index >= size) return;

        DoubleLinked* cur = new DoubleLinked(0);
        cur = shead->next;

        while (index--)
            cur = cur->next;
        cur->prev->next = cur->next;
        if (cur->next)
            cur->next->prev = cur->prev;

        delete cur;
        cur = nullptr;

        size--;
    }

private:
    int size;
    DoubleLinked* shead;
};

206反转链表

  • 双指针法
ListNode* reverseList(ListNode* head) {
    ListNode* prev = nullptr;
    ListNode* cur = head;
    ListNode* tmp;
    while (cur!= nullptr) {
        tmp = cur->next;
        cur->next = prev;
        prev = cur;
        cur = tmp;
    }
    return prev;
}
  • 递归法(根据以上while改写)
class Solution {
public:
    ListNode* reverse(ListNode* cur,ListNode* pre) {
    if (!cur)
        return pre;

    ListNode* tmp;
    tmp = cur->next;
    cur->next = pre;

    return reverse(tmp, cur);
    
}

ListNode* reverseList(ListNode* head) {
    return reverse(head, nullptr);
}
};
posted @ 2024-03-23 15:45  daydayup_cpp  阅读(11)  评论(0)    收藏  举报