数据结构(三)树 —— 编程作业 08 :二叉搜索树的操作集

数据结构系列内容的学习目录 → \rightarrow 浙大版数据结构学习系列内容汇总

  题目描述: 本题要求实现给定二叉搜索树的5种常用操作。

  函数接口定义:

BinTree Insert( BinTree BST, ElementType X );
BinTree Delete( BinTree BST, ElementType X );
Position Find( BinTree BST, ElementType X );
Position FindMin( BinTree BST );
Position FindMax( BinTree BST );

  其中BinTree结构定义如下:

typedef struct TNode *Position;
typedef Position BinTree;
struct TNode{
    ElementType Data;
    BinTree Left;
    BinTree Right;
};

   ∙ \bullet 函数InsertX插入二叉搜索树BST并返回结果树的根结点指针;
   ∙ \bullet 函数DeleteX从二叉搜索树BST中删除,并返回结果树的根结点指针;如果X不在树中,则打印一行Not Found并返回原树的根结点指针;
   ∙ \bullet 函数Find在二叉搜索树BST中找到X,返回该结点的指针;如果找不到则返回空指针;
   ∙ \bullet 函数FindMin返回二叉搜索树BST中最小元结点的指针;
   ∙ \bullet 函数FindMax返回二叉搜索树BST中最大元结点的指针。

  输入样例:

10
5 8 6 2 4 1 0 10 9 7
5
6 3 10 0 5
5
5 7 0 10 3

  输出样例:

Preorder: 5 2 1 0 4 8 6 7 10 9
6 is found
3 is not found
10 is found
10 is the largest key
0 is found
0 is the smallest key
5 is found
Not Found
Inorder: 1 2 4 6 8 9

  代码实现:

#include<iostream>
using namespace std;

typedef int ElementType;
typedef struct TNode *Position;
typedef Position BinTree;
struct TNode {
	ElementType Data;
	BinTree Left;
	BinTree Right;
};

void PreorderTraversal(BinTree BT);
void InorderTraversal(BinTree BT);

BinTree Insert(BinTree BST, ElementType X);
BinTree Delete(BinTree BST, ElementType X);
BinTree Find(BinTree BST, ElementType X);
BinTree FindMin(BinTree BST);
BinTree FindMax(BinTree BST);

int main()
{
	BinTree BST, MinP, MaxP, Tmp;
	ElementType X;
	int N, i;

	BST = NULL;
	cin >> N;
	for (i = 0; i < N; i++) 
	{
		cin >> X;
		BST = Insert(BST, X);
	}
	cout << "Preorder:";
	PreorderTraversal(BST); 
	cout << endl;
	MinP = FindMin(BST);
	MaxP = FindMax(BST);
	cin >> N;
	for (i = 0; i < N; i++) 
	{
		cin >> X;
		Tmp = Find(BST, X);
		if (Tmp == NULL)
			cout << X << " is not found" << endl;
		else {
			cout << Tmp->Data << " is found" << endl;
			if (Tmp == MinP)
				cout << Tmp->Data << " is the smallest key" << endl;
			if (Tmp == MaxP) 
				cout << Tmp->Data << " is the largest key" << endl;
		}
	}
	cin >> N;
	for (i = 0; i < N; i++) 
	{
		cin >> X;
		BST = Delete(BST, X);
	}
	cout << "Inorder:"; 
	InorderTraversal(BST); 
	cout << endl;

	system("pause");
	return 0;
}

// 查找递归实现 
BinTree Find(BinTree BST, ElementType X)
{
	if (!BST)  // 如果根结点为空,返回 NULL 
		return NULL;
	if (X < BST->Data) // 比根结点小,去左子树查找 
		return Find(BST->Left, X);
	else if (BST->Data < X)  // 比根结点大,去右子树查找 
		return Find(BST->Right, X);
	else if (BST->Data == X) // 找到了 
		return BST;
}

// 查找最小值的递归实现
BinTree FindMin(BinTree BST)
{
	if (!BST)    // 如果为空了,返回 NULL 
		return NULL;
	else if (BST->Left)   // 还存在左子树,沿左分支继续查找 
		return FindMin(BST->Left);
	else  // 找到了 
		return BST;
}

// 查找最大值的非递归实现
BinTree FindMax(BinTree BST)
{
	if (BST)  // 如果不空 
		while (BST->Right)   // 只要右子树还存在 
			BST = BST->Right;
	return BST;
}

// 插入
BinTree Insert(BinTree BST, ElementType X)
{
	if (!BST)  // 如果为空,初始化该结点
	{
		BST = (BinTree)malloc(sizeof(struct TNode));
		BST->Data = X;
		BST->Left = NULL;
		BST->Right = NULL;
	}
	else  // 不为空
	{
		if (X < BST->Data)  // 如果小,挂在左边 
			BST->Left = Insert(BST->Left, X);
		else if (BST->Data < X)  // 如果大,挂在右边 
			BST->Right = Insert(BST->Right, X);
		// 如果相等,什么都不用做 
	}
	return BST;
}

// 删除
BinTree Delete(BinTree BST, ElementType X)
{
	BinTree tmp;
	if (!BST)
		cout << "Not Found" << endl;
	else if (X < BST->Data)   // X 比当前结点值小,在左子树继续查找删除 
		BST->Left = Delete(BST->Left, X);
	else if (BST->Data < X)   // X 比当前结点值大,在右子树继续查找删除 
		BST->Right = Delete(BST->Right, X);
	else  //  找到被删除结点
	{
		if (BST->Left && BST->Right)  // 被删除结点有俩孩子结点
		{
			tmp = FindMin(BST->Right);   // 找到右子树中值最小的
			BST->Data = tmp->Data;     // 用找到的值覆盖当前结点 
			BST->Right = Delete(BST->Right, tmp->Data);   // 把前面找到的右子树最小值结点删除 
		}
		else  // 被删除结点只有一个孩子结点或没有孩子结点
		{
			tmp = BST;
			if (!BST->Left && !BST->Right)  // 没有孩子结点 
				BST = NULL;
			else if (BST->Left && !BST->Right)  // 只有左孩子结点 
				BST = BST->Left;
			else if (!BST->Left && BST->Right)  // 只有右孩子结点 
				BST = BST->Right;
			free(tmp);
		}
	}
	return BST;
}

// 先序遍历 
void PreorderTraversal(BinTree BT)
{
	if (BT)
	{
		cout << BT->Data << " ";  // 打印根 
		PreorderTraversal(BT->Left);  // 进入左子树 
		PreorderTraversal(BT->Right);  // 进入右子树 
	}
}

// 中序遍历 
void InorderTraversal(BinTree BT)
{
	if (BT)
	{
		InorderTraversal(BT->Left);  // 进入左子树 
		cout << BT->Data << " ";  // 打印根 
		InorderTraversal(BT->Right);  // 进入右子树 
	}
}

  测试: 输入样例的测试效果如下图所示。

在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值