数据结构 平衡二叉排序树的操作

#include<iostream>
#include<stdlib.h>
using namespace std;

//定义二叉树每一个节点
typedef struct TreeNode{
	int data;
	TreeNode *LChild;//左节点
	TreeNode *RChild;//右节点
}TreeNode;

/*
*  给二叉树插入一个值
*  参数:二叉树根结点Node,要插入的值data
*  插入成功,返回1
*  插入失败,函数返回0
*  这里是使用递归给二叉树插入值
*/
void Insert(TreeNode * &Node, int data){//这里使用引用
	if(Node==NULL){//为空,插入值,结束递归
		TreeNode *s;
		s = (TreeNode *)malloc(sizeof(TreeNode));
		s->data = data;//赋值
		s->RChild = s->LChild = NULL;//左右子树置空
		Node = s;
	}else if(data < Node->data){//插入的值小,那么插在左子树
		Insert(Node->LChild, data);
	}else if(data > Node->data){//插入的值大,那么插在右子树
		Insert(Node->RChild, data);
	}
}

/*
*  先序遍历
*  参数:二叉树根结点TreeNode *head
*  输出当前结点的值
*  返回空
*/
void PreOrder(TreeNode *head){
	if(head!=NULL){
		cout<<head->data<<" ";
		PreOrder(head->LChild);
		PreOrder(head->RChild);
	}
}

/*
*  中序遍历
*  可以按照递增顺序输出
*/
void InOrder(TreeNode *head){
	if(head!=NULL){
		InOrder(head->LChild);
		cout<<head->data<<" ";
		InOrder(head->RChild);
	}
}

/*
*  逆中序遍历
*  可以按照递减顺序输出
*/
void Inverse_InOrder(TreeNode *head){
	if(head!=NULL){
		InOrder(head->RChild);
		cout<<head->data<<" ";
		InOrder(head->LChild);
	}
}


/*
*  二叉排序树查找
*  参数:二叉树结点 Node ,要寻找的data值
*  返回结果:返回匹配data的结点的地址
*/
TreeNode *Search(TreeNode *Node, int data){
	if(Node==NULL)return NULL; //找不到,最后返回空
	else if(Node->data == data) return Node; //返回匹配data的结点的地址
	else if(Node->data > data) return Search(Node->LChild, data); //找到的值比较大,那就往左子树找
	else return Search(Node->RChild, data); //找到的值比较小,那就往右子树找
}

/*
*  二叉排序树删除结点
*  参数:二叉树根结点(引用) Node ,要删除的data值
*  将该节点删除,剩余结点满足二叉排序树的性质
*/
void Delete(TreeNode *&Node, int data){
	/*
		del_node: 要删除的节点
		del_parent: 删除节点的父结点
		Nodes: 临时使用,避免干扰Node的引用值
	*/
	TreeNode *del_node = NULL, *del_parent = NULL, *Nodes = Node;
	if(Nodes != NULL){
		while(Nodes){
			if(Nodes->data == data){ //找到需要删除结点
				del_node=Nodes;
				break;
			}
			del_parent = Nodes;
			if(Nodes->data > data)Nodes = Nodes->LChild; //往左子树找
			else Nodes = Nodes->RChild; //往右子树找
		}
		if(del_node == NULL)return;//找不到要删除的结点

		if(del_parent == NULL){//特殊情况,如果要删除根结点
			if(del_node->LChild!=NULL&&del_node->RChild!=NULL){//根结点同时有左右子树
				if(del_node->LChild->RChild == NULL){//根结点的左子结点没有右子树
					del_node->RChild->LChild = del_node->RChild;
					free(del_node);
				}else{
					//先将根结点的左子结点的右子树放到根结点右子节点的左子树叶子结点
					TreeNode *tmp = del_node->RChild;
					while(tmp->LChild!=NULL){ //寻找根结点的右子节点的最左的叶子结点
						tmp = tmp->LChild;
					}
					tmp->LChild = del_node->LChild->RChild; 
					del_node->LChild->RChild = del_node->RChild;
					Node = del_node->LChild;
					free(del_node);
				}
			}else{//根结点只有左子树或右子树(要是只有一个节点也直接删)
				//换成新的根结点
				if(del_node->LChild!=NULL)Node = Node->LChild;
				else Node = Node->RChild;
				free(del_node);
			}
			return;
		}

		//找到了要删除的结点
		if(del_node->LChild==NULL&&del_node->RChild==NULL){//若要删除的结点为叶子结点,直接删除
			//删除
			if(del_parent->LChild==del_node){
				del_parent->LChild=NULL;
				free(del_node);
			}else{
				del_parent->RChild=NULL;
				free(del_node);
			}
		}else if(del_node->LChild==NULL&&del_node->RChild != NULL){//若要删除的结点只有右子树
			del_parent->RChild = del_node->RChild;
			free(del_node);
		}else if(del_node->RChild==NULL&&del_node->LChild != NULL){//若要删除的结点只有左子树
			del_parent->LChild = del_node->LChild;
			free(del_node);
		}else{//若要删除的结点有左右子树
			if(del_parent->RChild==del_node){//删除的结点在父结点的右子树这边
				del_parent->RChild = del_node->LChild;
				if(del_parent->RChild->RChild!=NULL)del_node->RChild->LChild = del_parent->RChild->RChild;
				if(del_node->RChild!=NULL)del_parent->RChild->RChild = del_node->RChild;
				free(del_node);
			}else{//删除的结点在父结点的左子树这边
				del_parent->LChild = del_node->LChild;
				if(del_parent->LChild->RChild!=NULL)del_node->RChild->LChild = del_parent->LChild->RChild;
				if(del_node->RChild!=NULL)del_parent->LChild->RChild = del_node->RChild;
				free(del_node);
			}
		}
	}
}

int main(int argc, char const *argv[])
{
	/***************初始化过程***************/
	int data,len;
	// TreeNode *head=(TreeNode *)malloc(sizeof(TreeNode)); //初始化二叉树根结点的值为45
	// head->LChild = head->RChild = NULL;
	// head->data = 45;

	TreeNode *head=NULL;
	cout<<"输入要插入的个数:"<<endl;
	cin>>len;
	cout<<"输入要插入的值:"<<endl;
	for(int i=0;i<len;i++){
		cin>>data;
		Insert(head,data);
	}
	/***************初始化结束***************/

	// 先序遍历查看结果
	// PreOrder(head);
	// 中序遍历查看结果
	// InOrder(head);


	// 查找值为53的结点
	// TreeNode *result = Search(head,53);
	// cout<<result<<"  "<<result->data<<endl; //输出查到的结果和其地址


	// 中序遍历查看删除后排序的结果
	InOrder(head);
	cout<<endl;
	Delete(head,53);//删除53
	InOrder(head); //再查看中序遍历结果
	cout<<endl;

	return 0;
}


/*
输入过程:
	输入要插入的个数:
	6
	输入要插入的值:
	45 24 53 12 28 90
*/
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值