第三章 链表

//2024.1.29
#include <iostream>
using namespace std;

class List{
public:
    List(){
        size = 0;
        head = new ListNode;
        head->next = nullptr;
    }
    ~List(){
        while(head->next != nullptr){
            ListNode* temp = head;
            head = head->next;
            delete temp;
        }
        delete head;
    }

    struct ListNode{
        int data;
        ListNode* next;
        ListNode(){}
        ListNode(int data){
            this->data = data;
            this->next = nullptr;
        }
        ~ListNode(){}
    };

    //头插结点
    void add_beg(int data){
        ListNode* temp = new ListNode(data);
        temp->next = head->next; 
        head->next = temp;
        size++;
    }

    //尾插结点
    void add_end(int data){
        ListNode* cur = head;
        while(cur->next != nullptr){
            cur = cur->next;
        }
        cur->next = new ListNode(data);
        size++;
    }

    //按值删除
    void delete_node(int data){
        ListNode* cur = head;
        while(cur->next != nullptr){
            if(cur->next->data == data){
                ListNode* temp = cur->next;
                cur->next = cur->next->next;
                delete temp;
                size--;
            }
            else{
                cur = cur->next;
            }
        }
    }

    //改变结点
    void change_node(int oldd, int newd){
        ListNode* cur = head;
        while(cur->next != nullptr){
            cur = cur->next;
            if(cur->data == oldd){
                cur->data = newd;
            }
        }
    }

    //按值定位
    void find_data(int data){
        ListNode* cur = head;
        int locate = 0;
        while(cur->next != nullptr){
            cur = cur->next;
            locate++;
            if(cur->data == data){
                cout << locate << " ";
            }
        }
        cout << endl;
    }

    //删除倒数第n个结点值
    void delete_endn(int n){
        ListNode* fast = head;
        ListNode* slow = head;
        while(n-- && fast != nullptr){
            fast = fast->next;
        }
        if(fast == nullptr){
            cout << "error find_endn" << endl;
            return;
        }
        while(fast->next != nullptr){
            fast = fast->next;
            slow = slow->next;
        }
        ListNode* temp = slow->next;
        slow->next = slow->next->next;
        delete temp;
    }

    //反转链表(双指针法)
    void reverse_dptr(){
        ListNode* cur = head->next;
        ListNode* pre = nullptr;
        while(cur != nullptr){
            ListNode* temp = cur->next;
            cur->next = pre;
            pre = cur;
            cur = temp;
        }
        head->next = pre;
    }

    //反转链表(递归法)
    void reverse_digui2(ListNode* pre, ListNode* cur){
        if(cur == nullptr){
            head->next = pre;
            return;
        }
        ListNode* temp = cur->next;
        cur->next = pre;
        pre = cur;
        cur = temp;
        reverse_digui2(pre, cur);
    }
    void reverse_digui(){
        ListNode* cur = head->next;
        ListNode* pre = nullptr;
        reverse_digui2(pre, cur);
    }

    //判断链表是否有环
    ListNode* find_cycle(){
        ListNode* slow = head;
        ListNode* fast = head;
        while(slow->next != nullptr && fast->next != nullptr){
            slow = slow->next;
            fast = fast->next->next;
            if(slow == fast){
                cout << "have cycle" << endl;
                return slow;
            }
        }
        if(slow->next == nullptr && fast->next == nullptr){
            cout << "no cycle" << endl;
            return nullptr;
        }
    }

    //寻找环入口节点 2(x+y) = x + y + n(y+z) 
    ListNode* find_cyclein(){
        ListNode* fast = find_cycle();
        if(fast != nullptr){
            ListNode* slow = head;
            while(slow != fast){
                slow = slow->next;
                fast = fast->next;
            }
            return slow;
        }
        else{
            return nullptr;
        }
    }
    //遍历链表
    void for_each(){
        ListNode* cur = head;
        while(cur->next != nullptr){
            cur = cur->next;
            cout << cur->data << " ";
        }
        cout << endl;
    }

    //获取链表长度
    int get_size(){
        return size;
    }

private:
    int size;
    ListNode* head;
};
int main(){
    List list;
    list.add_end(1);
    list.add_end(2);
    list.add_end(3);
    list.add_beg(3);
    list.add_beg(4);
    list.reverse_dptr();
    list.reverse_digui();
    list.delete_endn(1);
    list.for_each();
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值