【数据结构C++】二叉树的各种功能递归实现

自学数据结构二叉树后,自己将二叉树用递归的方式完全实现了一遍,包括前中后序遍历,基本都是通过递归来实现的。

.h文件

typedef int ElemType;
typedef struct TreeNode {
	ElemType data;
	struct TreeNode* Left;
	struct TreeNode* Right;
}treeNode;

class BstRecursion {
public:
	//构造函数
	BstRecursion();

	//析构函数
	~BstRecursion();

	//1、获得树的大小
	int GetTreeSize();

	//2、插入元素
	void Insert(ElemType x);

	//3、查找节点元素是否存在
	bool Find(ElemType x);

	//4、查找最大元素
	treeNode* FindMax();
	
	//5、查找最小元素
	treeNode* FindMin();

	//6、删除元素(可以利用Find)
	void Delete(ElemType x);

	//7、判断是否为空树
	bool IsEmpty();

	//8、前序遍历
	void PreTraversal();

	//9、中序遍历
	void InTraversal();

	//10、后序遍历
	void PosTraversal();

	//11、清除所有元素
	void clear();

private:
	int treeSize;  //树的大小
	treeNode* Root; //根节点
	int IsDeleted; //判断是否删除成功的标志

	//各递归函数
	//插入递归
	treeNode* InsertElem(treeNode* root, ElemType x);

	//查找递归
	bool FindElem(treeNode* root, ElemType x);

	//查找最大值递归
	treeNode* FindMaxElem(treeNode* root);

	//查找最小值递归
	treeNode* FindMinElem(treeNode* root);

	//删除递归
	treeNode* DeleteElem(treeNode* root, ElemType x);

	//前序遍历递归
	void PreTraversalElem(treeNode* root);

	//中序遍历递归
	void InTraversalElem(treeNode* root);

	//后序遍历递归
	void PosTraversalElem(treeNode* root);
};

.cpp文件

//构造函数
BstRecursion::BstRecursion() {
	this->treeSize = 0;
	this->Root = NULL;
}

//析构函数
BstRecursion::~BstRecursion() {
	clear();
}

//1、获得树的大小
int BstRecursion::GetTreeSize() {
	return this->treeSize;
}

//2、插入元素
void BstRecursion::Insert(ElemType x) {
	this->Root = InsertElem(this->Root, x);
	this->treeSize++;
}
//递归插入
treeNode* BstRecursion::InsertElem(treeNode* root, ElemType x) {

	//找到需要插入的位置,创建新节点插入
	if (root == NULL) {
		treeNode* newNode = new treeNode();
		newNode->data = x;
		newNode->Left = newNode->Right = NULL;
		return newNode;
	}

	if (x <= root->data) root->Left = InsertElem(root->Left, x);
	if (x > root->data)  root->Right = InsertElem(root->Right, x);

	return root; //返回传入的根节点地址
}

//3、查找节点元素是否存在
bool BstRecursion::Find(ElemType x) {
	return FindElem(this->Root, x);
}
bool BstRecursion::FindElem(treeNode* root, ElemType x) {
	//两个递归结束条件
	if (root == NULL) return false; 
	if (root->data == x) return true;

	if (x < root->data) return FindElem(root->Left, x);
	if (x > root->data) return FindElem(root->Right, x);
}

//4、查找最大元素
treeNode* BstRecursion::FindMax() {
	//如果树为空,直接结束
	if (this->Root == NULL) return NULL;
	return FindMaxElem(this->Root);
}
treeNode* BstRecursion::FindMaxElem(treeNode* root) {
	//递归结束条件:没有右子树可以继续访问
	if (root->Right == NULL) return root;

	//进入递归,一层层返回最终找到的最大节点位置
	return FindMaxElem(root->Right);
}

//5、查找最小元素
treeNode* BstRecursion::FindMin() {
	//如果树为空,直接结束
	if (this->Root == NULL) return NULL;
	return FindMinElem(this->Root);
}
//查找最小值递归
treeNode* BstRecursion::FindMinElem(treeNode* root) {
	//递归结束条件:没有左子树可以继续访问
	if (root->Left == NULL) return root;

	//进入递归,一层层返回最终找到的最小节点位置
	return FindMinElem(root->Left);
}

//6、删除元素
void BstRecursion::Delete(ElemType x) {
	this->IsDeleted = 0;
	this->Root = DeleteElem(this->Root, x);

	//如果删除成功,对树节点数目操作
	if (this->IsDeleted)
		this->treeSize--;
}
//删除递归
treeNode* BstRecursion::DeleteElem(treeNode* root, ElemType x) {
	//没找到该元素,结束递归
	if (root == NULL) return root;

	if (x < root->data) root->Left = DeleteElem(root->Left, x);
	else if (x > root->data) root->Right = DeleteElem(root->Right, x);
	else {
		//如果找到了要删除的节点
		this->IsDeleted = 1; //标志为删除成功

		//如果要删除节点没有子节点
		if (root->Left == NULL && root->Right == NULL) {
			delete(root);
			root = NULL;
		}	
		//要删除的节点有两个子节点
		else if (root->Left != NULL && root->Right != NULL) {

			//找到要删除节点的右子树中最小元素,将其替换到要删除节点位置,再将其删除
			treeNode* temp = FindMinElem(root->Right);
			root->data = temp->data;

			//删除该最大子节点
			root->Right = DeleteElem(root->Right, temp->data);
		}
		//要删除的节点有一个子节点
		else {

			if (root->Left != NULL) {
				treeNode* temp = root;
				root = root->Left;
				delete(temp);
			}
			else if (root->Right != NULL) {
				treeNode* temp = root;
				root = root->Right;
				delete(temp);
			}
		}
		//结束递归,返回这个root的新地址
		return root;
	}
	return root;
}

//7、判断是否为空树
bool BstRecursion::IsEmpty() {
	if (this->Root == NULL) return true;
	return false;
}

//8、前序遍历
void BstRecursion::PreTraversal() {
	PreTraversalElem(this->Root);
	cout << endl;
}
// 前序遍历递归
void BstRecursion::PreTraversalElem(treeNode* root) {
	if (root == NULL) return;

	cout << root->data << " ";
	PreTraversalElem(root->Left);
	PreTraversalElem(root->Right);
}

//9、中序遍历
void BstRecursion::InTraversal() {
	InTraversalElem(this->Root);
	cout << endl;
}
//中序遍历递归
void BstRecursion::InTraversalElem(treeNode* root) {
	if (root == NULL) return;

	InTraversalElem(root->Left);
	cout << root->data << " ";
	InTraversalElem(root->Right);
}

//10、后序遍历
void BstRecursion::PosTraversal() {
	PosTraversalElem(this->Root);
	cout << endl;
}
//后序遍历递归
void BstRecursion::PosTraversalElem(treeNode* root) {
	if (root == NULL) return;

	PosTraversalElem(root->Left);
	PosTraversalElem(root->Right);
	cout << root->data << " ";
}

//11、清除所有元素
void BstRecursion::clear() {

	while (!IsEmpty()) {
		ElemType x = this->Root->data;
		Delete(x);
	}
}

测试:

int main() {

	BstRecursion bst;
	bst.Insert(20);
	bst.Insert(8);
	bst.Insert(12);
	bst.Insert(11);
	bst.Insert(6);
	bst.Insert(5);
	bst.Insert(9);
	bst.Insert(30);
	bst.Insert(35);
	bst.Insert(28);

	if (bst.Find(6))
		cout << "找到元素:6!" << endl;
	else
		cout << "没找到该元素!" << endl;

	cout << "最大元素为:" << bst.FindMax()->data << endl;
	//bst.Delete(8);
	bst.PreTraversal();
	bst.InTraversal();
	bst.PosTraversal();
	bst.Delete(20);
	bst.clear();
	return 0;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
叉树的非归遍历方式有三种,分别是前序遍历、中序遍历和后序遍历。 前序遍历:前序遍历的非实现需要借助一个辅助栈。首先将根节点入栈,然后开始循环,每次循环先取出栈顶元素,并输出该元素的值,然后判断该节点是否有右子节点,如果有,则入栈,再判断是否有左子节点,如果有,则入栈。需要注意的是,因为栈是后进先出的数据结构,所以在入栈的时候,先入右子节点再入左子节点,这样才能保证访问节点的顺序符合前序遍历。 中序遍历:中序遍历的非实现同样需要借助一个辅助栈。首先将根节点压入栈,然后不断将根节点的左子节点入栈,并将指针指向左子节点,直到左子节点为空。这时开始循环,每次循环先取出栈顶元素,并输出该元素的值,然后判断该节点是否有右子节点,如果有,则将右子节点压入栈。 后序遍历:后序遍历的非实现需要两个栈。首先将根节点入栈1,然后开始循环,从栈1中取出栈顶元素,将其值保存到一个临时变量中,然后将该节点的左子节点和右子节点入栈1。然后判断栈1是否为空,如果不为空,则重复上述操作,否则开始循环栈2,从栈2中取出栈顶元素,并输出该元素的值。在将节点入栈1时,先入左子节点再入右子节点,这样遍历完后输出的顺序就是后序遍历的顺序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值