算法导论第十二章-二叉搜索树-Cpp代码实现

实现了BST(二叉搜索树)的一些基本操作,比如插入,删除,查找元素,查找前驱后继等。

binany_search_tree.h

#pragma once

/*************************************************
Author:董小歪
Date:2016-06-12
Description:算法导论第十二章-二叉搜索树-Cpp代码实现
**************************************************/

#ifndef BINANY_SEARCH_TREE
#define BINANY_SEARCH_TREE

#include <iostream>
#include <string>

using namespace std;

struct TreeNode
{
	int val;
	TreeNode *left, *right, *parent;
	TreeNode(int _val) :val(_val), left(nullptr), right(nullptr), parent(nullptr){}
};

class MyBST 
{
public:
	MyBST():root(nullptr){}						//构造函数
	MyBST(TreeNode* _root):root(_root){}

	void inorder_tree_walk();					//中序遍历BST
	void tree_insert(int val);					//插入元素
	void tree_delete(int val);					//删除元素
	void transplant(TreeNode* u, TreeNode* v);	//删除元素移植过程

	TreeNode* get_root();						//返回树根
	TreeNode* tree_search(int val);				//查找元素
	TreeNode* iterative_tree_search(int val);	//非递归查找元素
	TreeNode* tree_minimum(TreeNode* node);		//获取最小关键字元素
	TreeNode* tree_maximum(TreeNode* node);		//获取最大关键字元素
	TreeNode* tree_successor(TreeNode* node);	//获取当期元素的后继
	TreeNode* tree_predecessor(TreeNode* node);	//获取当前元素的前驱

private:
	void inorder_tree_walk(TreeNode* node);					//中序遍历BST
	TreeNode* tree_search(TreeNode* node, int val);			//查找元素

	TreeNode *root;								//树根
};

TreeNode* MyBST::get_root()
{
	return root;
}

void MyBST::inorder_tree_walk()
{
	inorder_tree_walk(root);
}

void MyBST::inorder_tree_walk(TreeNode* node)
{
	if (node)
	{
		inorder_tree_walk(node->left);
		cout << node->val << " ";
		inorder_tree_walk(node->right);
	}
}

TreeNode* MyBST::tree_search(int val)
{
	return tree_search(root, val);
}

TreeNode* MyBST::tree_search(TreeNode* node, int val)
{
	if (!node || node->val == val)
		return node;
	if (val < node->val)
		return tree_search(node->left, val);
	else
		return tree_search(node->right, val);
}

TreeNode* MyBST::iterative_tree_search(int val)
{
	TreeNode* temp = root;
	while (temp && temp->val != val)
	{
		if (temp->val < val)
			temp = temp->right;
		else
			temp = temp->left;
	}
	return temp;
}

TreeNode* MyBST::tree_minimum(TreeNode* node)
{
	TreeNode* temp = node;
	while (temp && temp->left)
		temp = temp->left;
	return temp;
}

TreeNode* MyBST::tree_maximum(TreeNode* node)
{
	TreeNode* temp = node;
	while (temp && temp->right)
		temp = temp->right;
	return temp;
}

TreeNode* MyBST::tree_successor(TreeNode* node)
{
	if (node->right)
		return tree_minimum(node->right);
	TreeNode *temp = node->parent;
	while (temp && temp->right == node)
	{
		node = temp;
		temp = temp->parent;
	}
	return temp;
}

TreeNode* MyBST::tree_predecessor(TreeNode* node)
{
	if(node->left)
		return tree_maximum(node->left);
	TreeNode* temp = node->parent;
	while (temp && temp->left == node)
	{
		node = temp;
		temp = temp->parent;
	}
	return temp;
}

void MyBST::tree_insert(int val)
{
	TreeNode* node = new TreeNode(val), *parent = nullptr;
	TreeNode* r = root;
	while (r)
	{
		parent = r;
		if (r->val < val)
			r = r->right;
		else
			r = r->left;
	}
	node->parent = parent;
	if (parent == nullptr)
		root = node;
	else if (val < parent->val)
		parent->left = node;
	else
		parent->right = node;
}

void MyBST::transplant(TreeNode* u, TreeNode* v)
{
	if (u->parent == nullptr)
		root = v;
	else if (u == u->parent->left)
		u->parent->left = v;
	else
		u->parent->right = v;
	if (v)
		v->parent = u->parent;
}

void MyBST::tree_delete(int val)
{
	TreeNode* del = tree_search(val);	//找到要删除的结点元素
	if (del->left == nullptr)			//如果左子树为空
		transplant(del, del->right);
	else if (del->right == nullptr)		//右子树为空
		transplant(del, del->left);
	else
	{
		TreeNode* successor = tree_successor(del);//删除结点的后继
		if (successor != del->right)				//如果后继不是当前删除结点的右孩子
		{
			transplant(successor, successor->right);
			successor->right = del->right;
			successor->right->parent = successor;
		}
		transplant(del, successor);
		successor->left = del->left;
		successor->left->parent = successor;
	}
}

#endif // !BINANY_SEARCH_TREE


测试代码:

#include "binany_search_tree.h"

int main()
{
	cout << "创建二叉搜索树" << endl; MyBST mybst;
	cout << "中序遍历二叉搜索树:"; mybst.inorder_tree_walk(); cout << endl;
	cout << "插入元素12:"; 	mybst.tree_insert(12); mybst.inorder_tree_walk(); cout << endl;
	cout << "插入元素5:"; 	mybst.tree_insert(5); mybst.inorder_tree_walk(); cout << endl;
	cout << "插入元素2:"; 	mybst.tree_insert(2); mybst.inorder_tree_walk(); cout << endl;
	cout << "插入元素9:"; 	mybst.tree_insert(9); mybst.inorder_tree_walk(); cout << endl;
	cout << "插入元素18:"; 	mybst.tree_insert(18); mybst.inorder_tree_walk(); cout << endl;
	cout << "插入元素15:"; 	mybst.tree_insert(15); mybst.inorder_tree_walk(); cout << endl;
	cout << "插入元素13:"; 	mybst.tree_insert(13); mybst.inorder_tree_walk(); cout << endl;
	cout << "插入元素17:"; 	mybst.tree_insert(17); mybst.inorder_tree_walk(); cout << endl;
	cout << "插入元素19:"; 	mybst.tree_insert(19); mybst.inorder_tree_walk(); cout << endl;
	cout << "查找元素15:"; 
	TreeNode* find = mybst.tree_search(15); 
	if (find) cout << "元素找到:" << to_string(find->val) << endl;
	else cout << "元素未找到" << endl;
	cout << "查找元素14:";
	find = mybst.tree_search(14);
	if (find) cout << "元素找到:" << to_string(find->val) << endl;
	else cout << "元素未找到" << endl;
	cout << "最小元素为:" << mybst.tree_minimum(mybst.get_root())->val << endl;
	cout << "最大元素为:" << mybst.tree_maximum(mybst.get_root())->val << endl;
	cout << "元素12的后继为:" << mybst.tree_successor(mybst.get_root())->val << endl;
	cout << "元素9的后继为:" << mybst.tree_successor(mybst.get_root()->left->right)->val << endl;
	cout << "元素12的前驱为:" << mybst.tree_predecessor(mybst.get_root())->val << endl;
	cout << "元素13的前驱为:" << mybst.tree_predecessor(mybst.get_root()->right->left->left)->val << endl;

	cout << "删除元素19:"; mybst.tree_delete(19); mybst.inorder_tree_walk(); cout << endl;  //没有孩子的情况
	cout << "删除元素18:"; mybst.tree_delete(18); mybst.inorder_tree_walk(); cout << endl;  //只有一个左孩子的情况
	cout << "删除元素12:"; mybst.tree_delete(12); mybst.inorder_tree_walk(); cout << endl;  //同时有左右孩子的情况
	system("pause");
}

测试结果:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值