数据结构|二叉排序树的构造、查找、删除

二叉排序树的构造

二叉排序树是有一定的规律,即左子树小于根节点小于柚子树。
思路是:先定义一个根节点,输入数字,其左右子树为NULL,然后依次输入数字,每次依次从根节点开始比。比它小就往左子树走,一直到某个结点子树为NULL时,将其赋上去,大于或等于根结点时往右走,其他类似。

中序遍历掌握了的话,就很快上手

构造二叉排序树

void CreatBTree(T_NODE &tree)
{
    
    
	/*前面构造一个根节点*/
	tree = new BTree;
	cout << "请输入一个元素" << endl;
	elementype c;
	cin >> c;
	tree->lef_child = NULL;
	tree->rig_child = NULL;

	if (c != 65535)
	{
    
    
		tree->data = c;
	}

	//后面用递归排序  输入元素
	while (c != 65535)
	{
    
    
		cin >> c;
		if (c != 65535)
		{
    
    
			InSerChild(tree, c);
		}
	}

}

void InSerChild(T_NODE &tree, elementype c)
{
    
    
	if (c<tree->data)
	{
    
    //如果小于根节点元素  则先判断左孩子是否存在
		if (tree->lef_child == NULL)//如果左孩子不存在
		{
    
    
			tree->lef_child = new BTree;
			tree->lef_child->lef_child = NULL;
			tree->lef_child->rig_child = NULL;
			tree->lef_child->data = c;
		}
		else//左孩子存在
		{
    
    
			InSerChild(tree->lef_child, c);

		}

	}
	else
	{
    
    
		if (tree->rig_child == NULL)
		{
    
    
			tree->rig_child = new BTree;
			tree->rig_child->lef_child = NULL;
			tree->rig_child->rig_child = NULL;
			tree->rig_child->data = c;
		}
		else
		{
    
    
			InSerChild(tree->rig_child, c);
		}
	}
}

二叉排序树的查找

void FindBTree(T_NODE &tree, elementype x)
{
    
    
	if (x<tree->data)
	{
    
    
		if (tree->lef_child != NULL)
		{
    
    
			FindBTree(tree->lef_child, x);
		}
		else
		{
    
    
			cout << "此内容小于根节点元素,且树中无此元素" << endl;
		}
	}
	else if (x>tree->data)
	{
    
    
		if (tree->rig_child != NULL)
		{
    
    
			FindBTree(tree->rig_child, x);
		}
		else
		{
    
    
			cout << "此内容大于根节点元素,且树中无此元素" << endl;
		}
	}
	else
	{
    
    
		cout << "存在" << endl;
	}
}

二叉排序树的删除

/*二叉树的删除*/
//首先得先进行查找
void Del_Fin_BT(T_NODE &tree, elementype x)
{
    
    
	if (x<tree->data)
	{
    
    
		if (tree->lef_child != NULL)
		{
    
    
			Del_Fin_BT(tree->lef_child, x);
		}
		else
		{
    
    
			cout << "此内容小于根节点元素,且树中无此元素" << endl;
		}
	}
	else if (x>tree->data)
	{
    
    
		if (tree->rig_child != NULL)
		{
    
    
			Del_Fin_BT(tree->rig_child, x);
		}
		else
		{
    
    
			cout << "此内容大于根节点元素,且树中无此元素" << endl;
		}
	}
	else
	{
    
    
		Del_BT(tree);
	}
}

void Del_BT(T_NODE &tree)
{
    
    
	//删除该节点内容,然后为了保持二叉排序树的结构
	//应该,寻找该结点的前序和后继元素,取其一替代该节点
	T_NODE q, s;
	q = new BTree;
	s= new BTree;
	if (tree->lef_child == NULL)
	{
    
    
		q = tree;//先将其用q表示
		tree = tree->rig_child;//柚子树替代    这里就是关键了   如果柚子树存在则直接取代,否则的话 还存在,右子树原本就是NULL  取代之后也是NULL 所以也删除了
		free(q);//释放该节点
	}
	else if (tree->rig_child==NULL)
	{
    
    
		q = tree;
		tree = tree->rig_child;
		free(q);
	}
	else//如果都不为空,那么就要选择了
	{
    
    
		/*q->lef_child = tree->lef_child;
		q->rig_child = tree->rig_child;
		q->data = tree->data;*/
		q = tree;
		s = tree->lef_child;//选择该结点t的左子树最大的一个,也就是最接近它的一个
		while (s->rig_child)//最大的在结点柚子树  所以寻找右侧的
		{
    
    
			q = s;//用q记录最大柚子树的 根结点
			s = s->rig_child;//最大柚子树
		}
		tree->data = s->data;//直接赋值进去

		if (q != tree)//有树状结构时,直接使得最大柚子树的左子树取代其位置
		{
    
    
			q->rig_child = s->lef_child;

		}
		else//只有一个元素时
		{
    
    
			q->lef_child = s->lef_child;
		}
		free(s);
	}
}

二叉排序树的删除,要记住被删元素,左(右)取代其位置的上一结点
所以用q记录最大柚子树的 根结点 这点在二叉树中序遍历那也有

全部代码 方便以后看而已

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

typedef int elementype;
typedef int Status;

typedef struct BTree
{
    
    
	elementype data;
	struct BTree *lef_child, *rig_child;
}*T_NODE, Bnode;

void InSerChild(T_NODE &tree, elementype c);
//void FindBTree(T_NODE &tree, elementype x);
void Del_BT(T_NODE &tree);
void CreatBTree(T_NODE &tree)
{
    
    
	/*前面构造一个根节点*/
	tree = new BTree;
	cout << "请输入一个元素" << endl;
	elementype c;
	cin >> c;
	tree->lef_child = NULL;
	tree->rig_child = NULL;

	if (c != 65535)
	{
    
    
		tree->data = c;
	}

	//后面用递归排序  输入元素
	while (c != 65535)
	{
    
    
		cin >> c;
		if (c != 65535)
		{
    
    
			InSerChild(tree, c);
		}
	}

}


void InSerChild(T_NODE &tree, elementype c)
{
    
    
	if (c<tree->data)
	{
    
    //如果小于根节点元素  则先判断左孩子是否存在
		if (tree->lef_child == NULL)//如果左孩子不存在
		{
    
    
			tree->lef_child = new BTree;
			tree->lef_child->lef_child = NULL;
			tree->lef_child->rig_child = NULL;
			tree->lef_child->data = c;
		}
		else//左孩子存在
		{
    
    
			InSerChild(tree->lef_child, c);

		}

	}
	else
	{
    
    
		if (tree->rig_child == NULL)
		{
    
    
			tree->rig_child = new BTree;
			tree->rig_child->lef_child = NULL;
			tree->rig_child->rig_child = NULL;
			tree->rig_child->data = c;
		}
		else
		{
    
    
			InSerChild(tree->rig_child, c);
		}
	}
}

Status OutputTree_mid(T_NODE &tree)
{
    
    
	if (tree == NULL)
	{
    
    
		return 0;
	}
	else
	{
    
    
		if (tree->lef_child != NULL)
		{
    
    
			OutputTree_mid(tree->lef_child);
			//cout << tree->lef_child->data << endl;
		}
		cout << tree->data << endl;
		if (tree->rig_child != NULL)
		{
    
    
			OutputTree_mid(tree->rig_child);
			//cout<<tree->rig_child->data << endl;
		}

	}
}

/*二叉排序树的查找*/

void FindBTree(T_NODE &tree, elementype x)
{
    
    
	if (x<tree->data)
	{
    
    
		if (tree->lef_child != NULL)
		{
    
    
			FindBTree(tree->lef_child, x);
		}
		else
		{
    
    
			cout << "此内容小于根节点元素,且树中无此元素" << endl;
		}
	}
	else if (x>tree->data)
	{
    
    
		if (tree->rig_child != NULL)
		{
    
    
			FindBTree(tree->rig_child, x);
		}
		else
		{
    
    
			cout << "此内容大于根节点元素,且树中无此元素" << endl;
		}
	}
	else
	{
    
    
		cout << "存在" << endl;
	}
}

/*二叉树的删除*/
//首先得先进行查找
void Del_Fin_BT(T_NODE &tree, elementype x)
{
    
    
	if (x<tree->data)
	{
    
    
		if (tree->lef_child != NULL)
		{
    
    
			Del_Fin_BT(tree->lef_child, x);
		}
		else
		{
    
    
			cout << "此内容小于根节点元素,且树中无此元素" << endl;
		}
	}
	else if (x>tree->data)
	{
    
    
		if (tree->rig_child != NULL)
		{
    
    
			Del_Fin_BT(tree->rig_child, x);
		}
		else
		{
    
    
			cout << "此内容大于根节点元素,且树中无此元素" << endl;
		}
	}
	else
	{
    
    
		Del_BT(tree);
	}
}

void Del_BT(T_NODE &tree)
{
    
    
	//删除该节点内容,然后为了保持二叉排序树的结构
	//应该,寻找该结点的前序和后继元素,取其一替代该节点
	T_NODE q, s;
	q = new BTree;
	s= new BTree;
	if (tree->lef_child == NULL)
	{
    
    
		q = tree;//先将其用q表示
		tree = tree->rig_child;//柚子树替代    这里就是关键了   如果柚子树存在则直接取代,否则的话 还存在,右子树原本就是NULL  取代之后也是NULL 所以也删除了
		free(q);//释放该节点
	}
	else if (tree->rig_child==NULL)
	{
    
    
		q = tree;
		tree = tree->rig_child;
		free(q);
	}
	else//如果都不为空,那么就要选择了
	{
    
    
		/*q->lef_child = tree->lef_child;
		q->rig_child = tree->rig_child;
		q->data = tree->data;*/
		q = tree;
		s = tree->lef_child;//选择该结点t的左子树最大的一个,也就是最接近它的一个
		while (s->rig_child)//最大的在结点柚子树  所以寻找右侧的
		{
    
    
			q = s;//用q记录最大柚子树的 根结点
			s = s->rig_child;//最大柚子树
		}
		tree->data = s->data;//直接赋值进去

		if (q != tree)//有树状结构时,直接使得最大柚子树的左子树取代其位置
		{
    
    
			q->rig_child = s->lef_child;

		}
		else//只有一个元素时
		{
    
    
			q->lef_child = s->lef_child;
		}
		free(s);
	}
}

void main()
{
    
    
	T_NODE tree;
	CreatBTree(tree);
	OutputTree_mid(tree);
	elementype x;
	cout << "请输入一个需要查找的树元素" << endl;
	cin >> x;
	FindBTree(tree,x);
	cout << "删除该元素" << endl;
	Del_Fin_BT(tree,x);
	OutputTree_mid(tree);
	system("pause");
}


猜你喜欢

转载自blog.csdn.net/weixin_46096297/article/details/114334557