BinarySearchTree.h
#pragma once
struct TreeNode
{
int key;
TreeNode* parent;
TreeNode* leftChild;
TreeNode* rightChild;
};
class BinarySearchTree
{
private:
TreeNode* root;
int NodeNum; //存储节点的个数
public:
BinarySearchTree();
BinarySearchTree(int* a, int n);
~BinarySearchTree();
TreeNode* HeadRoot(); //返回二叉树根节点
int TreeNodeNum(); //返回二叉树的节点个数
void InorderTreeWalk()const; //递归中序遍历
void Inorder(TreeNode* n)const;
void InorderTreeWalk1()const; //非递归中序遍历
void PreorderTreeWalk()const; //递归先序遍历
void Preorder(TreeNode* n)const;
void PreorderTreeWalk1()const; //非递归先序遍历
void PostorderTreeWalk()const; //递归后序遍历
void Postorder(TreeNode* n)const;
void PostorderTreeWalk1()const; //非递归后序遍历
TreeNode* TreeMaximum(TreeNode* n)const; //二叉树中值最大的节点
TreeNode* TreeMinimum(TreeNode* n)const; //二叉树中值最小的节点
void TreeSuccessor()const; //后继法实现二叉树的升序排序
TreeNode* TreeSuccessor(TreeNode* n)const; //返回节点n的后驱节点
void TreePredecessor()const; //前驱法实现二叉树的降序排序
TreeNode* TreePredecessor(TreeNode* n)const; //返回节点n的前继节点
void TreeInsert(TreeNode* n); //插入一个节点
void TreeInsert(int k);
void Transplant(TreeNode* u, TreeNode* v); //用节点v代替节点u成为新的子树,为删除节点做准备
void TreeDelete(TreeNode* n); //删除节点n
TreeNode* TreeSearch(int k); //查找关键字为k的节点
};
BinarySearchTree.cpp
#include "BinarySearchTree.h"
#include <iostream>
#include <stack>
BinarySearchTree::BinarySearchTree()
{
NodeNum = 0;
root = nullptr;
}
BinarySearchTree::BinarySearchTree(int* a, int n)
{
root = nullptr;
NodeNum = 0;
TreeNode* r;
for (int i = 0; i < n; ++i)
{
TreeNode* t = new TreeNode;
t->key = *(a + i);
t->parent = t->leftChild = t->rightChild = nullptr;
TreeInsert(t);
}
}
BinarySearchTree::~BinarySearchTree()
{
}
TreeNode* BinarySearchTree::HeadRoot()
{
return root;
}
int BinarySearchTree::TreeNodeNum()
{
return NodeNum;
}
void BinarySearchTree::InorderTreeWalk() const
{
if (!root)
{
std::cout << "空树!\n";
return;
}
std::cout << "递归中序遍历:\n";
Inorder(root);
std::cout << "\n";
}
void BinarySearchTree::Inorder(TreeNode *n) const
{
if (n->leftChild)
Inorder(n->leftChild);
std::cout << n->key << " ";
if (n->rightChild)
Inorder(n->rightChild);
}
void BinarySearchTree::InorderTreeWalk1() const //非递归算法都使用栈作为辅助空间来实现
{
if (!root)
{
std::cout << "空树!\n";
return;
}
TreeNode* n = root;
std::stack<TreeNode*> Stack;
std::cout << "非递归中序遍历:\n";
while (n || !Stack.empty())
{
while (n)
{
Stack.push(n);
n = n->leftChild;
}
n = Stack.top();
Stack.pop();
std::cout << n->key << " ";
n = n->rightChild;
}
std::cout << "\n";
}
void BinarySearchTree::PreorderTreeWalk() const
{
if (!root)
{
std::cout << "空树!\n";
return;
}
std::cout << "递归先序遍历:\n";
Preorder(root);
std::cout << "\n";
}
void BinarySearchTree::Preorder(TreeNode* n) const
{
std::cout << n->key << " ";
if (n->leftChild)
Preorder(n->leftChild);
if (n->rightChild)
Preorder(n->rightChild);
}
void BinarySearchTree::PreorderTreeWalk1() const
{
if (!root)
{
std::cout << "空树!\n";
return;
}
TreeNode* n = root;
std::stack<TreeNode*> Stack;
std::cout << "非递归先序遍历:\n";
while (n || !Stack.empty())
{
while (n)
{
std::cout << n->key << " ";
Stack.push(n);
n = n->leftChild;
}
n = Stack.top();
Stack.pop();
n = n->rightChild;
}
std::cout << "\n";
}
void BinarySearchTree::PostorderTreeWalk() const
{
if (!root)
{
std::cout << "空树!\n";
return;
}
std::cout << "递归后序遍历:\n";
Postorder(root);
std::cout << "\n";
}
void BinarySearchTree::Postorder(TreeNode* n) const
{
if (n->leftChild)
Postorder(n->leftChild);
if (n->rightChild)
Postorder(n->rightChild);
std::cout << n->key << " ";
}
void BinarySearchTree::PostorderTreeWalk1() const
{
if (!root)
{
std::cout << "空树!\n";
return;
}
TreeNode* n = root;
std::stack<TreeNode*> Stack;
int flag[30]; //flag是用来标志入栈节点是否访问过其右子树
std::cout << "非递归后序遍历:\n";
while (n)
{
Stack.push(n);
n = n->leftChild;
flag[Stack.size()] = 0;
}
while (!Stack.empty())
{
n = Stack.top();
while (n->rightChild && flag[Stack.size()] == 0)
{
flag[Stack.size()] = 1;
n = n->rightChild;
while (n)
{
Stack.push(n);
flag[Stack.size()] = 0;
n = n->leftChild;
}
n = Stack.top();
}
n = Stack.top();
Stack.pop();
std::cout << n->key << " ";
}
std::cout << "\n";
}
TreeNode* BinarySearchTree::TreeMinimum(TreeNode* n) const
{
while (n->leftChild)
n = n->leftChild;
return n;
}
TreeNode* BinarySearchTree::TreeMaximum(TreeNode* n) const
{
while (n->rightChild)
n = n->rightChild;
return n;
}
void BinarySearchTree::TreeSuccessor() const
{
if (!root)
{
std::cout << "空树!\n";
return;
}
TreeNode* min = TreeMinimum(root);
TreeNode* n = min;
int count = 1;
std::cout << "后继法升序排序:\n";
std::cout << min->key << " ";
while (count!=NodeNum)
{
n = TreeSuccessor(n);
std::cout << n->key << " ";
count++;
}
std::cout << "\n";
}
TreeNode* BinarySearchTree::TreeSuccessor(TreeNode* n) const //根据二叉树的性质,找节点n的后继,若n有右孩子的话,后继就是以n->rightChild为根节点子树的最小值
{ //若n没有右孩子的话,则顺着树往上找,直到遇到这样的节点,这个节点是它的双亲的左孩子
if (n->rightChild)
return TreeMinimum(n->rightChild);
TreeNode* m = n->parent;
while (m && m->rightChild == n)
{
n = m;
m = n->parent;
}
return m;
}
void BinarySearchTree::TreePredecessor() const
{
if (!root)
{
std::cout << "空树!\n";
return;
}
TreeNode* max = TreeMaximum(root);
TreeNode* n = max;
int count = 1;
std::cout << "前驱法降序排序:\n";
std::cout << max->key << " ";
while (count != NodeNum)
{
n = TreePredecessor(n);
std::cout << n->key << " ";
count++;
}
std::cout << "\n";
}
TreeNode* BinarySearchTree::TreePredecessor(TreeNode* n) const //前驱的话和后继是对称的
{
if (n->leftChild)
return TreeMaximum(n->leftChild);
TreeNode* m = n->parent;
while (m && m->leftChild == n)
{
n = m;
m = n->parent;
}
return m;
}
void BinarySearchTree::TreeInsert(TreeNode* t)
{
if (!root)
{
root = t;
}
else
{
TreeNode* r;
r = root;
while (1)
{
if (t->key < r->key)
{
if (!r->leftChild)
{
r->leftChild = t;
t->parent = r;
break;
}
else
r = r->leftChild;
}
else
{
if (!r->rightChild)
{
r->rightChild = t;
t->parent = r;
break;
}
else
r = r->rightChild;
}
}
}
NodeNum++;
}
void BinarySearchTree::TreeInsert(int k)
{
TreeNode* t = new TreeNode;
t->key = k;
t->parent = t->leftChild = t->rightChild = nullptr;
TreeInsert(t);
}
void BinarySearchTree::Transplant(TreeNode* u, TreeNode* v)
{
if (!u->parent)
root = v;
else if (u->parent->leftChild == u)
u->parent->leftChild = v;
else
u->parent->rightChild = v;
if (v)
v->parent = u->parent;
}
void BinarySearchTree::TreeDelete(TreeNode* n) //删除一个节点的考虑几种情况,比较复杂
{
if (!n->leftChild) //无左孩子有右孩子,直接用右孩子来代替
Transplant(n, n->rightChild);
else if (!n->rightChild) //有左孩子无右孩子,直接用左孩子来代替
Transplant(n, n->leftChild);
else //既有左孩子又有右孩子,这种情况比较复杂
{
TreeNode* y = TreeMinimum(n->rightChild); //找到节点n右孩子的后继
if (y->parent != n) //如果后继不是n的右孩子,将后继y的右孩子来代替节点y
{
Transplant(y, y->rightChild);
y->rightChild = n->rightChild;
y->rightChild->parent = y;
}
Transplant(n, y); //用y来代替n
y->leftChild = n->leftChild; //注意各节点之间指针parent,leftChild,rightChild的属性,使其形成一棵完整的二叉搜索树
y->leftChild->parent = y;
}
NodeNum--;
delete n;
}
TreeNode* BinarySearchTree::TreeSearch(int k)
{
TreeNode* t = root;
while (t)
{
if (k == t->key)
break;
else if (k < t->key)
t = t->leftChild;
else
t = t->rightChild;
}
return t;
}
main.cpp
#include "BinarySearchTree.h"
#include <iostream>
const int SIZE = 10;
void Menu(BinarySearchTree& tree)
{
using std::cout;
char c;
do
{
system("cls");
system("color 3E");
cout << "------------------------------------------------------\n";
cout << "------------------------------------------------------\n";
cout << " 菜单\n";
cout << "******************************************************\n";
cout << "******************************************************\n";
cout << " 1-- 遍历\n";
cout << " 2-- 排序\n";
cout << " 3-- 插入\n";
cout << " 4-- 删除\n";
cout << " 0-- 退出\n";
cout << " 请输入选择:";;
std::cin >> c;
switch (c)
{
char n;
case '1':
do
{
system("cls");
cout << "*************************************\n";
cout << " 遍历\n";
cout << "-------------------------------------\n";
cout << " 1-- 递归遍历\n";
cout << " 2-- 非递归遍历\n";
cout << " 0-- 返回\n";
cout << " 请输入选择:";
std::cin >> n;
switch (n)
{
case '1':
system("cls");
cout << " 递归遍历\n";
cout << "-------------------------------\n";
tree.PreorderTreeWalk();
tree.InorderTreeWalk();
tree.PostorderTreeWalk();
system("pause");
break;
case '2':
system("cls");
cout << " 非递归遍历\n";
cout << "---------------------------------\n";
tree.PreorderTreeWalk1();
tree.InorderTreeWalk1();
tree.PostorderTreeWalk1();
system("pause");
break;
}
} while (n != '0');
break;
case '2':
system("cls");
cout << " 排序\n";
cout << "---------------------------------------\n";
tree.TreeSuccessor();
tree.TreePredecessor();
system("pause");
break;
case '3':
system("cls");
cout << " 插入\n";
cout << "---------------------------------------\n";
cout << "请输入要插入的数值:";
int k;
std::cin >> k;
tree.TreeInsert(k);
tree.InorderTreeWalk();
std::cout << "插入成功\n";
system("pause");
break;
case '4':
system("cls");
cout << " 删除\n";
cout << "---------------------------------------\n";
tree.InorderTreeWalk();
cout << "请输入要删除的值:";
int num;
std::cin >> num;
TreeNode* q = tree.TreeSearch(num);
if (!q)
cout << "未找到该节点\n";
else
{
tree.TreeDelete(q);
cout << "删除节点成功\n\n";
tree.InorderTreeWalk();
}
system("pause");
break;
}
} while (c != '0');
}
int main(void)
{
int a[SIZE] = { 15,6,4,3,8,16,8,1,12,20 };
BinarySearchTree tree(a, SIZE);
Menu(tree);
system("pause");
return 0;
}