二叉查找树(BSTree)

难点:二叉查找树的删除

二叉查找树

概念:

二叉查找树:要么为空树,若二叉查找树不为空,则需要满足以下性质:

(1)左子树上所有的节点值均小于或等于其根结点的值。

(2)右子树上所有的节点值均大于或等于其根结点的值。

(3)左右子树也一定分别为二叉查找树。

特点:

(1)将数据分为左右子树两部分,加快了查找的速度。

(2)中序遍历的结果为有序的。

优点:

(1)查找的时间复杂度为O(logN)。

(2)一般情况下,插入和删除的时间复杂度为O(logN)。

缺点:

(1)二叉排序树的构建和数据的输入顺序有极大的关系,如果输入为有序,二叉排序树将退化为线性结构,导致查找的时间复杂度降为O(N)。

举例:

数据序列:5,8,3,2,4,1,6,7,9

这样在查找是就将数据分为两部分进行查找,时间复杂度为O(logN)。

数据序列:1,2,3,4,5

 

如果数据本身有序,那么二叉排序树将退化为线性结构。

二叉查找树C++实现

二叉查找树的操作有:创建、添加、删除、销毁等基本操作,其他操作都比较简单,只有删除比较复杂。

二叉查找树的删除:

(1)待删除的节点为叶子节点时:将父节点对应的子节点的指针置空。

(2)待删除的节点只有左子树/右子树时:将父节点对应子节点的指针置为待删除节点的子节点。

(3)待删除的节点既有左子树又有右子树时:将左子树中最右节点\右子树最左节点和待删除节点交换,之后删除待删除节点。

BinarySearchTree.h文件:

#ifndef Binary_Search_Tree
#define Binary_Search_Tree

#include <iostream>
using namespace std;

//树的节点的类型
typedef int DataType;
//数据的节点
struct TreeNode
{
	DataType data;
	struct TreeNode* left;
	struct TreeNode* right;
};

//二叉排序树的数据结构
class BinarySearchTree
{
public:
	BinarySearchTree();
	~BinarySearchTree();
	TreeNode* createBSTree(DataType* dataList,int length);//创建二叉排序树
	void inorderTraversal(TreeNode* node);//二叉排序树的中序遍历
	void addTreeNode(DataType data);//给树添加新的节点
	void delTreeNode(DataType data);//删除树中的节点
	TreeNode* findTreeNode(DataType data);//查询
	void desTree(TreeNode* node);//销毁树
	TreeNode* getTreeRoot();
private:
	TreeNode* treeRoot;//树根
};

typedef BinarySearchTree BST;
#endif

//BinarySearchTree.cpp

#include "BinarySearchTree.h"

BST::BinarySearchTree()
{
	treeRoot = NULL;
}

BST::~BinarySearchTree()
{
	desTree(treeRoot);
}

TreeNode* BST::createBSTree(DataType* dataList,int length)
{
	treeRoot = new TreeNode();
	treeRoot->data = dataList[0];
	treeRoot->left = NULL;
	treeRoot->right = NULL;
	for (int i = 1; i < length; ++i)
	{
		addTreeNode(dataList[i]);
	}
	return treeRoot;
}

void BST::addTreeNode(DataType data)
{
	TreeNode* newNode = new TreeNode();
	newNode->data = data;
	newNode->left = NULL;
	newNode->right = NULL;
	TreeNode* node = treeRoot;
	while (1)
	{
		//如果新结点的值大于根结点的值,则在右子树。
		if (newNode->data >= node->data)
		{
			//若右子树为空,这直接插入
			if (node->right == NULL)
			{
				node->right = newNode;
				break;
			}
			//不为空,则继续判断。
			else
			{
				node = node->right;
			}
		}
		//否则在左子树上。
		else
		{
			if (node->left == NULL)
			{
				node->left = newNode;
				break;
			}
			else
			{
				node = node->left;
			}
		}
	}
}

void BST::inorderTraversal(TreeNode* node)
{
	if (node != NULL)
	{
		inorderTraversal(node->left);
		cout << node->data << ",";
		inorderTraversal(node->right);
	}
}

void BST::desTree(TreeNode* node)
{
	if (node != NULL)
	{
		desTree(node->left);
		desTree(node->right);
		delete [] node;
		node = NULL;
	}
}

TreeNode* BST::findTreeNode(DataType data)
{
	TreeNode* node = treeRoot;
	while (node)
	{
		if (node->data == data)
		{
			return node;
		}
		else if (node->data < data)
		{
			node = node->right;
		}
		else
		{
			node = node->left;
		}
	}
	return node;
}

void BST::delTreeNode(DataType data)
{
	TreeNode* node = treeRoot;//待删除节点的值
	TreeNode* parNode = NULL;//待删除节点的父节点
	while (node)
	{
		if (node->data == data)
		{
			//(1)叶子结点
			if (node->left == NULL && node->right == NULL)
			{
				//根结点
				if (parNode == NULL)
				{
					treeRoot = NULL;
				}
				else
				{
					(node == parNode->left) ? parNode->left = NULL : parNode->right = NULL;
				}
				delete[] node;
				node = NULL;
			}
			//(2)只有左/右子树
			else if (node->left == NULL || node->right == NULL)
			{
				//根节点
				if (parNode == NULL)
				{
					(node->left == NULL) ? treeRoot = node->right : treeRoot = node->left;
				}
				else
				{
					if (parNode->left == node)
					{
						(node->left == NULL) ? parNode->left = node->right : parNode->left = node->left;
					}
					else
					{
						(node->right == NULL) ? parNode->right = node->right : parNode->right = node->left;
					}
				}
				delete[] node;
				node = NULL;
			}
			//(3)既有左子树,又有右子树
			else
			{
				//寻找左子树的最右节点作为替换节点
				TreeNode* replaceNode = node->left;
				while (replaceNode->right)
				{
					replaceNode = replaceNode->right;
				}
				//保存替换节点的值
				DataType tempData = replaceNode->data;
				//删除replaceNode节点
				delTreeNode(tempData);
				replaceNode = NULL;
				//替换值域
				node->data = tempData;
			}
			break;
		}
		else
		{
			parNode = node;
			if (data < node->data)
			{
				node = node->left;
			}
			else
			{
				node = node->right;
			}
		}
	}
}

TreeNode* BST::getTreeRoot()
{
	return treeRoot;
}

Main.cpp

#include "BinarySearchTree.h"
int main()
{
	BST bsTree;
	DataType dataArr[] = { 5, 8, 3, 2, 4, 1, 6, 7, 9 };
	TreeNode* treeNode = bsTree.createBSTree(dataArr, sizeof(dataArr) / sizeof(dataArr[0]));
	//bsTree.addTreeNode(10);
	//bsTree.addTreeNode(9);
	//bsTree.addTreeNode(11);
	bsTree.delTreeNode(5);
	bsTree.inorderTraversal(bsTree.getTreeRoot());
	cout << endl;
	bsTree.delTreeNode(3);
	bsTree.inorderTraversal(bsTree.getTreeRoot());
	cout << endl;
	bsTree.delTreeNode(8);
	bsTree.inorderTraversal(bsTree.getTreeRoot());
	cout << endl;
	return 0;
}

以上代码如存在错误,请及时留言,谢谢。

数据结构可视化网站:https://www.cs.usfca.edu/~galles/visualization/Algorithms.html

 

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个 Python 实现的二叉搜索树类,以及按照您的要求进行的测试代码: ```python class Node: def __init__(self, key): self.left = None self.right = None self.val = key class BSTree: def __init__(self): self.root = None # 插入节点 def insert(self, key): if self.root is None: self.root = Node(key) else: self._insert(key, self.root) def _insert(self, key, node): if key < node.val: if node.left is None: node.left = Node(key) else: self._insert(key, node.left) elif key > node.val: if node.right is None: node.right = Node(key) else: self._insert(key, node.right) else: return # 中序遍历 def inorder_traversal(self): if self.root is None: return [] else: return self._inorder_traversal(self.root) def _inorder_traversal(self, node): res = [] if node: res = self._inorder_traversal(node.left) res.append(node.val) res = res + self._inorder_traversal(node.right) return res # 查找节点 def search(self, key): if self.root is None: return None else: return self._search(key, self.root) def _search(self, key, node): if node is None or node.val == key: return node elif key < node.val: return self._search(key, node.left) else: return self._search(key, node.right) # 测试代码 bst = BSTree() keys = [4, 9, 5, 11, 25, 3, 12, 17, 1, 32, 20, 15] for key in keys: bst.insert(key) print(bst.inorder_traversal()) print(bst.search(17)) print(bst.search(38)) ``` 以上代码会输出以下内容: ``` [1, 3, 4, 5, 9, 11, 12, 15, 17, 20, 25, 32] <__main__.Node object at 0x7fe7f8d5b040> None ``` 其中,`[1, 3, 4, 5, 9, 11, 12, 15, 17, 20, 25, 32]` 是中序遍历的结果,`<__main__.Node object at 0x7fe7f8d5b040>` 是关键字为 17 的结点,`None` 是关键字为 38 的结点(不存在)。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值