码迷,mamicode.com
首页 > 其他好文 > 详细

二叉搜索树

时间:2015-05-03 13:24:37      阅读:156      评论:0      收藏:0      [点我收藏+]

标签:

  一、概述    

       二叉排序树的查找过程和次优二叉树类似,通常采取二叉链表作为二叉排序树的存储结构。中序遍历二叉排序树可得到一个关键字的有序序列,一个无序序列可以通过构造一棵二叉排序树变成一个有序序列,构造树的过程即为对无序序列进行排序的过程。每次插入的新的结点都是二叉排序树上新的叶子结点,在进行插入操作时,不必移动其它结点,只需改动某个结点的指针,由空变为非空即可。搜索,插入,删除的复杂度等于树高,O(log(n)).

二、二叉搜索树的结构

二叉搜索树,对于任何节点x,左子树的关键字最大不超过x的关键子,右子树的关键子最小不低于x的关键字,如下图。直观的看,就是左大右小的一个递归结构。递归结构不怎么符合我们人的正常性的思维,需要仔细理解。

技术分享

技术分享

二叉搜索书的c++结构定义:

struct treeNode
{
	treeNode* left;
	treeNode*right;

	treeNode*p;
	int value;
    void*pData;
};


struct Tree
{
	treeNode *root;
	//int nsize;
};

三、算法

       在二叉搜索树结构定义的基础上,主要有以下的一些算法

(1)插入

         就是能在二叉树正确位置上插入节点,首先需要定位要插入的位置,然后进行插入即可。

void treeInsert(Tree &tree, treeNode*p)
{

	treeNode*pTemp=tree.root;//用于遍历

	treeNode *y=NULL;// 用于保存遍历的正确结果

	//进行二叉遍历
	while(pTemp!=NULL)
	{
		y=pTemp;   //保存结果

		if(pTemp->value<p->value)
			pTemp=pTemp->right;
		else
			pTemp=pTemp->left;


	}

	p->p=y; //设置好插入节点的父节点

	if(y==NULL) //如果遍历的结果为空,说明该棵树为空树,
		tree.root=p;

	else if(y->value>p->value)//插入正确的节点
		y->left=p;
	else
		y->right=p;



	
}

(2)删除

         删除一个二叉搜索树的节点z,稍微复杂一些。在z为根的子树中,找到z的后继,并形成一颗正确的二叉搜索的子树,加入到z之前的父节点中即可。

主要分为以下四种情况:

a、节点z的左子树为空

b、节点z的右子树为空

c、节点z的右节点是z的后继

d、节点z的右节点不是z的后继

void transPlant(Tree &tree,treeNode*u,treeNode*v)//将以v根的子树,替换以u为根的子树
{

	if (u->p==NULL)
		tree.root=v;
	else if(u==u->p->left)
		u->p->left=v;
	else
		u->p->right=v;

	if(v!=NULL)
		v->p=u->p;
}

void treeDelete(Tree &tree,treeNode*z)
{
	if(z->left==NULL)//情况1
		transPlant(tree,z,z->right);
	else if(z->right==NULL)//情况2
		transPlant(tree,z,z->left);
	else
	{
		treeNode*p=NULL;
		treeNode*pTemp=z->right;

		while(pTemp!=NULL)
		{
			p=pTemp;
			pTemp=pTemp->left;
		}

		if(p==z->right)//情况3
		{
			transPlant(tree,z,z->right);

			p->left=z->left;

			p->left->p=p;



		}
		else//情况4
		{

		transPlant(tree,p,p->right);

		p->right=z->right;

		p->right->p=p;

		transPlant(tree,z,p);

		p->left=z->left;

		p->left->p=p;


		}
	}


(3)遍历

遍历就是遍历一下二叉搜索树的结构。

void treeWalk(treeNode *p)
{

	if(p!=NULL)
	{

		treeWalk(p->left);

		std::cout<<p->value;

		treeWalk(p->right);
	}
}

(4)查询

在二叉搜索树结构的基础上,查询二叉树的某个节点。

treeNode * treeSearch(treeNode*p,int k)
{
	if(p==NULL || p->value==k)
		return p;

	if(k<p->value)
		return treeSearch(p->left,k);
	else
		return treeSearch(p->right,k);
}

(5)创建节点

treeNode *createNode(int k)
{
	treeNode *p=new treeNode();

	p->value=k;
	p->p=NULL;
	p->left=NULL;
	p->right=NULL;
	p->pData=NULL;

	return p;
}

四、测试示例

int _tmain(int argc, _TCHAR* argv[])
{

	Tree tree;
	tree.root=NULL;

	treeInsert(tree,createNode(10));
	treeInsert(tree,createNode(11));
	treeInsert(tree,createNode(12));
		treeInsert(tree,createNode(8));
		treeInsert(tree,createNode(22));
		treeInsert(tree,createNode(3));

		treeDelete(tree,treeSearch(tree.root,8));


		treeDelete(tree,treeSearch(tree.root,3));

		treeWalk(tree.root);

		int j;
		std::cin>>j;

	return 0;
}





二叉搜索树

标签:

原文地址:http://blog.csdn.net/kupepoem/article/details/45457877

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!