题目
- 把2个有序单调递增的链表 合并到一个链表倒序输出。要求不产生dummy node
- 单链表快排(按交换值和指针实现)
- 单链表归并(快慢指针)
解法
涉及链表的插入操作,要考虑当前插入点的node 和前一个node,修改指针。链表倒序的场景方法有头插法和尾插法
#include <iostream>
#include <algorithm>
using namespace std;
struct ListNode {
int _data;
ListNode* _next;
ListNode(int data):_data(data) {
_next = NULL;
}
};
class LinkList {
private:
int _len;
ListNode* _head;
public:
LinkList() {
_len = 0;
_head = NULL;
}
~LinkList() {
if (_head) {
ListNode* tmpNode = _head;
_head = _head->_next;
delete tmpNode;
tmpNode = NULL;
}
_len = 0;
}
ListNode* GetHead() { return _head; }
int GetLength() { return _len; }
LinkList* Push(int dt) {
ListNode* node = new ListNode(dt);
ListNode* tmpNode = _head;
if (!tmpNode) {
_head = node;
_len++;
return this;
}
while (tmpNode->_next) {
tmpNode = tmpNode->_next;
}
tmpNode->_next = node;
_len++;
return this;
}
/*
Keep node as start point, save it's next to a tmpNode
update tmpNode's pointer
*/
ListNode* Reverse(ListNode* node) {
if (!node) return node;
ListNode* tmpNode = node;
_head = node;
while (node->_next) {
tmpNode = node->_next;
node->_next = tmpNode->_next;
tmpNode->_next = _head;
_head = tmpNode;
}
return _head;
}
ListNode* Reverse2(ListNode* node) {
if(!node) return NULL;
ListNode* first = NULL, * second = NULL;
first = node;
while (node->_next) {
node = node->_next;
}
second = node;
ListNode* tmp = first;
while (first != second) {
tmp = first;
first = first->_next;
tmp->_next = second->_next;
second->_next = tmp;
}
return node;
}
/*
Note: Take a primary link list as a template, split another list as element to insert to the template list
Insert: Keep tow pointers, "_head" and "prev"
such as insert new node: node
tempNode = node;
node = node->next;
prev->next = tempNode;
tempNode->next = _head;
*/
ListNode* MergeList(LinkList* l) {
ListNode* lhead = l->GetHead();
ListNode* pre = NULL, *head = NULL, *tempNode = NULL;
if (!lhead) return _head;
if (!_head) return lhead;
if(_head->_data >= lhead->_data) {
head = lhead;
lhead = lhead->_next;
head->_next = _head;
pre = _head;
_head = _head->_next;
}
while (_head) {
if (_head->_data <= lhead->_data) {
pre = _head;
_head = _head->_next;
} else {
tempNode = lhead;
lhead = lhead->_next;
pre->_next = tempNode;
tempNode->_next = _head;
pre = tempNode;
}
if (!lhead) break;
}
if (!_head&& lhead) { pre->_next = lhead; }
_head = head;
return _head;
}
// 交换的是ListNode里面的值,而不是2个节点
ListNode* Partition(ListNode* left, ListNode* right) {
int data = left->_data;
ListNode* pSlow = left, *pQuick = left->_next;
while (pQuick != right) {
if (pQuick->_data < data) {
pSlow = pSlow->_next;
swap(pSlow->_data, pQuick->_data);
}
pQuick = pQuick->_next;
}
swap(pSlow->_data, left->_data);
return pSlow;
}
void QuickSortInternal(ListNode* left, ListNode* right) {
if (left == right) return;
ListNode* mid = Partition(left, right);
QuickSortInternal(left, mid);
QuickSortInternal(mid->_next, right);
}
void QuickSort() {
QuickSortInternal(_head, NULL);
}
ListNode* Merge(ListNode* left, ListNode* right) {
ListNode dummy(0);
static int i = 0;
ListNode *p = &dummy;
while(left && right) {
if (left->_data < right->_data) {
p->_next = left;
left = left->_next;
} else {
p->_next = right;
right = right->_next;
}
p = p->_next;
}
if (left) p->_next = left;
if (right) p->_next = right;
p = dummy._next;
cout << "Round " << i++ << " : ";
while (p) {
cout << p->_data << ", ";
p = p->_next;
}
cout << endl;
_head = dummy._next;
return _head;
}
ListNode *MergeRecursive(ListNode *a, ListNode *b) {
if (!a) return b;
if (!b) return a;
if (a->_data <= b->_data) {
a->_next = MergeRecursive(a->_next, b);
return a;
} else {
b->_next = MergeRecursive(b->_next, a);
return b;
}
}
ListNode* MergeSort(ListNode* node) {
if(!node || !node->_next) return node;
ListNode* slow = node, *fast = node, *pre = NULL;
while(fast && fast->_next) {
pre = slow;
slow = slow->_next;
fast = fast->_next->_next;
}
pre->_next = NULL;
ListNode *left = MergeSort(node); // slow 为中间结点了
ListNode* right = MergeSort(slow);
return Merge(left, right);
}
void Print(ListNode* tmp = NULL) {
if (!tmp) tmp = _head;
ListNode* node = tmp;
while (node->_next) {
cout << node->_data << "->";
node = node->_next;
}
cout << node->_data << endl;
}
};
int main() {
LinkList* l1 = new LinkList();
l1->Push(1)->Push(5)->Push(7)->Push(8)->Push(9)->Push(11)->Push(12)->Push(13);
cout << "L1: ";
l1->Print();
LinkList* l2 = new LinkList();
l2->Push(2)->Push(6)->Push(10)->Push(14)->Push(16);
cout << "L2: ";
l2->Print();
l2->MergeList(l1);
cout << "Merge: ";
l2->Print();
l2->Reverse(l2->GetHead());
//tmpNode = l2->Reverse2(tmpNode);
cout << "Reverse: ";
l2->Print();
LinkList* l3 = new LinkList();
l3->Push(23)->Push(12)->Push(34)->Push(1)->Push(2)->Push(88)->Push(87)->Push(10);
cout << "Origin L3: ";
l3->Print();
cout << "Sorted L3: " << endl;
//l3->QuickSort();
l3->MergeSort(l3->GetHead());
l3->Print(l3->GetHead());
delete l1;
delete l2;
delete l3;
return 0;
}