其他分享
首页 > 其他分享> > 二叉搜索树

二叉搜索树

作者:互联网

GitHub

二叉搜索树是以一棵二叉树来组织的,这样一棵树可以用一个链表数据结构来表示,其中每个结点就是一个对象。

二叉搜索树种的关键字总是以满足二叉搜索树的性质的方式来存储,一个结点的左子树中任意结点的键值不大于该结点的键值,且其右子树中任意结点树键值不小于该结点的键值。

如果按照中序遍历的方式输出一棵二叉搜索树的键值,所得到的是一个有序排列的队列。

BinarySearchTree.h

#pragma once


struct BinarySearchTreeNode
{
	BinarySearchTreeNode(int key) :Parent(nullptr), Left(nullptr), Right(nullptr), Key(key) { }
	BinarySearchTreeNode* Parent;
	BinarySearchTreeNode* Left;
	BinarySearchTreeNode* Right;

	int Key;
	void Print();
};
class BinarySearchTree
{
public:
	BinarySearchTree();
	~BinarySearchTree();
	void Report();
	void InorderTreeWalk(BinarySearchTreeNode* x);
	void PreorderTreeWalk(BinarySearchTreeNode* x);
	void PostorderTreeWalk(BinarySearchTreeNode* x);

	BinarySearchTreeNode* Minimum(BinarySearchTreeNode* x);
	BinarySearchTreeNode* Maximum(BinarySearchTreeNode* x);

	BinarySearchTreeNode* Search(BinarySearchTreeNode* x, int key);
	BinarySearchTreeNode* IterativeSearch(BinarySearchTreeNode* x, int key);

	BinarySearchTreeNode* Successor(BinarySearchTreeNode* x);
	BinarySearchTreeNode* Predecessor(BinarySearchTreeNode* x);

	void Insert(BinarySearchTreeNode* z);
	void Delete(BinarySearchTreeNode* z);

private:
	void Release(BinarySearchTreeNode* x);
	void Transplant(BinarySearchTreeNode* u, BinarySearchTreeNode* v);
public:
	BinarySearchTreeNode* Root;
};



void PrintNode(BinarySearchTreeNode* node);
void TestBinarySearchTree();

BinarySearchTree.cpp

#include "BinarySearchTree.h"
#include <iostream>
#include <vector>

using namespace std;

void BinarySearchTreeNode::Print()
{
	cout << Key << "  ";
}

BinarySearchTree::BinarySearchTree()
	:Root(nullptr)
{

}
BinarySearchTree::~BinarySearchTree()
{
	if (Root != nullptr)
	{
		Release(Root);
	}
	Root = nullptr;
}

void BinarySearchTree::Report()
{
	cout << "PreorderTreeWalk:\t";
	PreorderTreeWalk(Root);
	cout << endl << "InorderTreeWalk:\t";
	InorderTreeWalk(Root);
	cout << endl << "PostorderTreeWalk:\t";
	PostorderTreeWalk(Root);
	cout << endl;
}
void BinarySearchTree::InorderTreeWalk(BinarySearchTreeNode* x)
{
	if (x != nullptr)
	{
		InorderTreeWalk(x->Left);
		x->Print();
		InorderTreeWalk(x->Right);
	}
}
void BinarySearchTree::PreorderTreeWalk(BinarySearchTreeNode* x)
{
	if (x != nullptr)
	{
		x->Print();
		PreorderTreeWalk(x->Left);
		PreorderTreeWalk(x->Right);
	}
}
void BinarySearchTree::PostorderTreeWalk(BinarySearchTreeNode* x)
{
	if (x != nullptr)
	{
		PostorderTreeWalk(x->Left);
		PostorderTreeWalk(x->Right);
		x->Print();
	}
}

BinarySearchTreeNode* BinarySearchTree::Minimum(BinarySearchTreeNode* x)
{
	while (x->Left != nullptr)
	{
		x = x->Left;
	}
	return x;
}
BinarySearchTreeNode* BinarySearchTree::Maximum(BinarySearchTreeNode* x)
{
	while (x->Right != nullptr)
	{
		x = x->Right;
	}
	return x;
}

BinarySearchTreeNode* BinarySearchTree::Search(BinarySearchTreeNode* x, int key)
{
	if (x == nullptr || key == x->Key)
	{
		return x;
	}
	if (key < x->Key)
	{
		return Search(x->Left, key);
	}
	else
	{
		return Search(x->Right, key);
	}
}
BinarySearchTreeNode* BinarySearchTree::IterativeSearch(BinarySearchTreeNode* x, int key)
{
	while (x != nullptr && key != x->Key)
	{
		if (key < x->Key)
		{
			x = x->Left;
		}
		else
		{
			x = x->Right;
		}
	}
	return x;
}

BinarySearchTreeNode* BinarySearchTree::Successor(BinarySearchTreeNode* x)
{
	if (x->Right != nullptr)
	{
		return Minimum(x->Right);
	}
	auto y = x->Parent;
	while (y != nullptr && x == y->Right)
	{
		x = y;
		y = y->Parent;
	}
	return y;
}
BinarySearchTreeNode* BinarySearchTree::Predecessor(BinarySearchTreeNode* x)
{
	if (x->Left != nullptr)
	{
		return Maximum(x->Left);
	}
	auto y = x->Parent;
	while (y != nullptr && x == y->Left)
	{
		x = y;
		y = y->Parent;
	}
	return y;
}

void BinarySearchTree::Insert(BinarySearchTreeNode* z)
{
	BinarySearchTreeNode* x = Root;
	BinarySearchTreeNode* y = nullptr;
	while (x != nullptr)
	{
		y = x;
		if (z->Key < x->Key)
		{
			x = x->Left;
		}
		else
		{
			x = x->Right;
		}
	}
	z->Parent = y;
	if (y == nullptr)
	{
		Root = z;
	}
	else if (z->Key < y->Key)
	{
		y->Left = z;
	}
	else
	{
		y->Right = z;
	}
}
void BinarySearchTree::Delete(BinarySearchTreeNode* z)
{
	if (z->Left == nullptr)
	{
		Transplant(z, z->Right);
	}
	else if (z->Right == nullptr)
	{
		Transplant(z, z->Left);
	}
	else
	{
		BinarySearchTreeNode* y = Minimum(z->Right);
		if (y->Parent != z)
		{
			Transplant(y, y->Right);
			y->Right = z->Right;
			y->Right->Parent = y;
		}
		Transplant(z, y);
		y->Left = z->Left;
		y->Left->Parent = y;
	}
}

void BinarySearchTree::Release(BinarySearchTreeNode* x)
{
	if (x != nullptr)
	{
		Release(x->Left);
		Release(x->Right);
		delete x;
	}
}
void BinarySearchTree::Transplant(BinarySearchTreeNode* u, BinarySearchTreeNode* v)
{
	if (u->Parent == nullptr)
	{
		Root = v;
	}
	else if (u == u->Parent->Left)
	{
		u->Parent->Left = v;
	}
	else
	{
		u->Parent->Right = v;
	}
	if (v != nullptr)
	{
		v->Parent = u->Parent;
	}
}


void PrintNode(BinarySearchTreeNode* node)
{
	if (node)
	{
		node->Print();
	}
	else
	{
		cout << "Empty BinarySearchTreeNode." << endl;
	}
}
void TestBinarySearchTree()
{
	vector<BinarySearchTreeNode*> nodes;
	nodes.push_back(new BinarySearchTreeNode(4));
	nodes.push_back(new BinarySearchTreeNode(5));
	nodes.push_back(new BinarySearchTreeNode(7));
	nodes.push_back(new BinarySearchTreeNode(6));
	nodes.push_back(new BinarySearchTreeNode(3));
	nodes.push_back(new BinarySearchTreeNode(1));
	nodes.push_back(new BinarySearchTreeNode(2));
	

	BinarySearchTree* tree = new BinarySearchTree();
	for (auto node : nodes)
	{
		tree->Insert(node);
		tree->Report();
	}
	cout << endl << "Root:\t";
	PrintNode(tree->Root);
	cout << endl << "Minimum:\t";
	PrintNode(tree->Minimum(tree->Root));
	cout << endl << "Maximum:\t";
	PrintNode(tree->Maximum(tree->Root));

	cout << endl << "Search:\t";
	PrintNode(tree->Search(tree->Root, 6));

	cout << endl << "Successor:\t";
	PrintNode(tree->Successor(tree->Root));
	cout << endl << "Predecessor:\t";
	PrintNode(tree->Predecessor(tree->Root));
	
	cout << endl << endl;
	for (auto node : nodes)
	{
		tree->Report();
		tree->Delete(node);
	}
}

输出:

PreorderTreeWalk:       4
InorderTreeWalk:        4
PostorderTreeWalk:      4
PreorderTreeWalk:       4  5
InorderTreeWalk:        4  5
PostorderTreeWalk:      5  4
PreorderTreeWalk:       4  5  7
InorderTreeWalk:        4  5  7
PostorderTreeWalk:      7  5  4
PreorderTreeWalk:       4  5  7  6
InorderTreeWalk:        4  5  6  7
PostorderTreeWalk:      6  7  5  4
PreorderTreeWalk:       4  3  5  7  6
InorderTreeWalk:        3  4  5  6  7
PostorderTreeWalk:      3  6  7  5  4
PreorderTreeWalk:       4  3  1  5  7  6
InorderTreeWalk:        1  3  4  5  6  7
PostorderTreeWalk:      1  3  6  7  5  4
PreorderTreeWalk:       4  3  1  2  5  7  6
InorderTreeWalk:        1  2  3  4  5  6  7
PostorderTreeWalk:      2  1  3  6  7  5  4

Root:   4
Minimum:        1
Maximum:        7
Search: 6
Successor:      5
Predecessor:    3

PreorderTreeWalk:       4  3  1  2  5  7  6
InorderTreeWalk:        1  2  3  4  5  6  7
PostorderTreeWalk:      2  1  3  6  7  5  4
PreorderTreeWalk:       5  3  1  2  7  6
InorderTreeWalk:        1  2  3  5  6  7
PostorderTreeWalk:      2  1  3  6  7  5
PreorderTreeWalk:       6  3  1  2  7
InorderTreeWalk:        1  2  3  6  7
PostorderTreeWalk:      2  1  3  7  6
PreorderTreeWalk:       6  3  1  2
InorderTreeWalk:        1  2  3  6
PostorderTreeWalk:      2  1  3  6
PreorderTreeWalk:       3  1  2
InorderTreeWalk:        1  2  3
PostorderTreeWalk:      2  1  3
PreorderTreeWalk:       1  2
InorderTreeWalk:        1  2
PostorderTreeWalk:      2  1
PreorderTreeWalk:       2
InorderTreeWalk:        2
PostorderTreeWalk:      2

E:\GitHub\IntroductionToAlgorithms\C++\build\Debug\IntroductionToAlgorithms.exe (进程 4004)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .

 

标签:Right,BinarySearchTreeNode,void,BinarySearchTree,nullptr,二叉,搜索,Left
来源: https://blog.csdn.net/xunmeng2002/article/details/115466519