二叉搜索树的相关操作

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014303647/article/details/82777585

二叉搜索树是一些AVL,RB-tree等的基础,所以了解二叉搜索树的基本操作很重要。

定义:

若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。

这里给出自己画的一个二叉树,不知道有啥好的画图软件

在这里插入图片描述

首先我们得知道如何验证是否是一颗标准的二叉树,中序遍历,中序遍历的二叉搜索树肯定死有序的,并且是升序。

首先声明二叉树的节点

struct TreeNode 
{
	int val;
	TreeNode *left;
	TreeNode *right;
	TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

查找二叉搜索树的节点

那么如何在一颗二叉搜索树中找到特定的节点,因为根节点比左节点大,比右节点小,只需要和根节点比较即可。

//root表示当前遍历的根节点 pre为遍历的上一个节点,target为目标节点
bool SearchBST(TreeNode* root,int key,TreeNode* &pre,TreeNode* &target)
{
	if (!root)
	{
		target = pre;
		return false;
	}
	if (root->val == key)
	{
		target = root;
		return true;
	}
	pre = root;
	if (root->val < key)
		SearchBST(root->right, key, pre, target);
	else
		SearchBST(root->left, key, pre, target);
}

删除二叉搜索树的节点

删除二叉树的节点有三种情况

1: 当这个节点的右子树为空,那么直接用该节点的左子树覆盖即可。

2: 当这个节点的左子树为空,那么直接用该节点的右子树覆盖即可。

3:当这个节点左右子树都存在的时候,则只需要找到中序遍历的下一个节点去替代他即可,所以从右子树开始找,然后一直找左节点,即是该节点在中序遍历中的下一个节点B,然后遍历的时候位置B的前一个节点,最后置为NULL即可。

代码:

void DeleteBSTnode(TreeNode* &root,int key)
{
	TreeNode* s;
	if (root == NULL)
	{
		return;
	}
	if (root->val == key)
	{
		//cout << " 找到了该值" << endl;
		cout << root->val << endl;
		if (root->right == NULL)
		{
			//cout << "窝在这里" << endl;
			s = root;
			root = root->left;
			free(s);
		}
		else if (root->left == NULL)
		{
			s = root;
			root = root->right;
			free(s);
		}
		//如果左右子节点都有
		else
		{
			TreeNode* pre;
			pre = root;
			s = root->right;
			while (s->left)
			{
				pre = s;
				s = s->left;
			}
			root->val = s->val; 
			pre->left = NULL;
			free(s);
		}
	}
	else if (root->val<key) DeleteBSTnode(root->right, key);
	else DeleteBSTnode(root->left, key);
}

插入节点到二叉搜索树

其实和遍历二叉树没多大区别,找到该插入的位置即可。如果树为空,那么这个新节点为根节点。

代码:

void InsertBSTnode(TreeNode* root, int key)
{
	TreeNode* newNode = new TreeNode(key);
	if (root == NULL)
	{
		newNode = root;
		return;
	}
	TreeNode* pre = NULL;
	TreeNode* target = NULL;
	if (SearchBST(root, key, pre, target))
	{
		cout << "该节点已经存在" << endl;
		return;
	}
	else
	{
		TreeNode* plastNode = NULL;
		while(root)
		{
			plastNode = root;
			if (root->val > key) root = root->left;
			else root = root->right;
		}
		if (plastNode->val < key) plastNode->right = newNode;
		else plastNode->left = newNode;
	}
}

完整的代码,包括测试代码

#include "stdafx.h"
#include<iostream>
#include<vector>
#include<stack>
#include<map>
#include<string>
#include<queue>
#include<set>
#include<algorithm>
#include<malloc.h>
#include<stdlib.h>
#include<functional>
using namespace std;


struct TreeNode 
{
	int val;
	TreeNode *left;
	TreeNode *right;
	TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};


void mid_order(TreeNode* Troot)
{
	if (Troot) 
	{
		mid_order(Troot->left);
		cout << Troot->val << " ";
		mid_order(Troot->right);
	}
}


//root表示当前遍历的根节点 pre为遍历的上一个节点,target为目标节点
bool SearchBST(TreeNode* root,int key,TreeNode* &pre,TreeNode* &target)
{
	if (!root)
	{
		target = pre;
		return false;
	}
	if (root->val == key)
	{
		target = root;
		return true;
	}
	pre = root;
	if (root->val < key)
		SearchBST(root->right, key, pre, target);
	else
		SearchBST(root->left, key, pre, target);
}



void DeleteBSTnode(TreeNode* &root,int key)
{
	TreeNode* s;
	if (root == NULL)
	{
		return;
	}
	if (root->val == key)
	{
		//cout << " 找到了该值" << endl;
		cout << root->val << endl;
		if (root->right == NULL)
		{
			//cout << "窝在这里" << endl;
			s = root;
			root = root->left;
			free(s);
		}
		else if (root->left == NULL)
		{
			s = root;
			root = root->right;
			free(s);
		}
		//如果左右子节点都有
		else
		{
			TreeNode* pre;
			pre = root;
			s = root->right;
			while (s->left)
			{
				pre = s;
				s = s->left;
			}
			root->val = s->val; 
			pre->left = NULL;
			free(s);
		}
	}
	else if (root->val<key) DeleteBSTnode(root->right, key);
	else DeleteBSTnode(root->left, key);
}


void InsertBSTnode(TreeNode* root, int key)
{
	TreeNode* newNode = new TreeNode(key);
	if (root == NULL)
	{
		newNode = root;
		return;
	}
	TreeNode* pre = NULL;
	TreeNode* target = NULL;
	if (SearchBST(root, key, pre, target))
	{
		cout << "该节点已经存在" << endl;
		return;
	}
	else
	{
		TreeNode* plastNode = NULL;
		while(root)
		{
			plastNode = root;
			if (root->val > key) root = root->left;
			else root = root->right;
		}
		if (plastNode->val < key) plastNode->right = newNode;
		else plastNode->left = newNode;
	}
}

int main()
{

	TreeNode* p1 = new TreeNode(8);
	TreeNode* p2 = new TreeNode(5);
	TreeNode* p3 = new TreeNode(10);
	TreeNode* p4 = new TreeNode(4);
	TreeNode* p5 = new TreeNode(7);
	TreeNode* p6 = new TreeNode(9);
	TreeNode* p7 = new TreeNode(12);
	TreeNode* p8 = new TreeNode(6);
	TreeNode* p9 = new TreeNode(11);

	p1->left = p2;
	p1->right = p3;
	p2->left = p4;
	p2->right = p5;
	p3->left = p6;
	p3->right = p7;
	p5->left = p8;
	p7->left = p9;

	TreeNode*  root = p1;

	mid_order(root);
	cout << endl;

	/*TreeNode* pre = NULL;
	TreeNode* target = NULL;

	cout << SearchBST(root, 7, pre, target) << endl;*/

	//cout << target->val << " "<< target->left->val << endl;
//	if (target->right)  cout << target->right->val << endl;

//	cout << root->val << endl;

	//DeleteBSTnode(root, 5);
	//mid_order(root);
	//cout << endl;

	int key = 0;
	while (key != -1)
	{
		cout << "请输入你要插入的值" << endl;
		cin >> key;
		InsertBSTnode(root, key);
		mid_order(root);
		cout << endl;
	}
	return 0;
}


猜你喜欢

转载自blog.csdn.net/u014303647/article/details/82777585
今日推荐