二叉查找树的操作,插入,删除,遍历等等C++实现

数据结构 专栏收录该内容
4 篇文章 0 订阅

二叉查找树的基本操作C++实现

#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
int pd = 0;//非常重要,判断一棵树是不是空树

struct treeNode;
typedef struct treeNode* BST;
struct ElementType;

struct ElementType {
	double key;
};

struct treeNode {
	ElementType data;
	treeNode* leftNode;
	treeNode* rightNode;
};

BST Init(BST& b) {
	treeNode* temp = new treeNode();
	if (temp == NULL) return NULL;
	temp->leftNode = NULL;
	temp->rightNode = NULL;
	b = temp;
	return b;
}

void Display(BST b, int i) {//相当于前序遍历   如何进行层序遍历?
	cout << "位置: " << i << ",元素为:" << b->data.key << endl;
	if (b->leftNode) Display(b->leftNode, i * 2);
	if (b->rightNode) Display(b->rightNode, i * 2 + 1);
}

bool Insert(const ElementType x, BST b) {
	if (pd == 0) {
		b->data = x;
		pd = 1;
		return true;
	}
	treeNode* temp = new treeNode();
	temp = b;
	//需要用一个指针指向这个节点的父节点
	treeNode* father=new treeNode();
	father = temp;
	while (temp) {
		father = temp;
		if (temp->data.key == x.key) return false;
		else if (temp->data.key > x.key) temp = temp->leftNode;
		else temp = temp->rightNode;
	}
	treeNode* son = new treeNode();
	son->data = x;
	son->leftNode = NULL;
	son->rightNode = NULL;
	if (father->data.key > son->data.key) father->leftNode = son;
	else father->rightNode = son;
	return true;
}

treeNode* SearchRecursion(const ElementType x, treeNode* b) {
	//if (b) {
	//	if (x.key == b->data.key) return b;
	//	else if (x.key < b->data.key) SearchRecursion(x, b->leftNode);
	//	else SearchRecursion(x, b->rightNode);
	//}
	//return NULL;/that why? this has an error message.
	if (!b) return NULL;
	if (x.key == b->data.key) return b;
	else if (x.key < b->data.key) SearchRecursion(x, b->leftNode);
	else SearchRecursion(x, b->rightNode);

}

treeNode* SearchIteration(const ElementType x, const BST b) {
	treeNode* temp = new treeNode();
	temp = b;
	while (b) {
		if (x.key == temp->data.key) return temp;
		else if (x.key < temp->data.key) temp = temp->leftNode;
		else temp = temp->rightNode;
	}
	return NULL;
}

//Delete1和Delete2中有三段同样查找该节点父节点的操作,思考把该操作抽出来,单独做一个函数

bool Delete1(const ElementType x, BST b) {//删除的这个节点为叶节点
	//treeNode* temp = new treeNode();
	//temp = SearchRecursion(x, b);
	//delete temp;
	//temp = NULL;
	//return true;
	//首先是这种思路有什么问题
	//换一种思路····找到它的父节点让父节点指向它改为指向空
	treeNode* temp = new treeNode();
	temp = SearchRecursion(x, b);
	treeNode* father = new treeNode();
	father = b;
	while (father) {
		if (father->leftNode == temp || father->rightNode == temp) break;
		else if (father->data.key > temp->data.key) father = father->leftNode;
		else if (father->data.key < temp->data.key) father = father->rightNode;
	}
	//找到之后······
	if (father->leftNode == temp) father->leftNode = NULL;
	else if (father->rightNode == temp) father->rightNode = NULL;
	delete temp;
	return true;
}

bool Delete2(const ElementType x, BST b) {//删除的节点只有一个子节点
	treeNode* temp = new treeNode();思考如何把下面的if和else if两个语句合并成一个
	temp = SearchRecursion(x, b);
	if (temp->leftNode == NULL && temp->rightNode != NULL) {//找到的节点只有一个节点,且该节点的子节点右节点
		//先找的该节点的父节点
		treeNode* father = new treeNode();
		father = b;
		while (father) {
			if (father->leftNode == temp || father->rightNode == temp) break;
			else if (father->data.key > temp->data.key) father = father->leftNode;
			else if (father->data.key < temp->data.key) father = father->rightNode;
		}
		//找到之后······
		if (father->leftNode == temp) father->leftNode = temp->rightNode;
		else if (father->rightNode == temp) father->rightNode = temp->rightNode;
		delete temp;
		return true;
	}
	else if (temp->rightNode == NULL && temp->leftNode != NULL) {//找的的节点只有一个节点,且该节点的子节点为左节点
		//先找的该节点的父节点
		treeNode* father = new treeNode();
		father = b;
		while (father) {
			if (father->leftNode == temp || father->rightNode == temp) break;
			else if (father->data.key > temp->data.key) father = father->leftNode;
			else if (father->data.key < temp->data.key) father = father->rightNode;
		}
		//找到之后······
		if (father->leftNode == temp) father->leftNode = temp->leftNode;
		else if (father->rightNode == temp) father->rightNode = temp->leftNode;
		delete temp;
		return true;
	}
}

bool Delete3(const ElementType x, BST b) {//删除的节点有两个子节点
	//先找到该节点(A)右子树中最小数据的节点(B)
	//把B中的数据赋给A
	//在把B节点用前两种适合的一个删除掉
	treeNode* temp = new treeNode();
	temp = SearchRecursion(x, b);
	treeNode* minSon = new treeNode();
	treeNode* minSonSelf = new treeNode();
	minSon = temp->rightNode;
	while (minSon) {
		minSonSelf = minSon;
		minSon = minSon->leftNode;
	}
	//先把B节点中的数据存起来
	//再把B节点删除掉
	//再把存起来的值放到要删除的节点
	ElementType x1;
	x1 = minSonSelf->data;
	
	if (minSonSelf->rightNode != NULL) Delete2(x1, b);
	else if (minSonSelf->rightNode == NULL) Delete1(x1, b);
	temp->data = x1;
	return true;
}

bool DeleteSum(const ElementType x, BST b) {//不改的话有一个弊端,搜索需要搜索两边,temp这个变量没有得到充分的利用
	treeNode* temp = new treeNode();
	temp = SearchRecursion(x, b);
	if (!temp) return false;//在该树中没有这个元素,没有找到
	else if (temp->leftNode == NULL && temp->rightNode == NULL)  Delete1(x, b);
	else if ((temp->leftNode == NULL && temp->rightNode != NULL) || (temp->rightNode == NULL && temp->leftNode != NULL)) Delete2(x, b);
	else if (temp->leftNode != NULL && temp->rightNode != NULL) Delete3(x, b);
}

void Print(treeNode* node) {//打印某一结点中数据的函数
	cout << node->data.key << " ";
}

void PreOrder(BST b) {//前序遍历
	if (b) {
		Print(b);
		PreOrder(b->leftNode);
		PreOrder(b->rightNode);
	}
}

void InOrder(BST b) {//中序遍历
	if (b) {
		InOrder(b->leftNode);
		Print(b);
		InOrder(b->rightNode);
	}
}

void PosOrder(BST b) {//后序遍历
	if (b) {
		PosOrder(b->leftNode);
		PosOrder(b->rightNode);
		Print(b);
	}
}

void LevelOrder(BST b) {//层序遍历
	queue<treeNode*> q;
	treeNode* temp = new treeNode();
	temp = b;
	q.push(temp);
	while (temp) {
		if (temp->leftNode) {
			q.push(temp->leftNode);
		}
		if (temp->rightNode) {
			q.push(temp->rightNode);
		}
		Print(temp);
		q.pop();
		if (q.empty()) return;
		temp = q.front();
	}
}

int main() {
	BST b;
	b = Init(b);
	ElementType q, w, e, r, t, y, u, i, o, p, s, d, f, g, h, j, k;
	q.key = 5;
	w.key = 10;
	e.key = 4;
	r.key = 2;
	t.key = 7;
	y.key = 9;
	u.key = 1;
	i.key = 3;
	o.key = 12;
	p.key = 0;
	s.key = 6;
	d.key = 11;
	f.key = 13;
	g.key = 15;
	h.key = 14;
	j.key = 16;
	k.key = 1.5;
	Insert(q, b);
	Insert(w, b);
	Insert(e, b);
	Insert(r, b);
	Insert(t, b);
	Insert(y, b);
	Insert(u, b);
	Insert(i, b);
	Insert(o, b);
	Insert(p, b);
	Insert(s, b);
	Insert(d, b);
	Insert(f, b);
	Insert(g, b);
	Insert(h, b);
	Insert(j, b);
	Insert(k, b);

	cout << "最初的树" << endl;
	Display(b, 1);
	cout << endl;

	/*//两种查找功能的测试
	treeNode* a1 = new treeNode();
	a1 = SearchIteration(p, b);
	cout << a1->data.key << endl;

	a1 = SearchRecursion(u, b);
	cout << a1->data.key << endl;*/

	//删除功能的测试
	//第一种删除叶节点测试
	/*DeleteSum(p, b);
	Display(b, 1);*/

	//第二种删除该节点只有一个子节点(左子节点)测试
	/*Delete2(u, b);
	Display(b, 1);*/
	//第二种删除该节点只有一个子节点(右子节点)测试
	/*Delete2(f, b);
	Display(b, 1);*/

	//第三种删除该节点有两个子节点测试1 ····最后删的节点没有子节点(右子节点)
	/*Delete3(q, b);
	Display(b, 1);*/
	//cout << endl;
	//第三种删除该节点有两个子节点测试2 ····最后删除的节点有子节点(右子节点)
	/*Delete3(s, b);
	Display(b, 1);*/
	
	//删除功能的总测试
	/*DeleteSum(q, b);
	Display(b, 1);
	cout << endl;
	DeleteSum(s, b);
	Display(b, 1);*/

	//接下来就是测试遍历的功能 前序遍历 中序遍历 后序遍历 层序遍历
	cout << "前序遍历:" << endl;
	PreOrder(b);
	cout << endl;
	
	cout << "中序遍历:" << endl;
	InOrder(b);
	cout << endl;
	
	cout << "后序遍历:" << endl;
	PosOrder(b);
	cout << endl;
	
	cout << "层序遍历:" << endl;
	LevelOrder(b);
	cout << endl;
	

	return 0;
} 

共有添加,删除,递归查找,迭代查找,显示整棵树,前,中,后,层,遍历功能。。。👊
运行倒是可以,但不是特别完美,还可以大幅度的优化。
有兴趣的可以优化试试🙃😄🙃

展开阅读全文
  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 创作都市 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值