数据结构与算法笔记二 - 链表

数据结构与算法笔记二 - 链表

#include <iostream>
#include <stack>

using namespace std;

struct Node {
    Node * next;
    int data;
};


class LinkList {
public:
    LinkList();

    void putNode(int);

    void showLinkList();
    
    // 1. 判断是否为回文结构 -- 栈方法
    bool isPalindromeStack();

    // 2 判断是否为回文结构 -- 快慢指针方法
    bool isPalindromeQuickSlowPtr();

    // 3 单链表倒序
    void reverseLinklist();

    void destroyLinkList();

    ~LinkList();


private:
    Node * m_Header;
    int m_Size;
};

LinkList::LinkList() {
    this->m_Header = new Node{nullptr, 0};
    this->m_Size = 0;
}


void LinkList::putNode(int val) {
    Node * newNode = new Node{nullptr, val};
    Node * cur = this->m_Header;
    while (cur->next != nullptr) cur = cur->next;
    cur->next = newNode;
    ++this->m_Size;
}


void LinkList::showLinkList() {
    Node * cur = this->m_Header;
    while (cur->next != nullptr) {
        cur = cur->next;
        cout << cur->data << ' ';
    }
    cout << endl;
}


bool LinkList::isPalindromeStack() {
    stack<Node *> s;
    Node * cur = this->m_Header;
    while (cur->next != nullptr) {
        cur = cur->next;
        s.push(cur);
    }

    bool res = true;
    cur = this->m_Header;
    while (cur->next) {
        cur = cur->next;

        if (cur->data != s.top()->data) {
            res = false;
            break;
        }

        s.pop();
    }

    return res;
}

void LinkList::reverseLinklist() {
    if (this->m_Header->next == nullptr) return;
    Node * temp;
    Node * pre = nullptr;
    Node * cur = this->m_Header->next;

    while (cur != nullptr) {
        temp = cur->next;
        cur->next = pre;
        pre = cur;
        cur = temp;
    }

    this->m_Header->next = pre;
}


void LinkList::destroyLinkList() {
    if (this->m_Header->next == nullptr) return;
    Node * cur = this->m_Header->next;
    Node * temp;
    while(cur) {
        temp = cur->next;
        delete cur;
        cur = temp;
        this->m_Size--;
    }
}

bool LinkList::isPalindromeQuickSlowPtr() {
    if (this->m_Header->next == nullptr) {
        cout << "No element in link list!" << endl;
        return true;
    }

    Node * qPtr = this->m_Header;   // 快指针
    Node * sPtr = this->m_Header;   // 慢指针

    while (qPtr->next && qPtr->next->next) {
        sPtr = sPtr->next;
        qPtr = qPtr->next->next;
    }
    // 运行完上面的代码后
    // 链表中元素个数为偶数时,qPtr指向最后一个元素,sPtr指向第 length / 2 个元素,
    // 此时令 qPtr = sPtr->next; sPtr->next = nullptr;
    // 链表中元素个数为奇数时,qPtr指向倒数第二个元素,sPtr指向第 (length - 1) / 2 个元素,
    // 此时令 qPtr = sPtr->next->next; sPtr->next = nullptr; 不需要核对最中间的一位元素

    int isOdd = false;

    if (qPtr->next) {
        qPtr =  sPtr->next->next;
        isOdd = true;
    }
    else {
        qPtr = sPtr->next;
    }

    Node * midNode = sPtr->next;

    sPtr->next = nullptr;
    // 这样整个链表就分为了两个链表,两者包括的位置分别为 [0, length / 2] 和 [(length + 1) / 2]
    // [(length + 1) / 2] 链表倒序,pre 指向倒序后的链表的第一位
    Node * next;
    Node * pre = nullptr;
    while(qPtr) {
        next = qPtr->next;
        qPtr->next = pre;
        pre = qPtr;
        qPtr = next;
    }

    // 比较两个链表
    bool res = true;
    Node * right = pre;
    Node * left = this->m_Header->next;
    while (left) {
        if (left->data != right->data) {
            res = false;
            break;
        }
        left = left->next;
        right = right->next;
    }

    // 还原链表,此时 qPtr 和 next 均指向同一个 nullptr
    while (pre) {
        next = pre->next;
        pre->next = qPtr;
        qPtr = pre;
        pre = next;
    }

    if (isOdd) {
        sPtr->next = midNode;
    }
    else {
        sPtr->next = qPtr;
    }


    return res;
}


LinkList::~LinkList() {
    if (this->m_Header->next != nullptr) {
        destroyLinkList();
    }
    delete this->m_Header;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值