## Topo
```
#include <iostream>
using namespace std;
typedef struct leader* lref;
typedef struct trailer* tref;
struct leader{
int key; // Key value
int count; // Count leader before it, leader before it in topo
lref next; // To next leader
tref trailer; // Trailer will manage leader which stay behind current leader
};
struct trailer{
lref id; // To leader which stay behind current leader
tref next; // The next trailer of current leader
};
vector<lref> allNodes;
lref addList(lref& head, lref& tail, int w, int &z)
{
lref h;
h = head;
tail->key = w;
while(h->key != w) // Sequential Search to return q or p
{
h = h->next;
}
if(h == tail)
{ // need create new tail to be guard
tail = new leader;
h->next = tail;
z++;
h->count = 0;
h->trailer = nullptr;
//allNodes.push_back(h); // Easy to delete node
}
return h;
}
void update(lref& p, lref& q)
{
tref t = new trailer;
t->id = q;
t->next = p->trailer;
p->trailer = t;
q->count++;
}
void topoSort(lref& head , lref& tail, int& z)
{
lref p = head;
lref q = p;
head = nullptr; // head : list of node have count = 0
while(p != tail)
{
q = p;
p = p->next;
--z;
if(q->count == 0)
{
q->next = head;
head = q;
}
}
q = head;
while(q)
{
cout << q->key << " ";
tref t = q->trailer;
q = q->next;
while(t)
{
p = t->id;
p->count--;
if(p->count == 0)
{
p->next = q;
q = p;
}
t = t->next;
}
}
}
void deleteTrailers(tref t) {
while (t != NULL) {
tref temp = t;
t = t->next;
delete temp;
}
}
void deleteLeaders(lref head) {
while (head != NULL) {
lref temp = head;
head = head->next;
deleteTrailers(temp->trailer); // Giải phóng danh sách các trailer
delete temp;
}
}
int main()
{
lref head, tail, p , q;
int z, x, y;
z = 0;
head = new leader;
tail = head;
while(cin >> x >> y)
{
p = addList(head,tail, x , z);
q = addList(head,tail, y , z);
update(p, q);
}
lref head_tmp = head;
topoSort(head, tail, z);
if(z)
{
cout << "Error List!\n";
}
deleteLeaders(head_tmp);
}
```
## Radix Sort (Ứng dụng Hash)
+ Xác định số lớn nhất để xem lặp lại bao nhiêu lần
+ Mỗi lần lặp sẽ lặp sẽ tạo các leader theo thứ tự theo thứ tự tăng dần, leader sẽ chứa các trailer mà có kí số bằng đại diện đó
+ Giống với sắp xếp Topo nhưng các leader được sắp tăng dần
+ Mỗi lần duyệt kí số sẽ nối trailer của leader trước nối trailer sau rồi xoá các leader(Coi ví dụ trong tập nhé mf)
```
#include <iostream>
#include <fstream>
#include <math.h>
#include "multi-link-list.h"
#include "radix-sort.h"
struct TRAILER //node quản lý các số dữ liệu thực sự
{
int number;
TRAILER* next;
};
struct TLIST //danh sách các trailer
{
TRAILER* head;
};
struct LEADER //node quản lý các chữ số dùng để so sánh được sắp xếp thứ tự tăng dần của digit
{
int digit;
LEADER* next;
TRAILER* trailerHead;
TRAILER* trailerTail;
};
struct LLIST //danh sách các leader
{
LEADER* head;
};
#include <iostream>
#include "multi-link-list.h"
TRAILER* createTrailer(int number)
{
TRAILER* trailer = new TRAILER;
if (!trailer)
{
std::cerr << "Cannot allocate memory\n";
return nullptr;
}
trailer->next = nullptr;
trailer->number = number;
return trailer;
}
LEADER* createLeader(int digit)
{
LEADER* leader = new LEADER;
if (!leader)
{
std::cerr << "Cannot allocate memory\n";
return nullptr;
}
leader->digit = digit;
leader->next = nullptr;
leader->trailerHead = nullptr;
leader->trailerTail = nullptr;
return leader;
}
void addHeadTrailer(TLIST& tlist, int number)
{
TRAILER* newTrailer = createTrailer(number);
if (!newTrailer)
return;
if (tlist.head)
newTrailer->next = tlist.head;
tlist.head = newTrailer;
}
void delTrailer(TLIST& tlist)
{
for (TRAILER* trailer = tlist.head; trailer; trailer = trailer->next)
delete trailer;
tlist.head = nullptr;
}
void delLeader(LLIST& llist)
{
for (LEADER* leader = llist.head; leader; leader = leader->next)
delete leader;
llist.head = nullptr;
}
LEADER* getLeader(LLIST& llist, int digit)
{
if (!llist.head) //leader list chưa có phần tử nào -> tạo phần tử đầu tiên
{
LEADER* newLeader = createLeader(digit);
if (!newLeader)
return nullptr;
llist.head = newLeader;
return llist.head;
}
//tìm leader với digit đã cho
LEADER* fakeHead = createLeader(-1); //tạo một head giả trỏ đến head thật sự
fakeHead->next = llist.head;
LEADER* leader = fakeHead;
while (leader->next && (leader->next)->digit < digit) //tìm phần tử cuối cùng
//hoặc phần tử tiếp theo có digit lớn hơn hoặc bằng digit đã cho
leader = leader->next;
//nếu phần tử tiếp theo là nullptr hoặc có digit lớn hơn
//-> không tồn tại leader với digit đã cho
//-> tạo leader mới
if (!leader->next || (leader->next)->digit > digit)
{
LEADER* newLeader = createLeader(digit);
newLeader->next = leader->next;
if (leader == fakeHead)
llist.head = newLeader;
else
leader->next = newLeader;
return newLeader;
}
//trường hợp còn lại: phần tử tiếp theo có digit bằng với digit cho trước
//-> đã tồn tại leader với digit cho trước
//-> trả về leader tiếp theo
return leader->next;
}
int main()
{
TLIST tlist = {nullptr};
std::ifstream f = openFile("input.txt");
int k, n;
f >> k >> n;
for (int i = 0; i < n; i++) //tạo danh sách liên kết gồm các trailer
{
int number;
f >> number;
addHeadTrailer(tlist, number);
}
radixSort(tlist, k);
for (TRAILER* trailer = tlist.head; trailer; trailer=trailer->next)
std::cout << trailer->number << " ";
delTrailer(tlist);
return 0;
}
std::ifstream openFile(const char path[])
{
std::ifstream f;
f.open(path);
if (!f)
{
std::cerr << "Cannot open file!\n";
exit(-1);
}
return f;
}
int getDigit(int number, int k, int i) //chia các chữ số thành các phần gồm k chữ số
//lấy đoạn thứ i (i từ 0) từ phải qua trái
{
return (number / (int)pow(10, k * i)) % (int)pow(10, k);
}
void radixSort(TLIST& tlist, int k)
{
if (!tlist.head)
return;
int max = tlist.head->number;
for (TRAILER* trailer = tlist.head; trailer; trailer = trailer->next)
if (max < trailer->number)
max = trailer->number; //tìm số lớn nhất trong trailer list
int times = ceil(ceil(log10(max)) / k); //tính toán số lần thực hiện vòng for
//sử dụng số lớn nhất để tính toán
//công thức: số số chữ số chia số khoảng chia yêu cần (làm tròn lên)
for (int i = 0; i < times; i++)
{
LLIST llist = {nullptr};
TRAILER* trailer = tlist.head;
do
{
int digit = getDigit(trailer->number, k, i);
LEADER* leader = getLeader(llist, digit); //trả về leader giữ digit
//nếu chưa tồn tại, tạo mới rồi trả về
//addTail trailer để giữ tính stable của radix sort
TRAILER* curTrailer = trailer; //lưu lại trailer hiện tại
trailer = trailer->next;
////nếu leader đang xét chưa có trailer -> thêm vào và cập nhật trailerHead và trailerTail
if (!leader->trailerHead)
{
leader->trailerHead = leader->trailerTail = curTrailer;
curTrailer->next = nullptr;
continue;
}
////nếu leader đã có trailer
curTrailer->next = nullptr;
leader->trailerTail = (leader->trailerTail)->next = curTrailer;
} while (trailer);
//sau khi hoàn thành đưa các trailer vào đúng leader có digit theo thứ tự tăng dần
//-> nối các trailer lại với nhau
tlist.head = (llist.head)->trailerHead;
for (LEADER* leader = llist.head; leader->next; leader = leader->next)
(leader->trailerTail)->next = (leader->next)->trailerHead;
delLeader(llist); //sau khi nối thì xóa hệ thống leader
}
}
```
## Priority queue
### Heap
+ Insert, Extract -> siftUp
+ Remove -> siftDown
+ i = 0, j = 2*i + 1
```
#include <iostream>
using namespace std;
struct p_queue{
int key;
int priority; // do uu tien
};
void sift(p_queue* a, int l, int r)
{
int i = l;
int j = 2*i + 1;
while(j < r)
{
if(j < r - 1)
{
if(a[j].priority > a[j+1].priority)
{
++j;
}
}
if(a[i].priority <= a[j].priority)
break;
swap(a[i], a[j]);
i = j;
j = i*2 + 1;
}
}
void sift_up(p_queue* a, int index)
{
int i = (index - 1)/2;
int j = index;
while(i)
{
if(a[j].priority < a[i].priority)
{
swap(a[j], a[i]);
}
else{
break;
}
j = i;
i = (j - 1) / 2;
}
}
void Insert(p_queue*& a, int x, int priority, int& len)
{
p_queue* b = new p_queue[len + 1];
memcpy(b, a, len*sizeof(p_queue));
b[len].key = x;
b[len].priority = priority;
delete[]a;
a = b;
int l = (len + 1) / 2 - 1;
sift_up(b, len);
++len;
}
void Remove(p_queue*& a, int val, int& len)
{
int index = 0;
for(int i = 0 ; i < len; ++i)
{
if(a[i].key == val)
{
index = i;
swap(a[index], a[len-1]);
break;
}
}
if(index == len)
return;
p_queue* b = new p_queue[len - 1];
memcpy(b, a, (len - 1)*sizeof(p_queue));
delete[] a;
a = b;
--len;
sift(a, index, len);
}
int Extract(p_queue* a, int& len)
{
if(len == 0)
{
return -1;
}
int val = a[0].key;
swap(a[0], a[len-1]);
--len;
sift(a, 0, len);
return val;
}
int main()
{
p_queue *a = nullptr;
int list[] = {1, 4, 5, 3, 2 ,7 ,6};
int priority[] = {1, 2, 3, 4, 5 ,6 ,7};
int n = 7;
int l = n / 2 - 1;
a = new p_queue[n];
for(int i = 0 ; i < n ; ++i)
{
a[i].key = list[i];
a[i].priority = priority[i];
}
while(l--)
{
sift(a,l,n);
}
for(int i = 0 ; i < n; ++i)
{
cout << a[i].key << "-" << a[i].priority << endl;
}
cout << "After insert \n";
Insert(a, 10, 2, n);
cout << n << endl;
for(int i = 0 ; i < n; ++i)
{
cout << a[i].key << "-" << a[i].priority << endl;
}
cout << "After remove \n";
Remove(a, 4, n);
cout << n << endl;
for(int i = 0 ; i < n; ++i)
{
cout << a[i].key << "-" << a[i].priority << endl;
}
cout << "Pop : " << Extract(a, n) << endl;
for(int i = 0 ; i < n; ++i)
{
cout << a[i].key << "-" << a[i].priority << endl;
}
}
```
### List
```
#include <iostream>
using namespace std;
struct PQNode{
PQNode* next;
int key;
int priority;
PQNode(int key, int priority) : key(key), priority(priority), next(nullptr) {}
};
bool isEmpty(PQNode* head) {
return head == nullptr;
}
// Method to insert an object into the queue
void Insert(PQNode*& head, int key, int priority) {
PQNode* newNode = new PQNode(key, priority); // Create a new node
// If the queue is empty or the new node has higher priority than the head
if (isEmpty(head) || head->priority > priority) {
newNode->next = head; // Insert the new node at the beginning
head = newNode;
} else {
// Find the correct position to insert the new node
PQNode* current = head;
while (current->next != nullptr && current->next->priority <= priority) {
current = current->next;
}
newNode->next = current->next;
current->next = newNode;
}
}
// Method to extract (remove) the highest priority object from the queue
PQNode* Extract(PQNode*& head) {
if (isEmpty(head)) {
return nullptr; // Return null if the queue is empty
}
PQNode* temp = head; // Store the head node
head = head->next; // Move the head to the next node
return temp; // Return the original head node
}
// Method to remove an object with a specific ID from the queue
bool Remove(PQNode*& head, int val) {
if (isEmpty(head)) {
return false; // Return false if the queue is empty
}
if (head->key == val) {
// Remove the head node if it matches the ID
PQNode* temp = head;
head = head->next;
delete temp;
return true;
}
// Search for the node with the given ID
PQNode* current = head;
while (current->next != nullptr && current->next->key != val) {
current = current->next;
}
if (current->next == nullptr) {
return false; // Return false if the ID is not found
}
// Remove the found node
PQNode* temp = current->next;
current->next = temp->next;
delete temp;
return true;
}
// Method to change the priority of an object with a specific ID
bool changePriority(PQNode*& head,int val, int newPriority) {
if (Remove(head, val)) {
// If the object is successfully removed, re-insert it with the new priority
Insert(head, val, newPriority);
return true;
}
return false; // Return false if the object with the specified ID is not found
}
void printQueue(PQNode* a)
{
PQNode* p = a;
while(p)
{
cout << p->key << " - " << p->priority << endl;
p = p->next;
}
}
int main()
{
PQNode *a;
int list[] = {1, 4, 5, 3, 2 ,7 ,6};
int priority[] = {1, 2, 3, 4, 5 ,6 ,7};
int n = 7;
for(int i = 0 ; i < n; ++i)
{
Insert(a, list[i], priority[i]);
}
printQueue(a);
cout << "After insert 10 : " << endl;
Insert(a, 10, 2);
printQueue(a);
Remove(a, 4);
printQueue(a);
}
```
## BST
+ Sử dụng dummyHead để gán hai node ý tưởng để khử đệ qui
```
#include <bits/stdc++.h>
using namespace std;
template<typename T>
class Stack {
private:
struct StackNode {
T data;
StackNode* next;
StackNode(T data) : data(data), next(nullptr) {}
};
StackNode* topNode;
public:
Stack() : topNode(nullptr) {}
~Stack() {
while (!isEmpty()) {
pop();
}
}
void push(T data) {
StackNode* newNode = new StackNode(data);
newNode->next = topNode;
topNode = newNode;
}
void pop() {
if (isEmpty()) {
return;
}
StackNode* temp = topNode;
topNode = topNode->next;
delete temp;
}
T top() {
if (!isEmpty()) {
return topNode->data;
}
return nullptr; // Handle this appropriately in your code
}
bool isEmpty() {
return topNode == nullptr;
}
};
struct NODE{ // AVL
int key;
NODE* pLeft;
NODE* pRight;
int height;
};
struct BSTNODE{
int key;
BSTNODE* pLeft;
BSTNODE* pRight;
};
BSTNODE* createNode(int data){
BSTNODE* pNode = new BSTNODE;
pNode->key = data;
pNode->pLeft = NULL;
pNode->pRight = NULL;
return pNode;
}
NODE* createNodeAVL(int data){
NODE* pNode = new NODE;
pNode->key = data;
pNode->height = 0;
pNode->pLeft = nullptr;
pNode->pRight = nullptr;
return pNode;
}
void Insert(BSTNODE* &pRoot, int x){
if (pRoot == NULL)
pRoot = createNode(x);
else if (x < pRoot->key)
Insert(pRoot->pLeft, x);
else if (x > pRoot->key)
Insert(pRoot->pRight, x);
}
void Insert(BSTNODE*& dummyHead, BSTNODE*& root, int x)
{
if(root == nullptr)
{
root = createNode(x);
return;
}
BSTNODE* p1 = root; // p2 is parent of p1
BSTNODE* p2 = dummyHead;
while(p1 != nullptr)
{
if(p1->key == x)
return;
p2 = p1;
if(p1->key > x)
{
p1 = p1->pLeft;
}
else{
p1 = p1->pRight;
}
}
p1 = createNode(x);
if(p2->key > x)
{
p2->pLeft = p1;
}
else
{
p2->pRight = p1;
}
}
int Height(BSTNODE* pRoot){
if (pRoot == NULL)
return -1;
return max(Height(pRoot->pLeft), Height(pRoot->pRight)) + 1;
}
void printTree(BSTNODE* r, int indent = 0)
{
if (r != nullptr) {
if (r->pRight) {
printTree(r->pRight, indent + 5);
}
if (indent > 0) {
cout << setw(indent) << " ";
}
cout << "[" << r->key << "]" << endl;
if (r->pLeft) {
printTree(r->pLeft, indent + 5);
}
}
}
void printTree(NODE* r, int indent = 0)
{
if (r != nullptr) {
if (r->pRight) {
printTree(r->pRight, indent + 5);
}
if (indent > 0) {
cout << setw(indent) << " ";
}
cout << "[" << r->key << "]" << endl;
if (r->pLeft) {
printTree(r->pLeft, indent + 5);
}
}
}
void createTree(BSTNODE*& dummy, BSTNODE*& root, int a[], int n)
{
if(n <= 0)
return;
for(int i = 0 ; i < n; ++i)
{
Insert(dummy, root, a[i]);
}
}
// 6. Level-order Traversal:
void LevelOrder(BSTNODE* pRoot){
if (pRoot == NULL)
return;
queue<BSTNODE*> Q;
Q.push(pRoot);
while (!Q.empty()){
BSTNODE* p = Q.front();
Q.pop();
cout << p->key << " ";
if (p->pLeft != NULL)
Q.push(p->pLeft);
if (p->pRight != NULL)
Q.push(p->pRight);
}
}
// BSTNODE* Search(BSTNODE* pRoot, int x){
// if (pRoot == NULL)
// return NULL;
// if (x == pRoot->key)
// return pRoot;
// else if (x < pRoot->key)
// return Search(pRoot->pLeft, x);
// else
// return Search(pRoot->pRight, x);
// }
BSTNODE* Search(BSTNODE* root, int x)
{
if(root == nullptr)
return root;
BSTNODE* p1 = root;
while(p1 != nullptr)
{
if(p1->key == x)
return p1;
if(p1->key > x)
{
p1 = p1->pLeft;
}
else{
p1 = p1->pRight;
}
}
return nullptr;
}
BSTNODE* findRightMostNode(BSTNODE* pRoot){
// pRoot must be not null
if (pRoot->pRight == NULL)
return pRoot;
return findRightMostNode(pRoot->pRight);
}
void Del(BSTNODE*& root, int x)
{
if(root == nullptr)
return;
if(root->key < x)
Del(root->pRight, x);
else if (root->key > x)
Del(root->pLeft, x);
else
{
if(root->pLeft == nullptr && root->pRight == nullptr) // no child
{
delete root;
root = nullptr;
}
else if (root->pLeft == nullptr || root->pRight == nullptr)
{
if(root->pLeft == nullptr)
{
BSTNODE* tmp = root->pRight;
delete root;
root = tmp;
}
else
{
BSTNODE* tmp = root->pLeft;
delete root;
root = tmp;
}
}
else
{
BSTNODE* rightMost = findRightMostNode(root->pLeft);
root->key = rightMost->key;
Del(root->pLeft, rightMost->key);
}
}
}
void DeleteNode(BSTNODE*& root, int x) { # Non-recursive
BSTNODE* parent = nullptr;
BSTNODE* current = root;
// Tìm node cần xoá
while (current != nullptr && current->key != x) {
parent = current;
if (x < current->key) {
current = current->pLeft;
} else {
current = current->pRight;
}
}
// Nếu không tìm thấy node cần xoá
if (current == nullptr) {
return;
}
// Nếu node có hai con
if (current->pLeft != nullptr && current->pRight != nullptr) {
BSTNODE* successor = current->pRight;
BSTNODE* successorParent = current;
// Tìm node kế cận (node có giá trị nhỏ nhất trong cây con phải của current)
while (successor->pLeft != nullptr) {
successorParent = successor;
successor = successor->pLeft;
}
// Copy giá trị của successor vào current
current->key = successor->key;
// Di chuyển current và parent đến node kế cận để xoá
current = successor;
parent = successorParent;
}
// Node có một hoặc không có con
BSTNODE* child = (current->pLeft != nullptr) ? current->pLeft : current->pRight;
// Xác định node cần xoá là con trái hay con phải của parent
if (parent == nullptr) {
root = child;
} else if (parent->pLeft == current) {
parent->pLeft = child;
} else {
parent->pRight = child;
}
// Xoá node
delete current;
}
```
## AVL
```jk
int getHeight(NODE* root)
{
if(root == nullptr)
return 0;
return max(getHeight(root->pLeft), getHeight(root->pRight)) + 1;
}
void UpdateHeight(NODE*& p){
if (p == nullptr) return;
p->height = max(getHeight(p->pLeft), getHeight(p->pRight)) + 1;
}
NODE* LeftRotation(NODE* pRoot){
NODE* child = pRoot->pRight;
pRoot->pRight = child->pLeft;
child->pLeft = pRoot;
UpdateHeight(pRoot);
UpdateHeight(child);
return child;
}
NODE* RightRotation(NODE* pRoot){
NODE* child = pRoot->pLeft;
pRoot->pLeft = child->pRight;
child->pRight = pRoot;
UpdateHeight(pRoot);
UpdateHeight(child);
return child;
}
int BalanceFactor(NODE* p){
if (p == NULL) return 0;
return getHeight(p->pLeft) - getHeight(p->pRight);
}
void Balance(NODE*& pRoot){
if (pRoot == NULL)
return;
UpdateHeight(pRoot);
int balanceFactor = BalanceFactor(pRoot);
if (abs(balanceFactor) <= 1)
return;
// Left Left
if (balanceFactor > 1 && BalanceFactor(pRoot->pLeft) >= 0){
pRoot = RightRotation(pRoot);
}
// Right Right
else if (balanceFactor < -1 && BalanceFactor(pRoot->pRight) < 0){
pRoot = LeftRotation(pRoot);
}
// Left Right
else if (balanceFactor > 1 && BalanceFactor(pRoot->pLeft) < 0){
pRoot->pLeft = LeftRotation(pRoot->pLeft);
pRoot = RightRotation(pRoot);
}
// Right Left
else if(balanceFactor < -1 && BalanceFactor(pRoot->pRight) >= 0){
pRoot->pRight = RightRotation(pRoot->pRight);
pRoot = LeftRotation(pRoot);
}
}
void Insert(NODE* &pRoot, int x){
if (pRoot == nullptr){
pRoot = createNodeAVL(x);
return;
}
if (x < pRoot->key){
Insert(pRoot->pLeft, x);
UpdateHeight(pRoot->pLeft);
}
else if (x > pRoot->key){
Insert(pRoot->pRight, x);
UpdateHeight(pRoot->pRight);
}
else
return;
Balance(pRoot);
}
void RemoveRightmost(NODE*& pRoot, NODE*& tmp){
if (pRoot->pRight != NULL){
RemoveRightmost(pRoot->pRight, tmp);
}
else{
tmp->key = pRoot->key;
tmp = pRoot;
pRoot = pRoot->pLeft;
delete tmp;
}
Balance(pRoot);
}
void Remove(NODE* &pRoot, int x){
if (pRoot == NULL)
return;
if (x < pRoot->key)
Remove(pRoot->pLeft, x);
else if (x > pRoot->key)
Remove(pRoot->pRight, x);
else{
// FOUND
NODE* tmp = pRoot;
if (pRoot->pLeft == NULL){
pRoot = pRoot->pRight;
delete tmp;
}
else if (pRoot->pRight == NULL){
pRoot = pRoot->pLeft;
delete tmp;
}
else
RemoveRightmost(pRoot->pLeft, tmp);
}
Balance(pRoot);
}
void balanceTree(NODE*& node) {
if (node == nullptr) {
return;
}
// Balance the left subtree
balanceTree(node->pLeft);
// Balance the right subtree
balanceTree(node->pRight);
// Get the balance factor of this node to check whether
// this node became unbalanced
int balance = BalanceFactor(node);
// If this node becomes unbalanced, then there are 4 cases
// Left Left Case
if (balance > 1 && BalanceFactor(node->pLeft) >= 0) {
node = RightRotation(node);
}
// Left Right Case
if (balance > 1 && BalanceFactor(node->pLeft) < 0) {
node->pLeft = LeftRotation(node->pLeft);
node = RightRotation(node);
}
// Right Right Case
if (balance < -1 && BalanceFactor(node->pRight) <= 0) {
node = LeftRotation(node);
}
// Right Left Case
if (balance < -1 && BalanceFactor(node->pRight) > 0) {
node->pRight = RightRotation(node->pRight);
node = LeftRotation(node);
}
// Return the node pointer
}
void InsertNonRecursive(NODE*& root, int x) {
Stack<NODE**> path;
// Find the position to insert the new node
NODE** p = &root;
while (*p != nullptr) {
path.push(p); // Store the path for later balancing
if (x < (*p)->key) {
p =&((*p)->pLeft);
} else if (x > (*p)->key) {
p =&((*p)->pRight);
} else { // Element already exists
return;
}
}
// Create new node
*p = createNodeAVL(x);
// Traverse back up the tree and balance each node
while (!path.isEmpty()) {
p = path.top();
path.pop();
if(abs(BalanceFactor(*p)) > 1)
{
UpdateHeight(*p);
Balance(*p);
break; // Dung lai khi gap nut mat can bang
}
}
UpdateHeight(root);
}
void RemoveNonRecursive(NODE*& root, int x) {
Stack<NODE*> path;
NODE* p = root;
NODE* parent = nullptr;
// Tìm node cần xoá
while (p != nullptr && (p)->key != x) {
path.push(p); // Store the path for later balancing
parent = p;
if (x < (p)->key) {
p = ((p)->pLeft);
} else if (x > p->key){
p = ((p)->pRight);
}
else
break;
}
// Nếu không tìm thấy node cần xoá
if (p == nullptr) {
return;
}
// Nếu node có hai con
if (p->pLeft != nullptr && p->pRight != nullptr) {
NODE* successor = p->pRight;
NODE* successorParent = p;
// Tìm node kế cận (node có giá trị nhỏ nhất trong cây con phải của current)
while (successor->pLeft != nullptr) {
path.push(successorParent);
successorParent = successor;
successor = successor->pLeft;
}
// Copy giá trị của successor vào current
p->key = successor->key;
// Di chuyển current và parent đến node kế cận để xoá
p = successor;
parent = successorParent;
}
// Node có một hoặc không có con
NODE* child = (p->pLeft != nullptr) ? p->pLeft : p->pRight;
// Xác định node cần xoá là con trái hay con phải của parent
if (parent == nullptr) {
root = child;
} else if (parent->pLeft == p) {
parent->pLeft = child;
} else {
parent->pRight = child;
}
// Xoá node
delete p;
// Traverse back up the tree and balance each node
while (!path.isEmpty()) {
p = path.top();
path.pop();
if(abs(BalanceFactor(p)) >= 1)
{
UpdateHeight(p);
Balance(p);
}
}
}
int main()
{
int a[] = {3,2,4,5,6,7,2,3,5};
int n = sizeof(a)/sizeof(a[0]);
BSTNODE* dummyHead = new BSTNODE;
BSTNODE* root = nullptr;
dummyHead->pRight = root;
createTree(dummyHead, root, a, n);
//LevelOrder(root);
// printTree(root);
// BSTNODE* node = Search(root, 7);
// cout << node->key << endl;
// DeleteNode(root, 3);
// printTree(root);
// DeleteNode(root, 2);
// printTree(root);
// AVL Tree
NODE* AVL_root = nullptr;
for(int i = 0; i < n ; ++i)
{
InsertNonRecursive(AVL_root, a[i]);
//printTree(AVL_root, a[i]);
}
printTree(AVL_root);
cout <<"-------------------------\n";
InsertNonRecursive(AVL_root,8);
printTree(AVL_root);
cout <<"-------------------------\n";
RemoveNonRecursive(AVL_root,5);
printTree(AVL_root);
cout <<"-------------------------\n";
RemoveNonRecursive(AVL_root,4);
printTree(AVL_root);
cout <<"-------------------------\n";
RemoveNonRecursive(AVL_root,6);
printTree(AVL_root);
}
```
## Đỏ đen
```
#include <iostream>
using namespace std;
struct RBNode{
int key;
bool color; //Black = 0
RBNode* parent;
RBNode* left;
RBNode* right;
};
RBNode* nil;
RBNode* getNode(int key, int color, RBNode* nil)
{
RBNode* p = new RBNode;
p->key = key;
p->color = color;
p->left = p->right = p->parent = nil;
return p;
}
void leftRotate(RBNode*& root, RBNode* x)
{
RBNode* y = x->right;
x->right = y->left;
if (y->left != nil)
{
y->left->parent = x;
}
y->parent = x->parent;
if(x->parent == nil)
{
root = y;
}
else
{
if(x->parent->left == x)
{
x->parent->left = y;
}
else
x->parent->right = y;
}
y->left = x;
x->parent = y;
}
void rightRotate(RBNode*& root, RBNode* x)
{
RBNode* y = x->left;
x->left = y->right;
if (y->right != nil)
{
y->right->parent = x;
}
y->parent = x->parent;
if(x->parent == nil)
{
root = y;
}
else
{
if(x->parent->left == x)
{
x->parent->left = y;
}
else
x->parent->right = y;
}
y->right = x;
x->parent = y;
}
void insertLeftAdjust(RBNode* &pRoot, RBNode* ref) { // parent in left side
RBNode* p = ref->parent->parent->right;
if (p->color == true) { //case 1
ref->parent->color = false;
p->color = false;
ref->parent->parent->color = true;
ref = ref->parent->parent;
} else {
//Case 2 or case 3
if (ref == ref->parent->right) {
ref = ref->parent;
leftRotate(pRoot, ref);
}
//case 3
ref->parent->color = false;
ref->parent->parent->color = true;
rightRotate(pRoot, ref->parent->parent);
}
}
void insertRightAdjust(RBNode* &pRoot, RBNode* ref) {
RBNode* p = ref->parent->parent->left;
if (p->color == true) {
ref->parent->color = false;
p->color = false;
ref->parent->parent->color = true;
ref = ref->parent->parent;
} else {
if (ref == ref->parent->left) {
ref = ref->parent;
rightRotate(pRoot, ref);
}
ref->parent->color = false;
ref->parent->parent->color = true;
leftRotate(pRoot, ref->parent->parent);
}
}
void inserFixedUp(RBNode* &pRoot, RBNode* ref) {
while (ref->parent->color == true) {
if (ref->parent == ref->parent->parent->left) {
insertLeftAdjust(pRoot, ref);
} else {
insertRightAdjust(pRoot, ref);
}
}
pRoot->color = false;
}
void BST_Insert(RBNode*& root, RBNode* x)
{
RBNode* y = nil;
RBNode* z = root;
while(z != nil)
{
y = z;
if(x->key < z->key)
z = z->left;
else if(x->key > z->key)
z = z->right;
else
return;
}
x->parent = y;
if(y == nil)
root = x;
else
{
if(x->key < y->key)
y->left = x;
else
y->right = x;
}
}
void insert(RBNode*& root, int key)
{
RBNode* x = getNode(key, true, nil);
BST_Insert(root, x);
inserFixedUp(root, x);
}
RBNode* createTree(int a[], int n) {
RBNode* pRoot = nil;
for (int i = 0; i < n; i++) {
insert(pRoot, a[i]);
}
return pRoot;
}
RBNode* lookUp(RBNode* pRoot, int key) {
RBNode* ans = pRoot;
while (ans != nil) {
if (ans->key == key) {
return ans;
}
if (ans->key > key) {
ans = ans->left;
} else {
ans = ans->right;
}
}
return nil;
}
int blackHeight(RBNode* pRoot) {
if (pRoot == nil) {
return 1;
}
int leftBlackHeight = blackHeight(pRoot->left);
int rightBlackHeight = blackHeight(pRoot->right);
if (leftBlackHeight != rightBlackHeight) {
return 0;
}
if (pRoot->color == false) {
leftBlackHeight++;
}
return leftBlackHeight;
}
void removeLeftAdjust(RBNode* pRoot, RBNode* ref) {
RBNode* p = ref->parent->right;
if (p->color == true) {
p->color = false;
ref->parent->color = true;
leftRotate(pRoot, ref->parent);
p = ref->parent->right;
}
if (p->right->color == false && p->left->color == false) {
p->color = true;
ref = ref->parent;
} else {
if (p->right->color == false) {
p->left->color = false;
p->color = true;
rightRotate(pRoot, p);
p = ref->parent->right;
}
p->color = ref->parent->color;
ref->parent->color = false;
p->right->color = false;
leftRotate(pRoot, ref->parent);
ref = pRoot;
}
}
void removeRightAdjust(RBNode* pRoot, RBNode* ref) {
RBNode* p = ref->parent->left;
if (p->color == true) {
p->color = false;
ref->parent->color = true;
rightRotate(pRoot, ref->parent);
p = ref->parent->left;
}
if (p->left->color == false && p->right->color == false) {
p->color = true;
ref = ref->parent;
} else {
if (p->left->color == false) {
p->right->color = false;
p->color = true;
leftRotate(pRoot, p);
p = ref->parent->left;
}
p->color = ref->parent->color;
ref->parent->color = false;
p->left->color = false;
rightRotate(pRoot, ref->parent);
ref = pRoot;
}
}
void removeFixedUp(RBNode* pRoot, RBNode* ref) {
while ((ref->color == false) && (ref != pRoot)) {
if (ref == ref->parent->left) {
removeLeftAdjust(pRoot, ref);
} else {
removeRightAdjust(pRoot, ref);
}
}
ref->color = false;
}
RBNode* minimum(RBNode* pRoot, RBNode* ref) {
while (ref->left != nil) {
ref = ref->left;
}
return ref;
}
RBNode* maximum(RBNode* pRoot, RBNode* ref) {
while (ref->right != nil) {
ref = ref->right;
}
return ref;
}
RBNode* treeSuccessor(RBNode* pRoot, RBNode* ref) {
if (ref->right != nil) {
return minimum(pRoot, ref->right);
}
RBNode* y = ref->parent;
while (y != nil && ref == y->right) {
ref = y;
y = y->parent;
}
return y;
}
//return 0 if key does not appear in tree, therefore cannot remove
//return 1 if successfully remove
int remove(RBNode* pRoot, int key) {
RBNode* pFind = lookUp(pRoot, key);
if (pFind == nil) {
return 0;
}
RBNode* y;
if (pFind->left == nil || pFind->right == nil) {
y = pFind;
} else {
y = treeSuccessor(pRoot, pFind);
}
RBNode* x;
if (y->left != nil) {
x = y->left;
} else {
x = y->right;
}
if (x != nil) {
x->parent = y->parent;
}
if (y->parent == nil) {
pRoot = x;
} else if (y == y->parent->left) {
y->parent->left = x;
} else {
y->parent->right = x;
}
if (y != pFind) {
pFind->key = y->key;
}
if (y->color == false) {
removeFixedUp(pRoot, x);
}
delete y;
}
int main(){
nil = new RBNode;
nil->color = false;
nil->left = nil->right = nil->parent = nil;
RBNode* root = nil;
}
```
## Graph
```
Prim(G, root) {
for (each vertex v in V) {
v.dist = INF;
v.parent = NIL;
}
root.dist = 0; VT = ∅;
createQueue(Q, V);
while (!isEmpty(Q)){
v* = extractQueue(Q);
add v* to VT;
for (each v in Q that is adjacent to v*)
if (G[v*][v] < v.dist) {
v.dist = G[v*][v];
v.parent = v*;
updateQueue(Q, v);
}
}
}
```
```
void Prim(Graph g, int root)
{
int len = g.getV();
prim* lst = new prim[len];
for(int i = 0 ; i < len ; ++i)
{
lst[i].priority = i + 1;
lst[i].dist = INFINITY;
lst[i].parent = nullptr;
}
lst[root].dist = 0;
p_queue* Q = nullptr;
createQueue(Q, lst, len);
while(Q->len > 0)
{
prim v_star = Extract(Q,Q->len);
// DUyet ma tran trong so de lay ra cac dinh ke cua v_star roi thuc hien nhu ma gia
}
}
```
```
Dijkstra(G(V, E), source) {
for (each vertex v ! V) {
v.dist = ";
v.parent = NIL;
}
source.dist = 0; VT = #;
createQueue(Q, V);
while (!isEmpty(Q)) {
v* = extractQueue(Q);
add v* to VT;
for (each v ! Q that is adjacent to v*)
if (v*.dist + G[v*][v] < v.dist) {
v.parent = v*;
v.dist = v*.dist + G[v*][v];
updateQueue(Q, v);
}
}
}
```