数据结构与算法导论(C++)连载(六)--二叉搜索树

二叉搜索树-非空左子树小于根结点键值,非空右子树大于根结点键值,左右子树均为二叉搜索树。

一、二叉搜索树基本实现

新建一个类BinSeachTree,在BinSeachTree.h中:

#include"iostream"
using namespace std;

#define ElementType int
#define SearchTree TreeNode*
#define Position TreeNode*

class TreeNode {
public:
	ElementType element;
	SearchTree left;
	SearchTree right;
};
class BinSeachTree
{
public:
	BinSeachTree();
	~BinSeachTree();
	SearchTree CreateSearchTree(SearchTree tree);
	Position FindFromTree(ElementType x, SearchTree tree);
	Position FindMax(SearchTree tree);
	Position FindMax2(SearchTree tree);
	Position FindMin(SearchTree tree);
	Position FindMin2(SearchTree tree);
	SearchTree InsertToTree(ElementType x, SearchTree tree);
	SearchTree DeleteFromTree(ElementType x, SearchTree tree);
	void PreOrderTraversal(SearchTree BT);
	SearchTree tree;
};

在BinSeachTree.cpp中:

#include "BinSeachTree.h"



BinSeachTree::BinSeachTree()
{
	
}


BinSeachTree::~BinSeachTree()
{
}

/*
输入的结构:
              30
			 /  \
            20   50
			 \  /  \
             25 40  70
			 /     /  \
			23    54   80
			            \
						92
*/
SearchTree BinSeachTree::CreateSearchTree(SearchTree tree) {  //二叉搜索树的建立
	int tree_element;
	while (cin >> tree_element) {
		if (tree_element == '#')
			break;
		else
			tree = InsertToTree(tree_element, tree);
	}
	return tree;
}

Position BinSeachTree::FindFromTree(ElementType x, SearchTree tree) { //二叉搜索树查找
	if (tree == NULL)
		return NULL;
	if (tree->element < x)
		tree->right = FindFromTree(x, tree->right);
	else if (x < tree->element)
		tree->left = FindFromTree(x, tree->left);
	else
		return tree;
}

Position BinSeachTree::FindMax(SearchTree tree) {   //二叉搜索树最大结点-非递归
	if (tree != NULL)
		while (tree->right != NULL)
			tree = tree->right;
	return tree;
}

Position BinSeachTree::FindMax2(SearchTree tree) {   //二叉搜索树最大结点-递归
	if (tree == NULL)
		return NULL;
	else if (tree->right == NULL)
		return tree;
	else
		return FindMax2(tree->right);
}

Position BinSeachTree::FindMin(SearchTree tree) { //二叉搜索树最小结点-非递归
	if (tree != NULL)
		while (tree->left)
			tree = tree->left;
	return tree;
}

Position BinSeachTree::FindMin2(SearchTree tree) { //二叉搜索树最小结点-递归
	if (tree == NULL)
		return NULL;
	else if (tree->left == NULL)
		return tree;
	else
		return FindMin(tree->left);
}

SearchTree BinSeachTree::InsertToTree(ElementType x, SearchTree tree) {  //二叉搜索树插入-递归
	if (tree == NULL) {
		SearchTree P = new TreeNode;
		if (P == NULL) {
			cout << "malloc failed" << endl;
		}
		else {
			P->element = x;
			P->left = NULL;
			P->right = NULL;
			tree = P;
		}
	}
	else if (x < tree->element)
		tree->left = InsertToTree(x, tree->left);
	else if (x > tree->element)
		tree->right = InsertToTree(x, tree->right);
	return tree;
}

SearchTree BinSeachTree::DeleteFromTree(ElementType x, SearchTree tree) {  //二叉搜索树删除-递归
	Position temp;
	if (tree == NULL) {
		cout << "The tree is empty, no element." << endl;
	}
	else if (x < tree->element) {  //寻找要删除的位置
		tree->left = DeleteFromTree(x, tree->left);
	}
	else if (x > tree->element) {  //寻找要删除的位置
		tree->right = DeleteFromTree(x, tree->right);
	}
	else if (tree->left && tree->right) {  //找到要删除的位置,该节点有两个孩子
										   /*temp = FindMin(tree->right);*/ //可以换成左子树最大
		temp = FindMax(tree->left);
		tree->element = temp->element;
		tree->right = DeleteFromTree(tree->element, tree->right);
	}
	else { //仅有一个子树,或者为叶节点
		temp = tree;
		if (tree->left == NULL)
			tree = tree->right;
		else if (tree->right == NULL)
			tree = tree->left;
		delete temp;
	}
	return tree;
}

void BinSeachTree::PreOrderTraversal(SearchTree BT)  //先序遍历
{
	if (BT) {
		cout << BT->element << " ";
		PreOrderTraversal(BT->left);
		PreOrderTraversal(BT->right);
	}
}

在main.cpp中:

#include"BinSeachTree.h"

int main()
{
	BinSeachTree P ;
	P.tree = P.CreateSearchTree(P.tree);
	P.PreOrderTraversal(P.tree);
	cout << "\n";
	cout << "Max is :" << P.FindMax(P.tree)->element << "\n";
	cout << "Min is :" << P.FindMin(P.tree)->element << "\n";
	P.tree = P.InsertToTree(35, P.tree); P.tree = P.InsertToTree(45, P.tree); P.tree = P.InsertToTree(41, P.tree);
	cout << "Insert 35 45 41:";
	P.PreOrderTraversal(P.tree);
	cout << "\n";
	P.tree = P.DeleteFromTree(50, P.tree);
	cout << "Delete 50:";
	P.PreOrderTraversal(P.tree);
	cout << "\n";
	system("pause");
	return 0;
}

运行结果:

二、二叉搜索树应用-判断是否为同一棵树

新建一个类,在xxx.h中:

#include"iostream"

using namespace std;

#define BBTree BalanceBinTreeNode* 

class BalanceBinTreeNode
{
public:
	int v;
	BBTree Left;
	BBTree Right;
	int flag;
};
class BalanceBinTree
{
public:
	BalanceBinTree();
	~BalanceBinTree();
	BBTree MakeTree(int N);
	BBTree Insert(BBTree T, int V);
	BBTree NewNode(int V);
	int check(BBTree T, int V);
	int Judge(BBTree T, int N);
	void ResetT(BBTree T);
	void FreeTree(BBTree T);
	BBTree BBTPtr;

};

在xxx.cpp中:

#include "BalanceBinTree.h"
/*平衡二叉树平衡因子(任意左右子树的深度之差)小于等于1
这里时比较两个二叉搜索数是否为同一棵树*/


BalanceBinTree::BalanceBinTree()
{
	BBTPtr = new BalanceBinTreeNode;
}


BalanceBinTree::~BalanceBinTree()
{
}

/*
输入样例:
 4 2 - 一棵树有几点个结点,比较几次
 3 1 4 2 -最原始的树
 3 4 1 2 -需要比较的第一棵树
 3 2 4 1 -需要比较的第二棵树
 ...下一次比较循环
 0 - 退出
*/
BBTree BalanceBinTree::MakeTree(int N) //输入二叉搜索树
{
	BBTree T;
	int i, V;
	cin >> V;
	T = NewNode(V);
	for (i = 1; i<N; i++) {
		cin >> V;
		T = Insert(T, V);
	}
	return T;
}

BBTree BalanceBinTree::Insert(BBTree T,int V) //插入二叉搜索树
{
	if (!T) T = NewNode(V);
	else {
		if (V>T->v)
			T->Right = Insert(T->Right, V);
		else
			T->Left = Insert(T->Left, V);
	}
	return T;
}

BBTree BalanceBinTree::NewNode(int V)
{
	BBTree T = new BalanceBinTreeNode;
	T->v = V;
	T->Left = T->Right = NULL;
	T->flag = 0;
	return T;
}

int BalanceBinTree::check(BBTree T, int V)
{
	if (T->flag) {
		if (V<T->v) return check(T->Left, V);
		else if (V>T->v) return check(T->Right, V);
		else return 0;
	}
	else {
		if (V == T->v) {
			T->flag = 1;
			return 1;
		}
		else return 0;
	}
}

int BalanceBinTree::Judge(BBTree T, int N)  //判断是否是同一颗二叉搜索树
{
	int i, V, flag = 0;
	/* flag: 0代表目前还一致, 1代表已经不一致*/
	cin >> V;
	if (V != T->v) flag = 1;
	else T->flag = 1;
	for (i = 1; i<N; i++) {
		cin >> V;
		if ((!flag) && (!check(T, V))) flag = 1;
	}
	if (flag) return 0;
	else return 1;
}

void BalanceBinTree::ResetT(BBTree T) /* 清除T中各结点的flag标记 */
{
	if (T->Left) ResetT(T->Left);
	if (T->Right) ResetT(T->Right);
	T->flag = 0;
}
void BalanceBinTree::FreeTree(BBTree T) /* 释放T的空间 */
{
	if (T->Left) FreeTree(T->Left); 
	if (T->Right) FreeTree(T->Right);
	delete T;
}

在main.cpp中:

#include"BalanceBinTree.h"

int main()
{
	int N, L, i;
	BalanceBinTree T;
	cin >> N;
	while (N) {
		cin >> L;
		T.BBTPtr = T.MakeTree(N);
		for (i = 0; i<L; i++) {
			if (T.Judge(T.BBTPtr, N))cout << "Yes\n";
			else cout << "No\n";
			T.ResetT(T.BBTPtr); /*清除T中的标记flag*/
		}
		T.FreeTree(T.BBTPtr);
		cin >> N;
	}
	system("pause");
	return 0;
}

运行结果:

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值