看了《算法导论》上的第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);
}
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);
}