データ構造|二分木の構築、検索、削除

二分探索木の構築

二分探索木には特定の規則があります。つまり、左側のサブツリーはルートノードよりも小さく、グレープフルーツツリーよりも小さくなります。
アイデアは次のとおりです。最初にルートノードを定義し、番号を入力します。その左右のサブツリーは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