二叉查找树实现源码

看了《算法导论》上的第12章二叉查找树,现把对二叉树的几种操作罗列如下,实现的描述见代码注释。
 
 
   
#include < iostream >
using namespace std;

class Node
{
public :
int key;

Node
* left;
Node
* right;
Node
* parent;

Node(
int k);
};

class BinarySearchTree
{
public :
Node
* root;
BinarySearchTree();

// 以node为根节点开始搜索
Node * search(Node * node, int k);
// 插入节点
void insert(Node * node);
// 删除节点
void remove(Node * node);
// 得到最小值节点
Node * get_minimum(Node * node);
// 得到最大值节点
Node * get_maximum(Node * node);
// 查找前驱节点
Node * get_predecessor(Node * node);
// 查找后继节点
Node * get_successor(Node * node);
// 中序遍历
void in_order_traverse(Node * node);
};

int main()
{
int a[ 10 ] = { 5 , 3 , 4 , 2 , 8 , 9 , 1 , 7 , 6 , 0 };
BinarySearchTree
* binary_search_tree = new BinarySearchTree();
for ( int i = 0 ; i < 10 ; i ++ )
binary_search_tree
-> insert( new Node(a[i]));
binary_search_tree
-> in_order_traverse(binary_search_tree -> root);

// get the maximum
cout << " get the maximum: " << binary_search_tree -> get_maximum(binary_search_tree -> root) -> key << endl;

// remove 7
binary_search_tree -> remove(binary_search_tree -> search(binary_search_tree -> root, 7 ));
// remove 9
binary_search_tree -> remove(binary_search_tree -> search(binary_search_tree -> root, 9 ));
// remove 5
binary_search_tree -> remove(binary_search_tree -> search(binary_search_tree -> root, 5 ));
cout
<< " after remove the nodes: " << endl;
binary_search_tree
-> in_order_traverse(binary_search_tree -> root);
return 0 ;
}
Node::Node(
int k)
{
key
= k;
left
= right = parent = NULL;
}

BinarySearchTree::BinarySearchTree()
{
root
= NULL;
}

// 插入节点
void BinarySearchTree::insert(Node * node)
{
if (root == NULL)
{
root
= node;
}
else
{
Node
* p = root;
Node
* q = root;
while (q != NULL)
{
p
= q;
if (node -> key > q -> key)
q
= q -> right;
else
q
= q -> left;
}

node
-> parent = p;
if (node -> key > p -> key)
{
p
-> right = node;
}
else
{
p
-> left = node;
}
}
}

// 查找元素x
Node * BinarySearchTree::search(Node * node, int k)
{
if (node -> key == k || node == NULL)
return node;

if (node -> key < k)
return search(node -> right, k);
else
return search(node -> left, k);
}

// 算法导论书上把这三种情况给综合起来了
// 但看起来没有三种情况分别写出来清晰
// if判断的次数是相同的
void BinarySearchTree::remove(Node * node)
{
if (node -> left != NULL && node -> right != NULL)
{
Node
* temp = get_successor(node);
int k = temp -> key;
remove(temp);
node
-> key = k;
}
else if (node -> left != NULL || node -> right != NULL)
{
// 把父节点和子节点练成一线即可
if (node -> parent -> left == node)
{
if (node -> left == NULL)
{
node
-> parent -> left = node -> right;
node
-> right -> parent = node -> parent;
}
else
{
node
-> parent -> left = node -> left;
node
-> left -> parent = node -> parent;
}
}
else
{
if (node -> left == NULL)
{
node
-> parent -> right = node -> right;
node
-> right -> parent = node -> parent;
}
else
{
node
-> parent -> right = node -> left;
node
-> left -> parent = node -> parent;
}
}
delete node;
}
else
{
if (node -> parent -> left == node)
node
-> parent -> left = NULL;
else
node
-> parent -> right = NULL;
delete node;
}
}

// 得到以node为根节点的最小值
Node * BinarySearchTree::get_minimum(Node * node)
{
while (node -> left != NULL)
node
= node -> left;
return node;
}

// 得到以node为根节点的最大值
Node * BinarySearchTree::get_maximum(Node * node)
{
while (node -> right != NULL)
node
= node -> right;
return node;
}

// 得到key为x的前驱节点
Node * BinarySearchTree::get_predecessor(Node * node)
{
// 存在左分支
if (node -> left != NULL)
return get_maximum(node -> left);

// 若左分支不存在
// 前驱结点必然是x的最低祖先节点,且前驱结点的右儿子也是x的祖先
Node * p = node -> parent;
while (p != NULL && p -> left == node)
{
node
= p;
p
= p -> parent;
}
return p;
}

Node
* BinarySearchTree::get_successor(Node * node)
{
// 存在右分支
if (node -> right != NULL)
return get_minimum(node -> right);

// 若右分支不存在
// 后继结点必然是x的最低祖先节点,且后继结点的左儿子也是x的祖先
Node * p = node -> parent;
while (p != NULL && p -> right == node)
{
node
= p;
p
= p -> parent;
}
return p;
}

// 中序遍历
void BinarySearchTree::in_order_traverse(Node * node)
{
if (node == NULL)
return ;

in_order_traverse(node
-> left);
cout
<< node -> key << endl;
in_order_traverse(node
-> right);

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值