【相关知识】
二叉排序树(也称二叉查找树):或者是一棵空的二叉树,或者是具有下列性质的二叉树:
⑴ 若它的左子树不空,则左子树上所有结点的值均小于根结点的值;
⑵ 若它的右子树不空,则右子树上所有结点的值均大于根结点的值;
⑶ 它的左右子树也都是二叉排序树。
【题目描述】
①给定输入序列,按照二叉排序树算法创建二叉排序树。输出二叉排序树的中序遍历。
②输入一个待查找的整数x,如果整数x在二叉排序树中存在,这输出"Found.",否则输出"Not found."要求按照前序遍历顺序进行递归查找,要输出查找的过程。
③输入一个待查找的整数x,如果整数x在二叉排序树中存在,则输出"Found.",并删除找到的结点,并且输出删除后的二叉排序树的中序遍历序列。如果整数x不存在,否则输出"Not found."。
④然后按后序遍历销毁这棵树。
【测试数据】
【数据1】
请输入二叉树结点个数:
11
请输入结点数据:
38 12 34 56 13 6 98 3 17 40 78
请输入待查找的整数:
40
Searching...
38 56 40
Found.
请输入待删除的结点:
40
Found.
PreOrder sequence after deleted: 38 12 6 3 34 13 17 56 98 78
InOrder sequence after deleted: 3 6 12 13 17 34 38 56 78 98
Destroy tree...
Delete:3
Delete:6
Delete:17
Delete:13
Delete:34
Delete:12
Delete:78
Delete:98
Delete:56
Delete:38
【数据2】
请输入二叉树结点个数:
11
请输入结点数据:
38 12 34 56 13 6 98 3 17 40 78
请输入待查找的整数:
14
Searching...
38 12 34 13 17
Not found.
请输入待删除的结点:
9
Not found.
Destroy tree...
Delete:3
Delete:6
Delete:17
Delete:13
Delete:34
Delete:12
Delete:40
Delete:78
Delete:98
Delete:56
Delete:38
【代码】
cpp
#include <iostream>
#include <algorithm>
#include <limits.h>
#include<string>
using namespace std;
const int MAX = 100;
struct BiNode
{
int data;
BiNode* lchild, * rchild;//左右儿子指针
};
BiNode* root = NULL;
static bool flag = false;
void inOrder(BiNode* bt)
{
if (bt == NULL)
return;
else
{
inOrder(bt->lchild);
cout << bt->data << " ";
inOrder(bt->rchild);
}
}
void preOrder(BiNode* bt)
{
if (bt == NULL)
return;
else
{
cout << bt->data << " ";
preOrder(bt->lchild);
preOrder(bt->rchild);
}
}
void release(BiNode* bt)
{
if (bt != NULL)
{
release(bt->lchild);
release(bt->rchild);
delete bt;
bt = NULL;
}
}
void postOrder(BiNode* bt)
{
if (bt != NULL)
{
postOrder(bt->lchild);
postOrder(bt->rchild);
cout << "Delete:" << bt->data << endl;
}
}
void Insert(BiNode*& bt, int num)
{
if (bt == NULL)
{
bt = new BiNode;
bt->data = num;
bt->lchild = NULL;
bt->rchild = NULL;
}
else
{
if (num < bt->data)
Insert(bt->lchild, num);
else if (num > bt->data)
Insert(bt->rchild, num);
}
}
bool Search(BiNode* bt, int key)
{
if (bt == NULL)
return false;
else
{
if (key < bt->data)
{
cout << bt->data << " ";
Search(bt->lchild, key);
}
else if (key > bt->data)
{
cout << bt->data << " ";
Search(bt->rchild, key);
}
else
{
cout << bt->data << " ";
flag = true;
}
return flag;
}
}
//删除结点
void deleteNode(BiNode*& bt)
{
BiNode* p;
if (bt->lchild == NULL && bt->rchild == NULL) //叶子结点
{ //直接删除,再把该位置设为空
p = bt;
bt = NULL;
delete p;
}
else if (bt->rchild == NULL) //右子树为空,只有左子树
{
p = bt;
bt = bt->lchild; //把删除结点的左子树拼接到删除节点的父节点的右边,作为父节点的右子树
delete p;
}
else if (bt->lchild == NULL) //左子树为空,只有右子树,同上
{
p = bt;
bt = bt->rchild;
delete p;
}
else //左右子树都不为空|将要删除结点的左子树中最大的结点替换该删除的结点
{
BiNode* parent, * pre;
parent = bt;
pre = bt->lchild;
//转左,然后向右到尽头
while (pre->rchild)
{
parent = pre;
pre = pre->rchild;
}
bt->data = pre->data; //将根节点的左子树中的最大的节点赋给根节点,原本的根节点被替代
if (parent != bt)
parent->rchild = pre->lchild; //pre的lchild与parent建立联系,pre被删掉
else
parent->lchild = pre->lchild; //原来pre指向的结点,也就是最大的结点被删掉
delete pre;
}
}
//根据指定的关键数据找到要删除的节点的位置
bool deleteBST(BiNode*& bt, int key)
{
if (bt == NULL)
{
return false;
}
else
{
if (bt->data == key) //找到关键词
deleteNode(bt); //删除
else if (key < bt->data) //如果关键词比当前结点数据小,继续在其左子树中查找
return deleteBST(bt->lchild, key);
else //如果关键词比当前结点数据大,在其右子树中查找
return deleteBST(bt->rchild, key);
return true; //查找成功
}
}
int main()
{
int n, key;
int array[MAX] = { 0 };
cout << "请输入二叉树结点个数:\n";
cin >> n;
cout << "请输入结点数据:\n";
for (int i = 0; i < n; i++)
{
cin >> array[i];
}
for (int i = 0; i < n; i++)
{
Insert(root, array[i]);
}
//开始查找
cout << "请输入待查找的整数:\n";
cin >> key;
cout << "Searching..." << endl;
if (Search(root, key))
cout << "\nFound." << endl;
else
cout << "\nNot found." << endl;
cout << "请输入待删除的结点:\n";
cin >> key;
//开始删除
if (deleteBST(root, key))
{
cout << "Found." << endl;
cout << "PreOrder sequence after deleted: ";
preOrder(root);
cout << "\nInOrder sequence after deleted: ";
inOrder(root);
}
else
cout << "Not found." << endl;
//销毁二叉树
cout << endl << "Destroy tree..." << endl;
postOrder(root);
release(root);
return 0;
}
【运行效果】