数据结构与算法学习day06-设计链表、翻转链表

一、设计链表

1.题目

707. 设计链表 - 力扣(LeetCode)

2.思路

这道题用虚拟头结点来做代码量会少点且容易理解

这道题目设计链表的五个接口:

  • 获取链表第index个节点的数值(对于直接读取函数,实现时直接让指针指向该位置就行
  • 在链表的最前面插入一个节点(1.题目没有给head这个指针,则不需要操作 2.直接用虚拟头结点即可操作 3.链表长度需要增加
  • 在链表的最后面插入一个节点(1.cur指针需要先指向虚拟头结点,为了防止链表为空!2.链表长度需要增加
  • 在链表第index个节点前面插入一个节点(1.cur指针需要先指向虚拟头结点,为了找到插入位置前一个节点
  • 删除链表的第index个节点(释放指针内存后需要定义为空指针,防止成为野指针

3.代码

class MyLinkedList {//类的知识有点遗忘了
public:
    //定义链表
    struct LinkedNode{
        int val;
        LinkedNode* next;
        LinkedNode(int val):val(val),next(nullptr){}//个构造函数的初始化列表
    };
    MyLinkedList() {//初始化链表
        vitalhead = new LinkedNode(0);//使用虚拟头结点
        _size = 0;//作用:统计链表长度
    }
    
    int get(int index) {// 直接读current的值
        if(index < 0 || index > (_size-1)){
            return -1;
        }
        LinkedNode* current = vitalhead->next;
        while(index--){
            current = current->next;
        }
        return current->val;
    }
    
    void addAtHead(int val) {//需要移动头结点吗?
       LinkedNode* temp = new LinkedNode(val);
        temp->next = vitalhead->next;
        vitalhead->next = temp;
        _size++;//重要!!!
    }
    
    void addAtTail(int val) {
        LinkedNode* current = vitalhead;//防止是空的
        LinkedNode* temp = new LinkedNode(val);//默认没有指向
        while(current->next != NULL){
            current = current->next;
        }
        current->next = temp;
        _size++;
    }
    
    void addAtIndex(int index, int val) {
        if(index < 0) index = 0;
        if(index > _size) return;//如果 index 等于链表的长度,那么该节点会被追加到链表的末尾
        LinkedNode* current = vitalhead;//这个位置要注意是虚拟结点,为了找添加位置的前一个节点
        LinkedNode* temp = new LinkedNode(val);
        while(index--){
            current = current->next;
        }
        temp->next = current->next;
        current->next = temp;
        _size++;
    }
    
    void deleteAtIndex(int index) {
        if(index < 0 || index > (_size-1)){
            return ;//返回空
        }
        LinkedNode* current = vitalhead;
        while(index--){//
            current = current->next;
        }//找到前一个结点
        LinkedNode* temp = current->next;
        current->next = current->next->next;
        
        delete temp;//释放空间
        temp = nullptr;
        //delete命令指示释放了temp指针原本所指的那部分内存,
        //被delete后的指针temp的值(地址)并非就是NULL,而是随机值。也就是被delete后,
        //如果不再加上一句temp=nullptr,tmp会成为乱指的野指针
        //如果之后的程序不小心使用了tmp,会指向难以预想的内存空间
        _size--;
    }

    void printLinkedList(){
        LinkedNode* current = vitalhead;
        while(current->next != NULL){
            cout<<current->next->val<<" ";
            current = current->next;
        }
        cout << endl;
    }

    private:
        int _size;
        LinkedNode* vitalhead;
};

/**
 * Your MyLinkedList object will be instantiated and called as such:
 * MyLinkedList* obj = new MyLinkedList();
 * int param_1 = obj->get(index);
 * obj->addAtHead(val);
 * obj->addAtTail(val);
 * obj->addAtIndex(index,val);
 * obj->deleteAtIndex(index);
 */

二、翻转链表

1.题目

206. 反转链表 - 力扣(LeetCode)

2.思路

2.1 双指针

注意后面的更新顺序

2.2 递归算法

思路和双指针差不多

3.代码

双指针代码

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* current = head;
        ListNode* pre = NULL;
        ListNode* temp;
        while(current){
            temp = current->next;
            current->next = pre;
            pre = current;
            current = temp;
        }
        return pre; 
    }
};

 递归算法

class Solution {
public:

    ListNode* refunc(ListNode* cur,ListNode* pre){
        if(cur == nullptr) return pre;
        ListNode* temp = cur->next;
        cur->next = pre;
        return refunc(temp,cur);
        
    }
    ListNode* reverseList(ListNode* head) {
        return refunc(head,nullptr);
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值