二叉树排序

#include <stdio.h>
#include <stdlib.h>
#include <sstream>;
#include <iostream>;
using namespace std;
struct node {
	int key;
	node* lnode;
	node* rnode;
	node() {
		 lnode = NULL;
		 rnode = NULL;
	}
};
void creattree(node* &root,int key) {//要传一个引用过去
	if (root == NULL)
	{
		node* tmp = new(node);//动态分配一个空间
		(*tmp).key = key;
		root = tmp;
	}
	else
	{
		if ((*root).key > key) {
			creattree((*root).lnode, key);//递归,走到root的左节点,再判断,直到root为空
		}
		if ((*root).key < key) {
		    creattree((*root).rnode, key);//递归,走到root的右节点,再判断,直到root为空
		}
	}
}
//先序遍历 根--左--右
void ss(node* root) {
	if (root == NULL) {
		return;
	}
	else
	{
		cout << (*root).key << "\n";
		ss((*root).lnode);
		ss((*root).rnode);
	}
}
//中序遍历  左--根--右
void rr(node* root) {
	if (root == NULL) {
		return;
	}
	else {
		rr((*root).lnode);
		cout << (*root).key << "\n";
		rr((*root).rnode);
	}
}
//后序遍历 左--右--根
void ll(node* root) {
	if (root == NULL) {
		return;
	}
	else {
		rr((*root).lnode);
		rr((*root).rnode);
		cout << (*root).key << "\n";
	}
}

//查找(中序)
bool search (node* root,int key) {
	if (root == NULL) {
		return false;
	}
	else {
		if ((*root).key == key)
			return true;
		return (search((*root).lnode, key) || search((*root).rnode, key));//对于每一个根节点,只要左右两节点
		                                                          //有一个找到了,就放回true
	}
}
//删除1:处理找到的最大左子节点,并且完成key值搬运
void Delete1(node* &root,node* tmp) {
	int x = (*tmp).key;
	if ((*tmp).lnode == NULL)//如果左右节点都没有(传入的节点必然没有右节点)
		tmp = NULL;//就让该节点直接为NULL,删除该节点
	else
		tmp = (*tmp).lnode;//有左节点,就让该节点直接指向左节点,达到左节点覆盖该节点的效果
	(*root).key = x;
}
//删除2:找到要删除节点的左节点的最大值
node* Delete2(node* &root) {
	if ((*root).rnode == NULL)//如果节点没有右节点就停止
		return root;
	else
		Delete2((*root).rnode);
}
//删除3:处理找到的最小右子节点,并且完成key值搬运
void Delete3(node* &root, node* tmp) {
	int x = (*tmp).key;
	if ((*tmp).rnode == NULL)//如果左右节点都没有(传入的节点必然没有左节点)
		tmp = NULL;//就让该节点直接为NULL,删除该节点
	else
		tmp = (*tmp).rnode;//有右节点,就让该节点直接指向右节点,达到右节点覆盖该节点的效果
	(*root).key = x;
}
//删除4:找到要删除节点的右节点的最小值
node* Delete4(node* &root) {
	if ((*root).lnode == NULL)//如果节点没有左节点就停止
		return root;
	else
		Delete2((*root).lnode);
}
void Delete(node* &root, int  key) {
	if (root == NULL) {
		return;
	}
	else
	{
		if ((*root).key == key)//找到要删除的数的节点
		{
			if ((*root).lnode == NULL && (*root).rnode == NULL)//如果左右节点都没有
				root = NULL;//就让该节点直接为NULL,删除该节点
			else
				if ((*root).lnode != NULL)//有左节点
				{

					node* p = Delete2((*root).lnode);    //1.传入左节点,通过Delete2找到左节点最大的子节点
					Delete1(root, p);	                      // 2.将左节点最大的子节点的key搬到root中
				}
				else//只有右节点
				{
					node* p = Delete4((*root).rnode);    //1.传入左节点,通过Delete4找到右节点最小的子节点
					Delete3(root, p);	                      // 2.将右节点最小的子节点的key搬到root中
				}
		}
		else
		{
			if ((*root).key < key)
			{
				Delete((*root).rnode, key);
			}
			else
			{
				Delete((*root).lnode, key);
			}
		}
			
	}
}
int main(void) {
	int n;
	node* root = NULL;
	while (cin >> n && n) {
		creattree(root, n);
	}
	rr(root);
	ll(root);
	ss(root);
	int m;
	cin >> m;
	if(search(root, m))
	    cout <<"找到了";
	else
		cout << "没找到";
	Delete(root,m);
	if (search(root, m))
		cout << "找到了";
	else
		cout << "没找到";
	system("pause");
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值