@CrazyHenry
2018-03-06T09:47:43.000000Z
字数 4387
阅读 1171
dddd数据结构课本
- Author:李英民 | Henry
- E-mail: li
_yingmin@outlookdotcom- Home: https://liyingmin.wixsite.com/henry
快速了解我: About Me
转载请保留上述引用内容,谢谢配合!
#include <iostream>#include <queue>#include <cassert>using namespace std;// 二分搜索树template <typename Key, typename Value>class BST{private:// 树中的节点为私有的结构体, 外界不需要了解二分搜索树节点的具体实现struct Node{Key key;Value value;Node *left = nullptr;Node *right = nullptr;Node(Key key, Value value): key(key), value(value){}//拷贝构造,在remove函数里使用Node(Node *node): key(node->key),value(node->value),left(node->left),right(node->right){}};Node *root = nullptr; // 根节点int count = 0; // 树中的节点个数public:// 构造函数, 默认构造一棵空二分搜索树BST(){}// 析构函数, 释放二分搜索树的所有空间~BST(){destroy( root );}// 返回二分搜索树的节点个数int size(){return count;}// 返回二分搜索树是否为空bool isEmpty(){return count == 0;}// 向二分搜索树中插入一个新的(key, value)数据对void insert(Key key, Value value){root = insert(root, key, value);}// 查看二分搜索树中是否存在键keybool contain(Key key){return contain(root, key);}// 在二分搜索树中搜索键key所对应的值。如果这个值不存在, 则返回nullptrValue* search(Key key){return search( root , key );}// 二分搜索树的前序遍历void preOrder(){preOrder(root);}// 二分搜索树的中序遍历void inOrder(){inOrder(root);}// 二分搜索树的后序遍历void postOrder(){postOrder(root);}// 二分搜索树的层序遍历void levelOrder(){queue<Node*> q;q.push(root);while( !q.empty() ){Node *node = q.front();q.pop();cout<<node->key<<endl;if( node->left )q.push( node->left );if( node->right )q.push( node->right );}}// 寻找二分搜索树的最小的键值Key minimum(){assert( count != 0 );Node* minNode = minimum( root );return minNode->key;}// 寻找二分搜索树的最大的键值Key maximum(){assert( count != 0 );Node* maxNode = maximum(root);return maxNode->key;}// 从二分搜索树中删除最小值所在节点void removeMin(){if( root )root = removeMin( root );}// 从二分搜索树中删除最大值所在节点void removeMax(){if( root )root = removeMax( root );}// 从二分搜索树中删除键值为key的节点void remove(Key key){root = remove(root, key);}private:// 向以node为根的二分搜索树中, 插入节点(key, value), 使用递归算法// 返回插入新节点后的二分搜索树的根Node* insert(Node *node, Key key, Value value){if( node == nullptr ){++count;return new Node(key, value);}if( key == node->key )node->value = value;else if( key < node->key )node->left = insert( node->left , key, value);else // key > node->keynode->right = insert( node->right, key, value);return node;}// 查看以node为根的二分搜索树中是否包含键值为key的节点, 使用递归算法bool contain(Node* node, Key key){if( node == nullptr )return false;if( key == node->key )return true;else if( key < node->key )return contain( node->left , key );else // key > node->keyreturn contain( node->right , key );}// 在以node为根的二分搜索树中查找key所对应的value, 递归算法// 若value不存在, 则返回NULLValue* search(Node* node, Key key){if( node == nullptr )return nullptr;if( key == node->key )return &(node->value);else if( key < node->key )return search( node->left , key );else // key > node->keyreturn search( node->right, key );}// 对以node为根的二分搜索树进行前序遍历, 递归算法void preOrder(Node* node){if( node != nullptr ){cout<<node->key<<endl;preOrder(node->left);preOrder(node->right);}}// 对以node为根的二分搜索树进行中序遍历, 递归算法void inOrder(Node* node){if( node != nullptr ){inOrder(node->left);cout<<node->key<<endl;inOrder(node->right);}}// 对以node为根的二分搜索树进行后序遍历, 递归算法void postOrder(Node* node){if( node != nullptr ){postOrder(node->left);postOrder(node->right);cout<<node->key<<endl;}}// 释放以node为根的二分搜索树的所有节点// 采用后续遍历的递归算法void destroy(Node* node){if( node != nullptr ){destroy( node->left );destroy( node->right );delete node;--count;}}// 返回以node为根的二分搜索树的最小键值所在的节点, 递归算法Node* minimum(Node* node){if( node->left == nullptr )return node;return minimum(node->left);}// 返回以node为根的二分搜索树的最大键值所在的节点, 递归算法Node* maximum(Node* node){if( node->right == nullptr )return node;return maximum(node->right);}// 删除掉以node为根的二分搜索树中的最小节点, 递归算法// 返回删除节点后新的二分搜索树的根Node* removeMin(Node* node){if( node->left == nullptr ){Node* rightNode = node->right;delete node;--count;return rightNode;}node->left = removeMin(node->left);return node;}// 删除掉以node为根的二分搜索树中的最大节点, 递归算法// 返回删除节点后新的二分搜索树的根Node* removeMax(Node* node){if( node->right == nullptr ){Node* leftNode = node->left;delete node;--count;return leftNode;}node->right = removeMax(node->right);return node;}// 删除掉以node为根的二分搜索树中键值为key的节点, 递归算法// 返回删除节点后新的二分搜索树的根Node* remove(Node* node, Key key){if( node == nullptr )return nullptr;if( key < node->key ){node->left = remove( node->left , key );return node;}else if( key > node->key ){node->right = remove( node->right, key );return node;}else{ // key == node->key// 待删除节点左子树为空的情况if( node->left == nullptr ){Node *rightNode = node->right;delete node;--count;return rightNode;}// 待删除节点右子树为空的情况if( node->right == nullptr ){Node *leftNode = node->left;delete node;--count;return leftNode;}// 待删除节点左右子树均不为空的情况// 找到比待删除节点大的最小节点, 即待删除节点右子树的最小节点// 用这个节点顶替待删除节点的位置Node *successor = new Node(minimum(node->right));++count;successor->right = removeMin(node->right);successor->left = node->left;delete node;--count;return successor;}}};