算法导论 第十二章:二叉查找树(Binary Search Trees)

二叉查找树具有如下性质:

x是二叉查找树中的一个节点,如果y是x左子树中的一个节点,则y.key ≤ x.key ; 如果 y 是 x 右子树中的一个节点,则 x.key ≥ y.key.

在二叉树上执行的基本操作的时间与树的高度成正比。当这棵树是完全二叉树时,这些操作的最坏情况运行时间为Θ(lgn);如果该树是含n个节点的线性链,则这些操作的最坏情况的运行时间为Θ(n)。我们可以通过随机构造二叉查找树(期望高度:E(h)=O(lgn)),从而使得在这种树上基本动态集操作的平均时间为Θ(lgn)。

基本操作:

查找关键字

最大值&最小值

查找某key的前驱后继

插入

删除

完整代码如下:

#include<iostream>
#include<cstdlib>
using namespace std;

typedef struct BSTNode{
	int key;           //key value
	//int data;          //satellite data
	BSTNode *parent; //parent node
	BSTNode *left;   //left child node
	BSTNode *right;  //right child node
	}BSTNode;

typedef struct BSTree
{
	BSTNode *root;
	}BSTree;

void BST_Insert(BSTree *T,int value)
{
	BSTNode *x=T->root;
	BSTNode *y=NULL;      //y is x's parent node

	BSTNode *z=new BSTNode();//new inserted node
	z->key=value;
	z->parent=NULL;
	z->left=NULL;
	z->right=NULL;

	//locate insert position
	while(x!=NULL)
	{
		y=x;
		if(z->key < x->key)
			x=x->left;
		else
			x=x->right;
 		 }
	//link new node to its parent node
	z->parent = y;

	//link parent node to new node
	if(y==NULL)              //Treee is empty
		T->root=z;
	else if(z->key < y->key)
		y->left = z;
	else
		y->right = z;
	}
void BST_InorderWalk(BSTNode *x)
{
	if(x!=NULL)
	{
		BST_InorderWalk(x->left);
		cout<<x->key<<"   ";
		BST_InorderWalk(x->right);
	 	}
	}
BSTNode *BST_Search(BSTNode *x,int skey)
{
	if(x==NULL || skey==x->key)
		return x;
	if(skey < x->key)
		return BST_Search(x->left,skey);
	else
		return BST_Search(x->right,skey);
	}
BSTNode *BST_Minimum(BSTNode *x)
{
	while(x->left!=NULL)
		x=x->left;
	return x;
	}
BSTNode *BST_Maximum(BSTNode *x)
{
	while(x->right!=NULL)
		x=x->right;
	return x;
	}
BSTNode *BST_Successor(BSTNode *x)
{
	if(x->right!=NULL)
		return BST_Minimum(x->right);
	BSTNode *y=x->parent;
	while(y!=NULL && x==y->right)
	{
		x=y;
		y=y->parent;
		}
	return y;
	}
BSTNode *BST_Predecessor(BSTNode *x)
{
	if(x->left !=NULL)
		return BST_Maximum(x->left);
	BSTNode *y=x->parent;
	while(y!=NULL && x==y->left)
	{
		x=y;
		y=y->parent;
		}
	return y;
	}
void BST_Transplant(BSTree *T,BSTNode *u,BSTNode *v)
{
	if(u->parent==NULL)
		T->root=v;
	else if(u==u->parent->left)
		u->parent->left=v;
	else
		u->parent->right=v;
	if(v!=NULL)
		v->parent=u->parent;
	}
void BST_Delete(BSTree *T,BSTNode *z)
{
	if(z->left==NULL)                 //case 1
		BST_Transplant(T,z,z->right);
	else if(z->right==NULL)           //case 2
		BST_Transplant(T,z,z->left);
 	else                             //case 3
 	{
		BSTNode *y=BST_Minimum(z->right);
		if(y->parent!=z)
		{
			BST_Transplant(T,y,y->right);
			y->right=z->right;
			y->right->parent=y;
			}
		BST_Transplant(T,z,y);
		y->left=z->left;
		y->left->parent=y;
		}
	}
int main()
{
	int A[]={12,5,2,9,18,15,17,19};
	int n=sizeof(A)/sizeof(int);

	cout<<"/*----------------------Create BST-------------------------*/"<<endl;
	BSTree *T=new BSTree();
	T->root =NULL;
	for(int i=0;i<n;i++)      //Create Binary Search Tree
		BST_Insert(T,A[i]);

	cout<<"The Tree is(Inorder-walk-tree):"<<endl;
	BST_InorderWalk(T->root);
	cout<<endl;
	cout<<"/*---------------------------------------------------------*/"<<endl;

	cout<<"/*-----------------------Search BST------------------------*/"<<endl;
	int skey;
	BSTNode *snode=NULL;

	while(1)
	 {
		cout<<"Please input the searching key(-1 denote exiting):";
		cin>>skey;
		if(skey==-1)
	  	{
			cout<<"Exiting..."<<endl;
			break;
			}
		snode=BST_Search(T->root,skey);
		if(snode!=NULL)
			cout<<"The node exists in the tee!"<<endl;
		else
			cout<<"The node doesn't exist."<<endl;
		}
	cout<<"/*----------------------------------------------------------*/"<<endl;

	cout<<"/*-------------------Minimum and Maximum--------------------*/"<<endl;
	BSTNode *minNode=NULL,*maxNode=NULL;
	minNode=BST_Minimum(T->root);
	maxNode=BST_Maximum(T->root);
	cout<<"The Minimum of the BST is:"<<minNode->key<<endl;
	cout<<"The Maximum of the BST is:"<<maxNode->key<<endl;
	cout<<"/*----------------------------------------------------------*/"<<endl;

	cout<<"/*-------------------Successor and Predecessor--------------*/"<<endl;
	cout<<"Please input the node's key:";
	cin>>skey;
	BSTNode *curNode=NULL;
	curNode=BST_Search(T->root,skey);
	if(curNode!=NULL)
	{
		BSTNode *sucNode=NULL,*preNode=NULL;
		sucNode=BST_Successor(curNode);
		preNode=BST_Predecessor(curNode);
		cout<<"The Successor of the current Node "<<curNode->key<<" is:"<< sucNode->key<<endl;
		cout<<"The Predecessor of the current Node "<<curNode->key<<" is:"<< preNode->key<<endl;
		}
	else
		cout<<"The node doen't exist."<<endl;
	cout<<"/*-----------------------------------------------------------*/"<<endl;

	cout<<"/*----------------------Insert-------------------------------*/"<<endl;
	int ikey;
	cout<<"Please input the iserting node's key:";
	cin>>ikey;
	BST_Insert(T,ikey);
	cout<<"After inserting ,the Tree is:"<<endl;
	BST_InorderWalk(T->root);
	cout<<endl;
	cout<<"/*-----------------------------------------------------------*/"<<endl;

	cout<<"/*------------------Deletion---------------------------------*/"<<endl;
	int dkey;
	cout<<"Please input the deleting node's key:";
	cin>>dkey;
	BSTNode *dNode=NULL;
	dNode=BST_Search(T->root,dkey);
	if(dNode==NULL)
		cout<<"The node doesn't exist in the treee."<<endl;
	else
	{
		BST_Delete(T,dNode);
		cout<<"After deleting ,the tree is:"<<endl;
		BST_InorderWalk(T->root);
		cout<<endl;
		}
	cout<<"/*-----------------------------------------------------------*/"<<endl;

	return 0;
	}

运行结果:

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-27 10:07:53

算法导论 第十二章:二叉查找树(Binary Search Trees)的相关文章

算法导论第十二章__二叉搜索数

package I第12章__二叉搜索树; //普通二叉树 public class BinaryTree<T> { // -----------------------数据结构--------------------------------- private int height = 0; private Node<T> rootNode; class Node<T> { T t; int key; Node left; Node right; public Node

算法导论第十二章 二叉搜索树

一.二叉搜索树概览 二叉搜索树(又名二叉查找树.二叉排序树)是一种可提供良好搜寻效率的树形结构,支持动态集合操作,所谓动态集合操作,就是Search.Maximum.Minimum.Insert.Delete等操作,二叉搜索树可以保证这些操作在对数时间内完成.当然,在最坏情况下,即所有节点形成一种链式树结构,则需要O(n)时间.这就说明,针对这些动态集合操作,二叉搜索树还有改进的空间,即确保最坏情况下所有操作在对数时间内完成.这样的改进结构有AVL(Adelson-Velskii-Landis)

算法导论 第二十二章:图的搜索

图有两种标准的表示方法,即邻接矩阵和邻接表(通常邻接矩阵用于稠密图,邻接表用于稀疏图).如下: 对于图的搜索有两种方法:深度优先搜索 & 广度优先搜索. 广度优先搜索(Breadth-first search) 广度优先搜索是将已发现和未发现顶点之间的边界沿其广度方向向外扩展.亦即算法首先会发现和s距离为k的所有点,然后才会发现和s距离为k+1的其他顶点. 伪代码: EG: 运行时间:O(V+E). 深度优先遍历(Depth-first search) 在深度优先搜索中,对于最新发现的顶点,如果

算法导论 第二十二章:拓扑排序

拓扑排序(针对有向无回路图DAG)是深度优先搜索的一个应用,其结果图中所有顶点的一个线性排列. 伪代码如下: EG: 拓扑排序完整代码如下: #include<iostream> #include<iomanip> #include<string> #include<algorithm> using namespace std; #define UDG 0 #define DG 1 #define WHITE 0 #define GRAY 1 #define

算法导论第十五章动态规划

概述: 1.动态规划是通过组合子问题的解而解决原问题的. 2.动态规划适用于子问题不是独立的情况,也就是各子问题的包含公共的子子问题. 3.动态规划对每个子问题只求解一次,将其结果保存在一张表中. 4.动态规划的设计步骤:a.描述最优解的结构b.递归定义最优解的值c.按自底向上的方式计算最优觖的值d.由计算出的结构构造一个最优解 15.1钢条切割 钢条切割问题:给定定长的钢条和价格表,求切割方案,使得收益最大.如果n英寸的钢条的价格足够大,则不需要切割. 代码如下: //朴素递归求解钢条切割收益

【LeetCode-面试算法经典-Java实现】【096-Unique Binary Search Trees(唯一二叉搜索树)】

[096-Unique Binary Search Trees(唯一二叉搜索树)] [LeetCode-面试算法经典-Java实现][所有题目目录索引] 原题 Given n, how many structurally unique BST's (binary search trees) that store values 1-n? For example, Given n = 3, there are a total of 5 unique BST's. 1 3 3 2 1 \ / / /

Go语言实现二叉查找树(Binary Search Trees)

官网有一个二叉排序树的例子,在此基础上增加了查找和删除节点功能. 代码: package main //Binary Search Trees //author: Xiong Chuan Liang //date: 2015-2-1 import ( "fmt" "math/rand" ) func main() { t := New(10, 1) if Search(t, 6) { fmt.Println("Search(6) true") }

算法导论第十九章 斐波那契堆

<算法导论>第二版中在讨论斐波那契堆之前还讨论了二项堆,但是第三版中已经把这块的内容放到思考题中,究极原因我想大概是二项堆只是个引子,目的是为了引出斐波那契堆,便于理解,而且许多经典的算法实现都是基于斐波那契堆,譬如计算最小生成树问题和寻找单源最短路径问题等,此时再把二项堆单独作为一章来讲显然没有必要.类似的堆结构还有很多,如左倾堆,斜堆,二项堆等,下次我打算开一篇博客来记录下它们的异同点. 一.摊还分析(第十七章) 这些高级的数据结构的性能分析一般是基于一个技术——摊还分析,可以理解成一种时

算法导论 第十六章:贪心算法之单任务调度问题

贪心算法是使所做的选择看起来都是当前最优的,通过所做的局部最优选择来产生一个全局最优解. 其具有的性质如下: 1)贪心选择性质:一个全局最优解可以通过局部最优(贪心)选择来达到.即,在考虑如何做选择时,我们只考虑对当前问题最佳的选择而不考虑子问题的结果. 这一点是贪心算法不同于动态规划之处:在动态规划中,每一步都要做出选择,但是这些选择依赖于子问题的解.因此,解动态规划问题一般是自底向上,从小问题处理至大问题.在贪心算法中,我们所做的总是当前看似最优的选择,然后再解决选择之后所出现的子问题.贪心