//二叉树的深度优先遍历即为前序中序后序遍历,因为每次前中后序遍历都需要递归到底。所以为深度
//二叉树的广度优先遍历即为层序遍历
//二叉搜索树的遍历都为O(n)
//二分搜索树的缺点之一:一组数据可能组成不同的二叉树,极端情况下可能组成一个链表,此时的深度为链表的长度,从而降低性能,改进方法:构造成一个平衡二叉树,最典型的例子为红黑树,其他的树还包括:2-3tree/AVL tree/Splay tree /平衡二叉树和堆的结合:Treap/ trie数据结构实现字典序,和单词个数无关,只和单词的字母长度有关
//一个小作业:用trie字典树来实现一个统计文本的词频
//8数码游戏/8皇后游戏(都是树形搜索的变种)
//计算机领域其他的树:KD树/区间树/哈夫曼树
#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;
Node *right;
Node(Key key,Value value)
{
this->key=key;
this->value=value;
this->left=this->right=NULL;
}
Node(Node* node)
{
this->key=node->key;
this->value=node->value;
this->left=node->left;
this->right=node->right;
}
};
Node * root;
int count;
//在以node为根的二叉搜索树中插入以key和value的键值对
Node *insert(Node *node,Key key,Value value)
{
if(node == NULL)
{
count++;
return new Node(key,value);
}
if(key==node->key)
{
node->key=key;
}
else if(key>node->key)
{
node->right=insert(node->right,key,value);
}
else
{
node->left=insert(node->left,key,value);
}
return node;
}
//查看以root为根的二叉树中是否存在有key这个键存在
bool contain(Node *node,Key key)
{
if(node==NULL)
return false;
if(key==node->key)
return true;
else if(key>node->key)
return contain(node->right,key);
else
return contain(node->left,key);
}
//在以node为根的二叉搜索树中查找key所对应的value
Value* search(Node *node,Key key)
{
if(node==NULL)
return NULL;
else if(key==node->key)
return &(node->value);
else if(key>node->key)
return search(node->right,key);
else
return search(node->left,key);
}
//前序遍历
void preOrder(Node *node)
{
if(node!=NULL)
{
cout<<node->key<<" ";
preOrder(node->left);
preOrder(node->right);
}
}
//中序遍历
void inOrder(Node *node)
{
if(node!=NULL)
{
inOrder(node->left);
cout<<node->key<<" ";
inOrder(node->right);
}
}
//后序遍历
void postOrder(Node *node)
{
if(node!=NULL)
{
postOrder(node->left);
postOrder(node->right);
cout<<node->key<<" ";
}
}
//由于后续遍历的性质,先遍历一个结点的所有子树,然后才遍历自身,这个性质可以用与析构函数,先析构所有的子树,然后再析构自身
void destroy(Node *node)
{
if(node!=NULL)
{
destroy(node->left);
destroy(node->right);
delete node;
count--;
}
}
//返回以node为节点的二叉树中最小的节点
Node *mininum(Node *node)
{
assert(node!=NULL);
if(node->left==NULL)
return node;
return mininum(node->left);
}
//返回以node为节点的二叉树中最大的节点
Node *maxinum(Node *node)
{
assert(node!=NULL);
if(node->right==NULL)
return node;
return maxinum(node->right);
}
//删除以node为根的二叉树中的最小节点
//返回删除节点后新的二叉树的根
Node *removeMin(Node *node)
{
if(node->left==NULL)
{
Node *rightNode=node->right;
delete node;
count--;
return rightNode;
}
node->left=removeMin(node->left);
return node;
}
Node *removeMax(Node*node)
{
if(node->right==NULL)
{
Node *leftNode=node->left;
delete node;
count--;
return leftNode;
}
node->right=removeMax(node->right);
return node;
}
//删除以node为根的二叉树中的key节点,首先先要找到key这个节点,然后找到key这个节点的右子树的最小节点也就是key的后继节点然后把这个节点复制一份,让这个节点的right节点等于这个把这个节点的右子树的最小值删掉后返回的节点,同理这个节点也可以是左子树的最大值,时间复杂度为O(logn)
Node *remove(Node *node,Key key)
{
if(node==NULL)
return NULL;
if(key > node->key)
{
node->right=remove(node->right,key);
return node;
}
else if(key < node->key)
{
node->left=remove(node->left,key);
return node;
}
else //key==node->key
{
if(node->left==NULL)
{
Node *rightNode=node->right;
delete node;
count--;
return rightNode;
}
if(node->right==NULL)
{
Node *leftNode=node->left;
delete node;
count--;
return leftNode;
}
else
{// node->left!=NULL && node->right!=NULL
Node* successor=new Node(mininum(node->right));
count++;
successor->right=removeMin(node->right);
successor->left=node->left;
delete node;
count--;
return successor;
}
}
}
public:
BST()
{
root=NULL;
count=0;
}
~BST()
{
destroy(root);
}
int size()
{
return count;
}
bool IsEmpty()
{
return count==0;
}
//递归查找,然后插入
void insert(Key key,Value value)
{
root=insert(root,key,value);
}
bool contain(Key key)
{
return contain(root,key);
}
Value* search(Key key)
{
return search(root,key);
}
void preOrder()
{
preOrder(root);
}
void inOrder()
{
inOrder(root);
}
void postOrder()
{
postOrder(root);
}
//二叉搜索树的层序遍历需要用到队列这个数据结构,每次队列不为NULL的时候,把front元素拿出打印,随后把其左孩子和右孩子进行入队
void levelOrder()
{
queue<Node*> q;
q.push(root);
while(!q.empty())
{
Node *node=q.front();
q.pop();
cout<<node->key<<" ";
if(node->left!=NULL)
{
q.push(node->left);
}
if(node->right!=NULL)
{
q.push(node->right);
}
}
}
Key minimum()
{
Node *minNode=minimum(root);
return minNode->key;
}
Key maxinum()
{
Node *maxNode=maxinum(root);
return maxNode->key;
}
void removeMin()
{
if(root!=NULL)
root=removeMin(root);
}
void removeMax()
{
if(root!=NULL)
root=removeMax(root);
}
void remove(Key key)
{
root=remove(root,key);
}
};
C++二分搜索树相关问题
最新推荐文章于 2024-08-19 21:18:51 发布