commit 7f65649d3cef6d02f61357329a85fcd861aef028 Author: Lenyiin <569963146@qq.com> Date: Sun Sep 15 23:55:07 2024 +0800 博客 https://blog.lenyiin.com/avltree/ 的代码仓库 diff --git a/Linux/AVLTree.hpp b/Linux/AVLTree.hpp new file mode 100644 index 0000000..98fe7df --- /dev/null +++ b/Linux/AVLTree.hpp @@ -0,0 +1,612 @@ +#pragma once + +#include +#include +#include + +namespace Lenyiin +{ + template + struct AVLTreeNode + { + AVLTreeNode *_left; + AVLTreeNode *_right; + AVLTreeNode *_parent; + + int _bf; // balance factor 平衡因子 + std::pair _kv; // key-value + + // 普通构造 + AVLTreeNode(const std::pair &kv) + : _left(nullptr), _right(nullptr), _parent(nullptr), _bf(0), _kv(kv) + { + } + }; + + template + class AVLTree + { + private: + typedef AVLTreeNode Node; + + public: + bool Insert(const std::pair &kv) + { + // 1. 先按搜索树的规则进行插入 + if (_root == nullptr) + { + _root = new Node(kv); + return true; + } + + Node *parent = nullptr; + Node *cur = _root; + while (cur) + { + if (cur->_kv.first > kv.first) + { + parent = cur; + cur = cur->_left; + } + else if (cur->_kv.first < kv.first) + { + parent = cur; + cur = cur->_right; + } + else + { + return false; // 如果相等, 表示已经有了, 不需要插入 + } + } + + // 找到位置 + cur = new Node(kv); + if (parent->_kv.first > kv.first) + { + parent->_left = cur; + cur->_parent = parent; + } + else + { + parent->_right = cur; + cur->_parent = parent; + } + + // 2. 更新平衡因子 + while (parent) + { + if (cur == parent->_right) + { + parent->_bf++; // 插在右边, 平衡因子++ + } + else + { + parent->_bf--; // 插在左边, 平衡因子-- + } + + if (parent->_bf == 0) + { + // 说明 parent 所在的子树高度不变, 更新结束 + break; + } + else if (parent->_bf == 1 || parent->_bf == -1) + { + // 说明 parent 所在子树的高度变了, 继续往上更新 + cur = parent; + parent = parent->_parent; + } + else if (parent->_bf == 2 || parent->_bf == -2) + { + // parent 所在的子树出现问题了, 需要旋转处理一下 + // 1. 旋转前提是保持它依旧是搜索二叉树 + // 2. 旋转成平衡树 + if (parent->_bf == 2) + { + if (cur->_bf == 1) + { + // 左旋 + RotateL(parent); + } + else if (cur->_bf == -1) + { + // 右左双旋 + RotateRL(parent); + } + } + else if (parent->_bf == -2) + { + if (cur->_bf == -1) + { + // 右旋 + RotateR(parent); + } + else if (cur->_bf == 1) + { + // 左右双旋 + RotateLR(parent); + } + } + + // 旋转完成后, parent 所在的树的高度恢复到了插入节点前的高度 + // 如果是子树, 对上一层没有影响, 更新结束 + break; + } + } + + return true; + } + + // 左单旋 + void RotateL(Node *parent) + { + Node *ppNode = parent->_parent; + Node *subR = parent->_right; + Node *subRL = subR->_left; + + parent->_right = subRL; + if (subRL) + { + subRL->_parent = parent; + } + subR->_left = parent; + parent->_parent = subR; + + // 1. 原来 parent 是这棵树的根, 现在 subR 是根 + if (parent == _root) + { + _root = subR; + subR->_parent = nullptr; + } + // 2. parent 为根的树只是整棵树中的子树, 改变链接关系, 那么 subR 要顶替他的位置 + else + { + if (ppNode->_left == parent) + { + ppNode->_left = subR; + } + else + { + ppNode->_right = subR; + } + subR->_parent = ppNode; + } + + parent->_bf = subR->_bf = 0; + } + + // 右单旋 + void RotateR(Node *parent) + { + Node *ppNode = parent->_parent; + Node *subL = parent->_left; + Node *subLR = subL->_right; + + parent->_left = subLR; + if (subLR) + { + subLR->_parent = parent; + } + subL->_right = parent; + parent->_parent = subL; + + if (parent == _root) + { + _root = subL; + subL->_parent = nullptr; + } + else + { + if (ppNode->_left == parent) + { + ppNode->_left = subL; + } + else + { + ppNode->_right = subL; + } + subL->_parent = ppNode; + } + + parent->_bf = subL->_bf = 0; + } + + // 右左双旋 + void RotateRL(Node *parent) + { + Node *subR = parent->_right; + Node *subRL = subR->_left; + int bf = subRL->_bf; + + RotateR(parent->_right); + RotateL(parent); + + if (bf == -1) + { + parent->_bf = 0; + subR->_bf = 1; + subRL->_bf = 0; + } + else if (bf == 1) + { + parent->_bf = -1; + subR->_bf = 0; + subRL->_bf = 0; + } + else if (bf == 0) + { + parent->_bf = 0; + subR->_bf = 0; + subRL->_bf = 0; + } + } + + // 左右双旋 + void RotateLR(Node *parent) + { + Node *subL = parent->_left; + Node *subLR = subL->_right; + int bf = subLR->_bf; + + RotateL(subL); + RotateR(parent); + + if (bf == 1) + { + parent->_bf = 0; + subL->_bf = -1; + subLR->_bf = 0; + } + else if (bf == -1) + { + parent->_bf = 1; + subL->_bf = 0; + subLR->_bf = 0; + } + else if (bf == 0) + { + parent->_bf = 0; + subL->_bf = 0; + subLR->_bf = 0; + } + } + + // 中序遍历 + // void _InOrder(Node* root) + //{ + // if (root == nullptr) + // { + // return; + // } + + // _InOrder(root->_left); + // std::cout << root->_kv.first << ":" << root->_kv.second << std::endl; + // _InOrder(root->_right); + //} + + // void InOrder() + //{ + // _InOrder(_root); + // std::cout << std::endl; + // } + + // 中序遍历 非递归 + void InOrder() + { + std::stack stack; + Node *cur = _root; + + while (cur != nullptr || !stack.empty()) + { + // 找到最左边的节点 + while (cur != nullptr) + { + stack.push(cur); + cur = cur->_left; + } + + // 处理当前节点 + cur = stack.top(); + stack.pop(); + std::cout << cur->_kv.first << ":" << cur->_kv.second << std::endl; + + // 转向右子树 + cur = cur->_right; + } + std::cout << std::endl; + } + + // 前序遍历的递归实现 + // 辅助函数 + // void _PreOrder(Node* root) + //{ + // if (root == nullptr) + // { + // return; + // } + + // std::cout << root->_kv.first << ":" << root->_kv.second << std::endl; // 访问根节点 + // _PreOrder(root->_left); // 访问左子树 + // _PreOrder(root->_right); // 访问右子树 + //} + + // void PreOrder() + //{ + // _PreOrder(_root); + // std::cout << std::endl; + // } + + // 前序遍历的非递归实现 + void PreOrder() + { + if (_root == nullptr) + { + return; + } + + std::stack stack; + stack.push(_root); + + while (!stack.empty()) + { + Node *cur = stack.top(); + stack.pop(); + std::cout << cur->_kv.first << ":" << cur->_kv.second << std::endl; // 访问当前节点 + + // 先压入右子树再压入左子树(确保左子树先处理) + if (cur->_right != nullptr) + { + stack.push(cur->_right); + } + if (cur->_left != nullptr) + { + stack.push(cur->_left); + } + } + std::cout << std::endl; + } + + // 后序遍历的递归实现 + // 辅助函数 + // void _PostOrder(Node* root) { + // if (root == nullptr) + // { + // return; + // } + + // _PostOrder(root->_left); // 访问左子树 + // _PostOrder(root->_right); // 访问右子树 + // std::cout << root->_kv.first << ":" << root->_kv.second << std::endl; // 访问根节点 + //} + + // void PostOrder() + //{ + // _PostOrder(_root); + // std::cout << std::endl; + // } + + // 后序遍历的非递归实现 + void PostOrder() + { + if (_root == nullptr) + { + return; + } + + std::stack st; + Node *cur = _root; + Node *lastNode = nullptr; // 最近访问的节点 + while (cur || !st.empty()) + { + while (cur) + { + st.push(cur); + cur = cur->_left; + } + + Node *top = st.top(); + if ((top->_right == nullptr) || (lastNode == top->_right)) + { + std::cout << top->_kv.first << ":" << top->_kv.second << std::endl; + lastNode = top; + st.pop(); + } + else + { + cur = top->_right; + } + } + std::cout << std::endl; + } + + // 层序遍历 + void LevelOrder() + { + if (_root == nullptr) + { + return; + } + + std::queue queue; + queue.push(_root); + + while (!queue.empty()) + { + Node *cur = queue.front(); + queue.pop(); + std::cout << cur->_kv.first << ":" << cur->_kv.second << std::endl; // 访问当前节点 + + if (cur->_left != nullptr) + { + queue.push(cur->_left); // 将左子树压入队列 + } + if (cur->_right != nullptr) + { + queue.push(cur->_right); // 将右子树压入队列 + } + } + std::cout << std::endl; + } + + // 查找后继节点 + Node *findMin(Node *node) + { + while (node->_left != nullptr) + { + node = node->_left; + } + return node; + } + + Node *FindSuccessor(Node *node) + { + if (node->_right != nullptr) + { + return findMin(node->_right); + } + + Node *cur = _root; + Node *successor = nullptr; + while (cur != nullptr) + { + if (node->_kv.first < cur->_kv.first) + { + successor = cur; + cur = cur->_left; + } + else if (node->_kv.first > cur->_kv.first) + { + cur = cur->_right; + } + else + { + break; + } + } + return successor; + } + + // 查找前驱节点 + Node *findMax(Node *node) + { + while (node->_right != nullptr) + { + node = node->_right; + } + return node; + } + + Node *FindPredecessor(Node *node) + { + if (node->_left != nullptr) + { + return findMax(node->_left); + } + + Node *cur = _root; + Node *predecessor = nullptr; + while (cur != nullptr) + { + if (node->_kv.first < cur->_kv.first) + { + cur = cur->_left; + } + else if (node->_kv.first > cur->_kv.first) + { + predecessor = cur; + cur = cur->_right; + } + else + { + break; + } + } + return predecessor; + } + + // 获取树的高度 + int Height(Node *root) + { + if (root == nullptr) + { + return 0; + } + + int leftHeight = Height(root->_left); + int rightHeight = Height(root->_right); + + return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1; + } + + // 判断是否是平衡二叉树 + bool _IsBalance(Node *root) + { + if (root == nullptr) + { + return true; + } + + int leftHeight = Height(root->_left); + int rightHeight = Height(root->_right); + if (abs(leftHeight - rightHeight) > 1) + { + return false; + } + + return _IsBalance(root->_left) && _IsBalance(root->_right); + } + + bool IsBalance() + { + return _IsBalance(_root); + } + + // 查找 非递归 + // Node* Find(const K& key) + //{ + // Node* cur = _root; + // while (cur) + // { + // if (cur->_kv.first > key) + // { + // cur = cur->_left; + // } + // else if (cur->_kv.first < key) + // { + // cur = cur->_right; + // } + // else + // { + // return cur; + // } + // } + // return nullptr; + //} + + // 查找的递归实现 + // 辅助函数 + Node *_find(Node *root, const K &key) + { + if (root == nullptr || root->_kv.first == key) + { + return root; + } + if (key < root->_kv.first) + { + return _find(root->_left, key); + } + else + { + return _find(root->_right, key); + } + } + + // 查找节点 + Node *Find(const K &key) + { + return _find(_root, key); + } + + private: + Node *_root = nullptr; + }; +} \ No newline at end of file diff --git a/Linux/Main.cc b/Linux/Main.cc new file mode 100644 index 0000000..5b65994 --- /dev/null +++ b/Linux/Main.cc @@ -0,0 +1,58 @@ +#include "AVLTree.hpp" + +using namespace Lenyiin; + +void test_AVLTree() +{ + // int a[] = { 16, 3, 7, 11, 9, 26, 18, 14, 15 }; + int a[] = {4, 2, 6, 1, 3, 5, 15, 7, 16, 14}; + AVLTree t; + for (const auto &e : a) + { + t.Insert(std::make_pair(e, e)); + } + + t.InOrder(); + t.PreOrder(); + t.PostOrder(); + t.LevelOrder(); + std::cout << t.IsBalance() << std::endl; + + auto ret = t.Find(6); + if (ret == nullptr) + { + std::cout << "没有找到" << std::endl; + } + else + { + std::cout << "找到了" << std::endl; + std::cout << ret->_kv.first << ":" << ret->_kv.second << std::endl; + } + + auto pre = t.FindPredecessor(ret); + if (pre != nullptr) + { + std::cout << ret->_kv.first << " 的前驱节点是: " << pre->_kv.first << std::endl; + } + else + { + std::cout << "前驱节点为空" << std::endl; + } + + auto suc = t.FindSuccessor(ret); + if (suc != nullptr) + { + std::cout << ret->_kv.first << " 的后继节点是: " << suc->_kv.first << std::endl; + } + else + { + std::cout << "后继节点为空" << std::endl; + } +} + +int main() +{ + test_AVLTree(); + + return 0; +} \ No newline at end of file diff --git a/Linux/Makefile b/Linux/Makefile new file mode 100644 index 0000000..efa353d --- /dev/null +++ b/Linux/Makefile @@ -0,0 +1,6 @@ +main:Main.cc + g++ -o $@ $^ + +.PHONY:clean +clean: + rm -f main; \ No newline at end of file diff --git a/Linux/main b/Linux/main new file mode 100644 index 0000000..01b271f Binary files /dev/null and b/Linux/main differ diff --git a/Windows_AVLTree/.vs/Windows_AVLTree/FileContentIndex/3880893a-e572-49c9-a228-7aff0e07c65a.vsidx b/Windows_AVLTree/.vs/Windows_AVLTree/FileContentIndex/3880893a-e572-49c9-a228-7aff0e07c65a.vsidx new file mode 100644 index 0000000..d6fea0f Binary files /dev/null and b/Windows_AVLTree/.vs/Windows_AVLTree/FileContentIndex/3880893a-e572-49c9-a228-7aff0e07c65a.vsidx differ diff --git a/Windows_AVLTree/.vs/Windows_AVLTree/FileContentIndex/78e79c59-a728-40b8-90fc-843661b4372d.vsidx b/Windows_AVLTree/.vs/Windows_AVLTree/FileContentIndex/78e79c59-a728-40b8-90fc-843661b4372d.vsidx new file mode 100644 index 0000000..bd93eca Binary files /dev/null and b/Windows_AVLTree/.vs/Windows_AVLTree/FileContentIndex/78e79c59-a728-40b8-90fc-843661b4372d.vsidx differ diff --git a/Windows_AVLTree/.vs/Windows_AVLTree/FileContentIndex/ebfa8e33-2a40-4893-88ea-49a6ddb83f5a.vsidx b/Windows_AVLTree/.vs/Windows_AVLTree/FileContentIndex/ebfa8e33-2a40-4893-88ea-49a6ddb83f5a.vsidx new file mode 100644 index 0000000..c4c4484 Binary files /dev/null and b/Windows_AVLTree/.vs/Windows_AVLTree/FileContentIndex/ebfa8e33-2a40-4893-88ea-49a6ddb83f5a.vsidx differ diff --git a/Windows_AVLTree/.vs/Windows_AVLTree/v17/.suo b/Windows_AVLTree/.vs/Windows_AVLTree/v17/.suo new file mode 100644 index 0000000..c6d9005 Binary files /dev/null and b/Windows_AVLTree/.vs/Windows_AVLTree/v17/.suo differ diff --git a/Windows_AVLTree/.vs/Windows_AVLTree/v17/Browse.VC.db b/Windows_AVLTree/.vs/Windows_AVLTree/v17/Browse.VC.db new file mode 100644 index 0000000..4194308 Binary files /dev/null and b/Windows_AVLTree/.vs/Windows_AVLTree/v17/Browse.VC.db differ diff --git a/Windows_AVLTree/.vs/Windows_AVLTree/v17/ipch/AutoPCH/7d06ce2963e52a2c/AVLTREE.ipch b/Windows_AVLTree/.vs/Windows_AVLTree/v17/ipch/AutoPCH/7d06ce2963e52a2c/AVLTREE.ipch new file mode 100644 index 0000000..8c6dc16 Binary files /dev/null and b/Windows_AVLTree/.vs/Windows_AVLTree/v17/ipch/AutoPCH/7d06ce2963e52a2c/AVLTREE.ipch differ diff --git a/Windows_AVLTree/.vs/Windows_AVLTree/v17/ipch/AutoPCH/dd9557299af24ae5/AVLTREE.ipch b/Windows_AVLTree/.vs/Windows_AVLTree/v17/ipch/AutoPCH/dd9557299af24ae5/AVLTREE.ipch new file mode 100644 index 0000000..1245f31 Binary files /dev/null and b/Windows_AVLTree/.vs/Windows_AVLTree/v17/ipch/AutoPCH/dd9557299af24ae5/AVLTREE.ipch differ diff --git a/Windows_AVLTree/AVLTree.cpp b/Windows_AVLTree/AVLTree.cpp new file mode 100644 index 0000000..9f1a7de --- /dev/null +++ b/Windows_AVLTree/AVLTree.cpp @@ -0,0 +1,58 @@ +#include "AVLTree.hpp" + +using namespace Lenyiin; + +void test_AVLTree() +{ + //int a[] = { 16, 3, 7, 11, 9, 26, 18, 14, 15 }; + int a[] = { 4, 2, 6, 1, 3, 5, 15, 7, 16, 14 }; + AVLTree t; + for (const auto& e : a) + { + t.Insert(std::make_pair(e, e)); + } + + t.InOrder(); + t.PreOrder(); + t.PostOrder(); + t.LevelOrder(); + std::cout << t.IsBalance() << std::endl; + + auto ret = t.Find(6); + if (ret == nullptr) + { + std::cout << "ûҵ" << std::endl; + } + else + { + std::cout << "ҵ" << std::endl; + std::cout << ret->_kv.first << ":" << ret->_kv.second << std::endl; + } + + auto pre = t.FindPredecessor(ret); + if (pre != nullptr) + { + std::cout << ret->_kv.first << " ǰڵ: " << pre->_kv.first << std::endl; + } + else + { + std::cout << "ǰڵΪ" << std::endl; + } + + auto suc = t.FindSuccessor(ret); + if (suc != nullptr) + { + std::cout << ret->_kv.first << " ĺ̽ڵ: " << suc->_kv.first << std::endl; + } + else + { + std::cout << "̽ڵΪ" << std::endl; + } +} + +int main() +{ + test_AVLTree(); + + return 0; +} \ No newline at end of file diff --git a/Windows_AVLTree/AVLTree.hpp b/Windows_AVLTree/AVLTree.hpp new file mode 100644 index 0000000..01bd209 --- /dev/null +++ b/Windows_AVLTree/AVLTree.hpp @@ -0,0 +1,605 @@ +#pragma once + +#include +#include +#include + +namespace Lenyiin +{ + template + struct AVLTreeNode + { + AVLTreeNode* _left; + AVLTreeNode* _right; + AVLTreeNode* _parent; + + int _bf; // balance factor ƽ + std::pair _kv; // key-value + + // ͨ + AVLTreeNode(const std::pair& kv) + : _left(nullptr), _right(nullptr), _parent(nullptr), _bf(0), _kv(kv) + {} + }; + + template + class AVLTree + { + private: + typedef AVLTreeNode Node; + + public: + bool Insert(const std::pair& kv) + { + // 1. ȰĹв + if (_root == nullptr) + { + _root = new Node(kv); + return true; + } + + Node* parent = nullptr; + Node* cur = _root; + while (cur) + { + if (cur->_kv.first > kv.first) + { + parent = cur; + cur = cur->_left; + } + else if (cur->_kv.first < kv.first) + { + parent = cur; + cur = cur->_right; + } + else + { + return false; // , ʾѾ, Ҫ + } + } + + // ҵλ + cur = new Node(kv); + if (parent->_kv.first > kv.first) + { + parent->_left = cur; + cur->_parent = parent; + } + else + { + parent->_right = cur; + cur->_parent = parent; + } + + // 2. ƽ + while (parent) + { + if (cur == parent->_right) + { + parent->_bf++; // ұ, ƽ++ + } + else + { + parent->_bf--; // , ƽ-- + } + + if (parent->_bf == 0) + { + // ˵ parent ڵ߶Ȳ, ½ + break; + } + else if (parent->_bf == 1 || parent->_bf == -1) + { + // ˵ parent ĸ߶ȱ, ϸ + cur = parent; + parent = parent->_parent; + } + else if (parent->_bf == 2 || parent->_bf == -2) + { + // parent ڵ, Ҫתһ + // 1. תǰDZ + // 2. תƽ + if (parent->_bf == 2) + { + if (cur->_bf == 1) + { + // + RotateL(parent); + } + else if (cur->_bf == -1) + { + // ˫ + RotateRL(parent); + } + } + else if (parent->_bf == -2) + { + if (cur->_bf == -1) + { + // + RotateR(parent); + } + else if (cur->_bf == 1) + { + // ˫ + RotateLR(parent); + } + } + + // תɺ, parent ڵĸ߶Ȼָ˲ڵǰĸ߶ + // , һûӰ, ½ + break; + } + } + + return true; + } + + // + void RotateL(Node* parent) + { + Node* ppNode = parent->_parent; + Node* subR = parent->_right; + Node* subRL = subR->_left; + + parent->_right = subRL; + if (subRL) + { + subRL->_parent = parent; + } + subR->_left = parent; + parent->_parent = subR; + + // 1. ԭ parent ĸ, subR Ǹ + if (parent == _root) + { + _root = subR; + subR->_parent = nullptr; + } + // 2. parent Ϊֻе, ıӹϵ, ô subR Ҫλ + else + { + if (ppNode->_left == parent) + { + ppNode->_left = subR; + } + else + { + ppNode->_right = subR; + } + subR->_parent = ppNode; + } + + parent->_bf = subR->_bf = 0; + } + + // ҵ + void RotateR(Node* parent) + { + Node* ppNode = parent->_parent; + Node* subL = parent->_left; + Node* subLR = subL->_right; + + parent->_left = subLR; + if (subLR) + { + subLR->_parent = parent; + } + subL->_right = parent; + parent->_parent = subL; + + if (parent == _root) + { + _root = subL; + subL->_parent = nullptr; + } + else + { + if (ppNode->_left == parent) + { + ppNode->_left = subL; + } + else + { + ppNode->_right = subL; + } + subL->_parent = ppNode; + } + + parent->_bf = subL->_bf = 0; + } + + // ˫ + void RotateRL(Node* parent) + { + Node* subR = parent->_right; + Node* subRL = subR->_left; + int bf = subRL->_bf; + + RotateR(parent->_right); + RotateL(parent); + + if (bf == -1) + { + parent->_bf = 0; + subR->_bf = 1; + subRL->_bf = 0; + } + else if (bf == 1) + { + parent->_bf = -1; + subR->_bf = 0; + subRL->_bf = 0; + } + else if (bf == 0) + { + parent->_bf = 0; + subR->_bf = 0; + subRL->_bf = 0; + } + } + + // ˫ + void RotateLR(Node* parent) + { + Node* subL = parent->_left; + Node* subLR = subL->_right; + int bf = subLR->_bf; + + RotateL(subL); + RotateR(parent); + + if (bf == 1) + { + parent->_bf = 0; + subL->_bf = -1; + subLR->_bf = 0; + } + else if (bf == -1) + { + parent->_bf = 1; + subL->_bf = 0; + subLR->_bf = 0; + } + else if (bf == 0) + { + parent->_bf = 0; + subL->_bf = 0; + subLR->_bf = 0; + } + } + + + // + //void _InOrder(Node* root) + //{ + // if (root == nullptr) + // { + // return; + // } + + // _InOrder(root->_left); + // std::cout << root->_kv.first << ":" << root->_kv.second << std::endl; + // _InOrder(root->_right); + //} + + //void InOrder() + //{ + // _InOrder(_root); + // std::cout << std::endl; + //} + + // ǵݹ + void InOrder() + { + std::stack stack; + Node* cur = _root; + + while (cur != nullptr || !stack.empty()) { + // ҵߵĽڵ + while (cur != nullptr) { + stack.push(cur); + cur = cur->_left; + } + + // ǰڵ + cur = stack.top(); + stack.pop(); + std::cout << cur->_kv.first << ":" << cur->_kv.second << std::endl; + + // ת + cur = cur->_right; + } + std::cout << std::endl; + } + + // ǰĵݹʵ + // + //void _PreOrder(Node* root) + //{ + // if (root == nullptr) + // { + // return; + // } + + // std::cout << root->_kv.first << ":" << root->_kv.second << std::endl; // ʸڵ + // _PreOrder(root->_left); // + // _PreOrder(root->_right); // + //} + + //void PreOrder() + //{ + // _PreOrder(_root); + // std::cout << std::endl; + //} + + // ǰķǵݹʵ + void PreOrder() + { + if (_root == nullptr) + { + return; + } + + std::stack stack; + stack.push(_root); + + while (!stack.empty()) { + Node* cur = stack.top(); + stack.pop(); + std::cout << cur->_kv.first << ":" << cur->_kv.second << std::endl; // ʵǰڵ + + // ѹѹȷȴ + if (cur->_right != nullptr) + { + stack.push(cur->_right); + } + if (cur->_left != nullptr) { + stack.push(cur->_left); + } + } + std::cout << std::endl; + } + + // ĵݹʵ + // + //void _PostOrder(Node* root) { + // if (root == nullptr) + // { + // return; + // } + + // _PostOrder(root->_left); // + // _PostOrder(root->_right); // + // std::cout << root->_kv.first << ":" << root->_kv.second << std::endl; // ʸڵ + //} + + //void PostOrder() + //{ + // _PostOrder(_root); + // std::cout << std::endl; + //} + + // ķǵݹʵ + void PostOrder() + { + if (_root == nullptr) + { + return; + } + + std::stack st; + Node* cur = _root; + Node* lastNode = nullptr; // ʵĽڵ + while (cur || !st.empty()) + { + while (cur) + { + st.push(cur); + cur = cur->_left; + } + + Node* top = st.top(); + if ((top->_right == nullptr) || (lastNode == top->_right)) + { + std::cout << top->_kv.first << ":" << top->_kv.second << std::endl; + lastNode = top; + st.pop(); + } + else { + cur = top->_right; + } + } + std::cout << std::endl; + } + + // + void LevelOrder() + { + if (_root == nullptr) + { + return; + } + + std::queue queue; + queue.push(_root); + + while (!queue.empty()) + { + Node* cur = queue.front(); + queue.pop(); + std::cout << cur->_kv.first << ":" << cur->_kv.second << std::endl; // ʵǰڵ + + if (cur->_left != nullptr) { + queue.push(cur->_left); // ѹ + } + if (cur->_right != nullptr) { + queue.push(cur->_right); // ѹ + } + } + std::cout << std::endl; + } + + // Һ̽ڵ + Node* findMin(Node* node) + { + while (node->_left != nullptr) + { + node = node->_left; + } + return node; + } + + Node* FindSuccessor(Node* node) + { + if (node->_right != nullptr) + { + return findMin(node->_right); + } + + Node* cur = _root; + Node* successor = nullptr; + while (cur != nullptr) + { + if (node->_kv.first < cur->_kv.first) + { + successor = cur; + cur = cur->_left; + } + else if (node->_kv.first > cur->_kv.first) + { + cur = cur->_right; + } + else + { + break; + } + } + return successor; + } + + // ǰڵ + Node* findMax(Node* node) + { + while (node->_right != nullptr) + { + node = node->_right; + } + return node; + } + + Node* FindPredecessor(Node* node) + { + if (node->_left != nullptr) + { + return findMax(node->_left); + } + + Node* cur = _root; + Node* predecessor = nullptr; + while (cur != nullptr) + { + if (node->_kv.first < cur->_kv.first) + { + cur = cur->_left; + } + else if (node->_kv.first > cur->_kv.first) + { + predecessor = cur; + cur = cur->_right; + } + else + { + break; + } + } + return predecessor; + } + + // ȡĸ߶ + int Height(Node* root) + { + if (root == nullptr) + { + return 0; + } + + int leftHeight = Height(root->_left); + int rightHeight = Height(root->_right); + + return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1; + } + + // жǷƽ + bool _IsBalance(Node* root) + { + if (root == nullptr) + { + return true; + } + + int leftHeight = Height(root->_left); + int rightHeight = Height(root->_right); + if (abs(leftHeight - rightHeight) > 1) + { + return false; + } + + return _IsBalance(root->_left) && _IsBalance(root->_right); + } + + bool IsBalance() + { + return _IsBalance(_root); + } + + // ǵݹ + //Node* Find(const K& key) + //{ + // Node* cur = _root; + // while (cur) + // { + // if (cur->_kv.first > key) + // { + // cur = cur->_left; + // } + // else if (cur->_kv.first < key) + // { + // cur = cur->_right; + // } + // else + // { + // return cur; + // } + // } + // return nullptr; + //} + + // ҵĵݹʵ + // + Node* _find(Node* root, const K& key) + { + if (root == nullptr || root->_kv.first == key) + { + return root; + } + if (key < root->_kv.first) + { + return _find(root->_left, key); + } + else + { + return _find(root->_right, key); + } + } + + // ҽڵ + Node* Find(const K& key) + { + return _find(_root, key); + } + + private: + Node* _root = nullptr; + }; +} \ No newline at end of file diff --git a/Windows_AVLTree/Windows_AVLTree.sln b/Windows_AVLTree/Windows_AVLTree.sln new file mode 100644 index 0000000..4e5a254 --- /dev/null +++ b/Windows_AVLTree/Windows_AVLTree.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.7.34221.43 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Windows_AVLTree", "Windows_AVLTree.vcxproj", "{3C530849-DC24-4616-BE04-AC7136C26007}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3C530849-DC24-4616-BE04-AC7136C26007}.Debug|x64.ActiveCfg = Debug|x64 + {3C530849-DC24-4616-BE04-AC7136C26007}.Debug|x64.Build.0 = Debug|x64 + {3C530849-DC24-4616-BE04-AC7136C26007}.Debug|x86.ActiveCfg = Debug|Win32 + {3C530849-DC24-4616-BE04-AC7136C26007}.Debug|x86.Build.0 = Debug|Win32 + {3C530849-DC24-4616-BE04-AC7136C26007}.Release|x64.ActiveCfg = Release|x64 + {3C530849-DC24-4616-BE04-AC7136C26007}.Release|x64.Build.0 = Release|x64 + {3C530849-DC24-4616-BE04-AC7136C26007}.Release|x86.ActiveCfg = Release|Win32 + {3C530849-DC24-4616-BE04-AC7136C26007}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {5CA83C61-F3A5-432C-8E40-DD56D62438F7} + EndGlobalSection +EndGlobal diff --git a/Windows_AVLTree/Windows_AVLTree.vcxproj b/Windows_AVLTree/Windows_AVLTree.vcxproj new file mode 100644 index 0000000..60156f8 --- /dev/null +++ b/Windows_AVLTree/Windows_AVLTree.vcxproj @@ -0,0 +1,138 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 17.0 + Win32Proj + {3c530849-dc24-4616-be04-ac7136c26007} + WindowsAVLTree + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + + + + \ No newline at end of file diff --git a/Windows_AVLTree/Windows_AVLTree.vcxproj.filters b/Windows_AVLTree/Windows_AVLTree.vcxproj.filters new file mode 100644 index 0000000..c46e134 --- /dev/null +++ b/Windows_AVLTree/Windows_AVLTree.vcxproj.filters @@ -0,0 +1,27 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + + + 头文件 + + + \ No newline at end of file diff --git a/Windows_AVLTree/Windows_AVLTree.vcxproj.user b/Windows_AVLTree/Windows_AVLTree.vcxproj.user new file mode 100644 index 0000000..88a5509 --- /dev/null +++ b/Windows_AVLTree/Windows_AVLTree.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Windows_AVLTree/x64/Debug/AVLTree.obj b/Windows_AVLTree/x64/Debug/AVLTree.obj new file mode 100644 index 0000000..e8324fc Binary files /dev/null and b/Windows_AVLTree/x64/Debug/AVLTree.obj differ diff --git a/Windows_AVLTree/x64/Debug/Windows_AVLTree.exe b/Windows_AVLTree/x64/Debug/Windows_AVLTree.exe new file mode 100644 index 0000000..d847dfd Binary files /dev/null and b/Windows_AVLTree/x64/Debug/Windows_AVLTree.exe differ diff --git a/Windows_AVLTree/x64/Debug/Windows_AVLTree.exe.recipe b/Windows_AVLTree/x64/Debug/Windows_AVLTree.exe.recipe new file mode 100644 index 0000000..aa7b28c --- /dev/null +++ b/Windows_AVLTree/x64/Debug/Windows_AVLTree.exe.recipe @@ -0,0 +1,11 @@ + + + + + E:\Git 仓库\公开仓库\7_AVLTree\Windows_AVLTree\x64\Debug\Windows_AVLTree.exe + + + + + + \ No newline at end of file diff --git a/Windows_AVLTree/x64/Debug/Windows_AVLTree.ilk b/Windows_AVLTree/x64/Debug/Windows_AVLTree.ilk new file mode 100644 index 0000000..d087cc3 Binary files /dev/null and b/Windows_AVLTree/x64/Debug/Windows_AVLTree.ilk differ diff --git a/Windows_AVLTree/x64/Debug/Windows_AVLTree.log b/Windows_AVLTree/x64/Debug/Windows_AVLTree.log new file mode 100644 index 0000000..d28691d --- /dev/null +++ b/Windows_AVLTree/x64/Debug/Windows_AVLTree.log @@ -0,0 +1,2 @@ + AVLTree.cpp + Windows_AVLTree.vcxproj -> E:\Git 仓库\公开仓库\7_AVLTree\Windows_AVLTree\x64\Debug\Windows_AVLTree.exe diff --git a/Windows_AVLTree/x64/Debug/Windows_AVLTree.pdb b/Windows_AVLTree/x64/Debug/Windows_AVLTree.pdb new file mode 100644 index 0000000..0b278b6 Binary files /dev/null and b/Windows_AVLTree/x64/Debug/Windows_AVLTree.pdb differ diff --git a/Windows_AVLTree/x64/Debug/Windows_AVLTree.tlog/CL.command.1.tlog b/Windows_AVLTree/x64/Debug/Windows_AVLTree.tlog/CL.command.1.tlog new file mode 100644 index 0000000..cd19214 Binary files /dev/null and b/Windows_AVLTree/x64/Debug/Windows_AVLTree.tlog/CL.command.1.tlog differ diff --git a/Windows_AVLTree/x64/Debug/Windows_AVLTree.tlog/CL.read.1.tlog b/Windows_AVLTree/x64/Debug/Windows_AVLTree.tlog/CL.read.1.tlog new file mode 100644 index 0000000..401fd49 Binary files /dev/null and b/Windows_AVLTree/x64/Debug/Windows_AVLTree.tlog/CL.read.1.tlog differ diff --git a/Windows_AVLTree/x64/Debug/Windows_AVLTree.tlog/CL.write.1.tlog b/Windows_AVLTree/x64/Debug/Windows_AVLTree.tlog/CL.write.1.tlog new file mode 100644 index 0000000..7f8556b Binary files /dev/null and b/Windows_AVLTree/x64/Debug/Windows_AVLTree.tlog/CL.write.1.tlog differ diff --git a/Windows_AVLTree/x64/Debug/Windows_AVLTree.tlog/Cl.items.tlog b/Windows_AVLTree/x64/Debug/Windows_AVLTree.tlog/Cl.items.tlog new file mode 100644 index 0000000..ba3034b --- /dev/null +++ b/Windows_AVLTree/x64/Debug/Windows_AVLTree.tlog/Cl.items.tlog @@ -0,0 +1 @@ +E:\Git 仓库\公开仓库\7_AVLTree\Windows_AVLTree\AVLTree.cpp;E:\Git 仓库\公开仓库\7_AVLTree\Windows_AVLTree\x64\Debug\AVLTree.obj diff --git a/Windows_AVLTree/x64/Debug/Windows_AVLTree.tlog/Windows_AVLTree.lastbuildstate b/Windows_AVLTree/x64/Debug/Windows_AVLTree.tlog/Windows_AVLTree.lastbuildstate new file mode 100644 index 0000000..dac1cd4 --- /dev/null +++ b/Windows_AVLTree/x64/Debug/Windows_AVLTree.tlog/Windows_AVLTree.lastbuildstate @@ -0,0 +1,2 @@ +PlatformToolSet=v143:VCToolArchitecture=Native64Bit:VCToolsVersion=14.37.32822:TargetPlatformVersion=10.0.22000.0: +Debug|x64|E:\Git 仓库\公开仓库\7_AVLTree\Windows_AVLTree\| diff --git a/Windows_AVLTree/x64/Debug/Windows_AVLTree.tlog/link.command.1.tlog b/Windows_AVLTree/x64/Debug/Windows_AVLTree.tlog/link.command.1.tlog new file mode 100644 index 0000000..fb9d934 Binary files /dev/null and b/Windows_AVLTree/x64/Debug/Windows_AVLTree.tlog/link.command.1.tlog differ diff --git a/Windows_AVLTree/x64/Debug/Windows_AVLTree.tlog/link.read.1.tlog b/Windows_AVLTree/x64/Debug/Windows_AVLTree.tlog/link.read.1.tlog new file mode 100644 index 0000000..63e0116 Binary files /dev/null and b/Windows_AVLTree/x64/Debug/Windows_AVLTree.tlog/link.read.1.tlog differ diff --git a/Windows_AVLTree/x64/Debug/Windows_AVLTree.tlog/link.write.1.tlog b/Windows_AVLTree/x64/Debug/Windows_AVLTree.tlog/link.write.1.tlog new file mode 100644 index 0000000..6f20163 Binary files /dev/null and b/Windows_AVLTree/x64/Debug/Windows_AVLTree.tlog/link.write.1.tlog differ diff --git a/Windows_AVLTree/x64/Debug/Windows_AVLTree.vcxproj.FileListAbsolute.txt b/Windows_AVLTree/x64/Debug/Windows_AVLTree.vcxproj.FileListAbsolute.txt new file mode 100644 index 0000000..4f05b26 --- /dev/null +++ b/Windows_AVLTree/x64/Debug/Windows_AVLTree.vcxproj.FileListAbsolute.txt @@ -0,0 +1 @@ +E:\Git 仓库\公开仓库\7_AVLTree\Windows_AVLTree\x64\Debug\Windows_AVLTree.exe diff --git a/Windows_AVLTree/x64/Debug/vc143.idb b/Windows_AVLTree/x64/Debug/vc143.idb new file mode 100644 index 0000000..3577846 Binary files /dev/null and b/Windows_AVLTree/x64/Debug/vc143.idb differ diff --git a/Windows_AVLTree/x64/Debug/vc143.pdb b/Windows_AVLTree/x64/Debug/vc143.pdb new file mode 100644 index 0000000..7a23d7e Binary files /dev/null and b/Windows_AVLTree/x64/Debug/vc143.pdb differ