二叉排序树的操作

//1.根据给定的一组关键字(假设为int)序列,创建二叉排序树(CreateBst());
//2.分别使用递归和非递归方法,实现二叉排序树的查找操作(SreachK());
//3.计算查找成功与失败分别的ASL(ASLBST_V(),ASLBST_L())
//4.对二叉排序树进行插入关键字的操作(InsertBst());
//5.对二叉排序树进行删除关键字的操作(delBst());//删除方法一,删除方法二
//6.删除最小值(DelteMin())
//7.删除最大值(DeletMax())

#include<iostream>
#include<stack>
using namespace std;

#define  TRUE 1
#define  FALSE  0

typedef int KeyType, Status;

//二叉排序树的存储结构
typedef struct BSTNode {
	KeyType key;
	struct BSTNode* lchild, * rchild;
}BSTNode, * BiTree;

//非递归查找
Status SearchK1(BiTree bt, KeyType K, BiTree& p, BiTree& f) {
	//在根为bt的二叉排序树上查找键值等于K的记录
	//查找成功,用指针p指向目标;f指向目标的双亲,f初值为NULL
	p = bt;
	while (p) {
		if (K < p->key) { f = p; p = p->lchild; } //左子树上继续找
		else if (K > p->key)
		{
			f = p; p = p->rchild;
		} //右子树上继续找
		else return TRUE; //查找成功
	}//end while   
	return  FALSE;    //查找失败
}

int total_depth = 0;
int total_nodes = 0;
// 使用一个辅助函数进行递归遍历所有节点,并累积路径深度
void calculateDepth(BiTree node, int depth) {
	if (node == NULL) return;
	total_depth += depth;  // 累加路径深度
	total_nodes++;  // 统计节点个数
	calculateDepth(node->lchild, depth + 1);  // 递归遍历左子树
	calculateDepth(node->rchild, depth + 1);  // 递归遍历右子树
}
double ASL_T(BiTree bt) {//n为结点数
	if (bt == NULL) return 0.0;
	calculateDepth(bt, 1);  // 从根节点开始,初始深度为1
	// 计算平均查找长度(ASL)
	cout << total_depth << "/" << total_nodes<<"=";
	return (double)total_depth / total_nodes;

}

int total_depth_2 = 0;
int total_nodes_2;
int depth(BSTNode* bt, BSTNode* p) {//求深度
	if (bt == nullptr) {
		return 0;
	}
	if (p->key == bt->key) return 1;
	else if (p->key < bt->key) return depth(bt->lchild, p) + 1;
	else return depth(bt->rchild, p) + 1;
}
int countEmptyNodes(BiTree bt,BSTNode* root) {//求结点数和路径之和
	if (root == nullptr) {
		return 0;
	}
	int emptyNodes = 0;
	if ((root->lchild && !root->rchild) || (!root->lchild && root->rchild)) {
		emptyNodes = 1; total_depth_2 += depth(bt, root);
	}
	else if (!root->lchild && !root->rchild) {
		emptyNodes = 2; total_depth_2 += 2*depth(bt, root);
	}
	return emptyNodes + countEmptyNodes(bt,root->lchild) + countEmptyNodes(bt,root->rchild);
}
double ASL_F(BiTree bt) {//求失败的平均路径
	if (bt == NULL) return 0.0;
	BSTNode* root = bt;
	total_nodes_2 = countEmptyNodes(bt, root);
	cout << total_depth_2 << "/" << total_nodes_2 << "=";
	return (double)total_depth_2 / total_nodes_2;
	
}

//递归查找
Status SearchK2(BiTree bt, KeyType K, BiTree& p, BiTree& f) {
	if (bt == NULL) {
		p = NULL;
		return FALSE;
	}
	if (K == bt->key) {
		p = bt;
		return TRUE;
	}
	f = bt;
	if (K < bt->key) return SearchK2(bt->lchild, K, p, f);
	else return SearchK2(bt->rchild, K, p, f);
}

//插入用来检验递归查找的正确
void InsertBst(BiTree& bt, KeyType k) {
	BSTNode* f = NULL;
	BSTNode* p = NULL;
	if (!SearchK1(bt, k, f, p)) { //未找到R.key
		BSTNode* S = new BSTNode;
		S->key = k;
		S->lchild = S->rchild = NULL;
		if (!p) bt = S;   //二叉排序树中的第一个结点
		else if (S->key < p->key) p->lchild = S;
		else  p->rchild = S;
		cout << "插入成功!";
	}//end if
	else cout << "该结点已经存在!\n";
}

//生成
void CreateBst(BiTree& bt, int n, KeyType a[]) {
	bt = NULL;
	for (int i = 0; i < n; i++) {
		BSTNode* f = NULL;
		BSTNode* p = NULL;
		if (!SearchK1(bt, a[i], f, p)) { //未找到R.key
			BSTNode* S = new BSTNode;
			S->key = a[i];
			S->lchild = S->rchild = NULL;
			if (!p) bt = S;   //二叉排序树中的第一个结点
			else if (S->key < p->key) p->lchild = S;
			else  p->rchild = S;
		}
	}//for
}//end CreateBST 

//删除
//方法一
void delBst(BiTree& bt, KeyType K) {
	BSTNode* f = NULL;
	BSTNode* p,*q;
	//SearchK1(bt, k, p, f);
	//if (p == NULL) {
	//	cout << "无这个删除结点!";
	//	return;
	//}
	//if (p->lchild == NULL && p->rchild == NULL) {//度为0
	//	if (f->lchild == p) f->lchild = NULL;
	//	else  f->rchild = NULL;
	//	free(p);
	//}
	//else if (p->lchild && p->rchild == NULL) {//度为1
	//	if (f->lchild == p) f->lchild = p->lchild;
	//	else f->rchild = p->lchild;
	//	free(p);
	//}
	//else if (p->rchild && p->lchild == NULL) {//度为1
	//	if (f->lchild == p) f->lchild = p->rchild;
	//	else f->rchild = p->rchild;
	//	free(p);
	//}
	if (!SearchK1(bt, K, p, f)) return;//被删结点不存在
	q = p->lchild;
	if (p->rchild && p->rchild) {//度为2(方法一)
		BSTNode* s = p->lchild;
		while (s->rchild) s = s->rchild; //找P的中序前驱S
		s->rchild = p->rchild;         //P的右孩子交给S
		if (!f) bt = q;
		else if (f->lchild == p) f->lchild = p->lchild;      else f->rchild = p->lchild; //P的左孩子交给F
		free(p);
	}
	else {  //被删结点p的度为1,0
		q = p->rchild ? p->rchild : p->lchild;//q指向p的孩子
		if (!f) bt = q; //被删结点p是树根,重新指定树根
		else if (p == f->lchild)f->lchild = q; else f->rchild = q;
		delete p; //释放被删结点p
	}//else
	cout << "删除成功!";
}
//删除(方法二)
void DeleteBST(BiTree& bt, KeyType  K) { //删除bt上键值等于K的结点
	BSTNode* f = NULL;
	BSTNode* p,* q;
	if (!SearchK1(bt, K, p, f)) return;//被删结点不存在
	if (p->lchild && p->rchild) {  //被删结点p的度为2—-方法2
		q = p;BSTNode* s = p->lchild;
		while (s->rchild) { q = s; s = s->rchild; } //找p的中序前驱s,
		p->key = s->key;  //用s的值替换p的值
		if (q != p) q->rchild = s->lchild; else q->lchild = s->lchild;
		delete s;  //释放s
	}//if
	else {  //被删结点p的度为1,0
		q = p->rchild ? p->rchild : p->lchild;//q指向p的孩子
		if (!f) bt = q; //被删结点p是树根,重新指定树根
		else if (p == f->lchild)f->lchild = q; else f->rchild = q;
		delete p; //释放被删结点p
	}//else
	cout << "删除成功!";
}

//删除最小值(三种情况)
void DeleteMin(BiTree &bt) {
	BSTNode* p = bt;
	while (p->lchild) p = p->lchild;
	DeleteBST(bt, p->key);
}
//删除最大值(三种情况)
void DeleteMax(BiTree& bt) {
	BSTNode* p = bt;
	while (p->rchild) p = p->rchild;
	DeleteBST(bt, p->key);
}
//中序遍历来检验操作
void inOrderTraverse(BiTree bt) {
	if (bt != NULL) {
		inOrderTraverse(bt->lchild);
		cout << bt->key << " ";
		inOrderTraverse(bt->rchild);
	}
}

stack <BiTree>S;
//中序遍历(非递归)调用栈库来实现
void inOrder(BiTree bt) {
	if (!bt) return;
	//InitStack(S);
	BSTNode* p = bt;
	while (p || !S.empty()) {//EmptyStack(S)
		while (p) {  //沿着左链一路向下

			S.push(p);//左孩子进栈
			p = p->lchild;
		}
		p = S.top();
		S.pop();
		cout << p->key << " "; //访问
		p = p->rchild;
	}
}

int main() {
	BiTree bt=NULL; KeyType k; KeyType* a=NULL;
	int n;
	char ch1 = '1', ch2;
	while (ch1 == '1') {
		cout << "\n\n\n\n";
		cout << "\n\n\t\t\t\t二   叉    树\n";
		cout << "\n\t\t*********************************************";
		cout << "\n\t\t*           1----建 二 叉 排 序 树          *";
		cout << "\n\t\t*           2----插 入                      *";
		cout << "\n\t\t*           3----删 除 方 法 一             *";
		cout << "\n\t\t*           4----删 除 方 法 二             *";
		cout << "\n\t\t*           5----删 除 最 小 值             *";
		cout << "\n\t\t*           6----删 除 最 大 值             *";
		cout << "\n\t\t*           7----查找成功的ASL              *";
		cout << "\n\t\t*           8----查找失败的ASL              *";
		cout << "\n\t\t*           9----中 序 遍 历                *";
		cout << "\n\t\t*           0----返       回                *";
		cout << "\n\t\t*********************************************";
		cout << "\n\t\t请选择菜单号:";
		cin >> ch2;
		cout << "\n";
		switch (ch2)
		{
		case'1':
			cout << "输入二叉排序树节点个数n: ";
			cin >> n;
			a = new KeyType[n];
			cout << "输入数据,中间空格: ";
			for (int i = 0; i < n; i++)
				cin >> a[i];
			CreateBst(bt, n, a);
			break;
		case '2':
			cout << "请输入你要插入的数:";
	        cin >> k;
	        InsertBst(bt, k);
	        cout << endl;
			break;
		case '3':
			cout << "请输入你要删除的数:";
			cin >> k;
			delBst(bt, k);
			cout << endl;
			break;
		case'4':
			cout << "请输入你要删除的数:";
            cin >> k;
            DeleteBST(bt, k);
            cout << endl;
            break;
		case'5':
			
			DeleteMin(bt);
			break;
		case'6':
			
			DeleteMax(bt);
			break;
		case'7':
			cout << "查找成功的ASL:";
			cout << ASL_T(bt) << endl;
			total_depth = 0;
			total_nodes = 0;
			break;
		case'8':
			cout << "查找失败的ASL:";
			cout << ASL_F(bt) << endl;
			total_depth_2 = 0;
			total_nodes_2 = 0;
			break;
		case'9':
			cout << "此时的中序遍历结果(递归):";
			inOrderTraverse(bt);
			cout << endl;
			cout << "此时的中序遍历结果(非递归):";
			inOrder(bt);
			cout << endl;
			break;
		case'0':
			ch1 = 0;
			break;
		default:
			cout << "\n\t\t***请注意:输入有误!***";
		}

	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值