数据结构与算法笔记二 - 链表
#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;
}