#include<iostream> #include<vector> #include<queue> #include<string> #include<stack> using namespace std; /* 二叉搜索樹比二叉樹多一個性質,左節點的值小於父節點的值,右節點的值大於等於父節點的值 二叉搜索樹右能夠排序,平衡二叉搜索樹有紅黑樹,AVL樹,此處僅是通常二叉搜索樹。 二叉搜索樹一般設計比通常二叉樹多一個父節點域,不然要反覆找出某個節點的父節點 */ struct Node { int key; Node* left; Node* right; Node* parent; Node(int a) { key = a; left = right=parent=nullptr; } ///爲了代碼簡潔,此處二叉樹節點比較僅僅比較值是否相等 bool operator==(Node * other) { return key == other->key; } bool operator!=(Node* other) { return key != other->key; } }; ///返回以p爲樹根的樹中最大節點 Node* maxNode(Node* p) { if (p->right != nullptr) { while (p->right) { p = p->right; } } return p; } ///返回以p爲樹根的樹中最小節點 Node* minNode(Node* p) { if (p->left != nullptr) { while (p->left) { p = p->left; } } return p; } /* 返回節點p的後繼若不存在返回nullptr */ Node* successor(Node* root, Node* p) { Node* result = nullptr; if (p->right != nullptr) { result = minNode(p->right); } else { while (p->parent!=nullptr&&p->parent->right == p) { p = p->parent; } if (p->parent != nullptr) { result = p->parent; } } return result; } Node* pressor(Node* root, Node* p) { Node* result = nullptr; if (p->left != nullptr) { result = maxNode(p->left); } else { while (p->parent != nullptr&&p->parent->left == p) { p = p->parent; } if (p->parent != nullptr) { result = p->parent; } } return result; } Node* insertNode(Node* root, int k) { if (root == nullptr) { root = new Node(k); return root; } else { Node* p=root,*q = root; Node*temp = new Node(k); while (p) { if (k < p->key) { q = p; p = p->left; } else { q = p; p = p->right; } } if (k < q->key) { q->left = temp; temp->parent = q; } else { q->right = temp; temp->parent = q; } } return root; } /* 找出一個節點的值等於k */ Node* searchNode(Node* root, int k) { Node* p = root; while (p) { if (p->key == k) { return p; } else if (k < p->key) { p = p->left; } else { p = p->right; } } return p; } Node* deleteNode(Node* root, Node* p) { if (root == nullptr||p==nullptr)return root; if (p->left == nullptr || p->right == nullptr) { if (p->left != nullptr) { Node* temp = p->left; temp->parent = p->parent; if (p->parent != nullptr) ///p不是根節點 { if (p->parent->left == p) p->parent->left = temp; else p->parent->right = temp; } else ///p是根節點 { root = temp; } delete p; p = nullptr; } else if (p->right != nullptr) { Node* temp = p->right; temp->parent = p->parent; if (p->parent != nullptr) { if (p->parent->left == p) p->parent->left = temp; else p->parent->right = temp; } else { root = temp; } delete p; p = nullptr; } else { if (p ->parent== nullptr) root = nullptr; else { if (p->parent->left == p) p->parent->left = nullptr; else p->parent->right = nullptr; } delete p; p = nullptr; } } else ///p的兩個孩子都不爲空 { Node* temp = minNode(p->right); p->key = temp->key; ///此時temp的左孩子確定爲nullptr, if (temp->right != nullptr) { temp->right->parent = temp->parent; if (temp->parent->left == temp) temp->parent->left = temp->right; else temp->parent->right = temp->right; } else { if (temp->parent->right == temp) temp->parent->right = nullptr; else temp->parent->left = nullptr; } delete temp; } return root; } /* 刪除全部值爲k的節點 */ Node* deleteNode(Node* root, int k) { Node* p = searchNode(root, k); while (p!=nullptr&&p->key==k) { root=deleteNode(root, p); ////這裏犯了一個錯誤,查找了半天還一直覺得刪除節點出了問題,指針果真nb ///通過上一步指針p指向的空間已經被刪除了,因此下一步尋找p的後繼會出錯。 p = searchNode(root,k); } return root; } Node* buildTree(int a[], int n) { Node* root = nullptr; for (int i = 0; i < n; i++) { root = insertNode(root, a[i]); } return root; } void tree_sort(Node* root) { if (root == nullptr)return; Node* p = minNode(root); while (p != nullptr) { cout << p->key << " "; p = successor(root, p); } cout << endl; p = maxNode(root); while (p != nullptr) { cout << p->key << " "; p = pressor(root, p); } cout << endl; } void levelOrder3(Node* p) { if (p == nullptr)return; queue<Node*>qu; qu.push(p); while (!qu.empty()) { p = qu.front(); cout << p->key << " "; qu.pop(); if (p->left != nullptr) { qu.push(p->left); } if (p->right != nullptr) { qu.push(p->right); } } } /* int main() { const int len = 30; int a[len]; srand(1); for (int i = 0; i < len; i++) { a[i] = rand() % 30; if (a[i] == 0)a[i] += 1; } a[0] = 15; cout << endl << "=======數組a=====" << endl; for (int i = 0; i < len; i++) { cout << a[i] << " "; } cout << endl; Node* root=buildTree(a, len); cout << endl << "=======逐層遍歷=====" << endl; levelOrder3(root); cout << endl<<"=======排序====="<<endl; tree_sort(root); cout << endl; while (true) { int m; cin >> m; root = deleteNode(root, m); cout << endl << "=======逐層=====" << endl; levelOrder3(root); cout << endl; cout << endl << "=======排序=====" << endl; tree_sort(root); } } */