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

二叉搜索树

时间:2015-01-14 15:41:08      阅读:206      评论:0      收藏:0      [点我收藏+]

标签:二叉树   算法导论   

二叉搜索树是红黑树的基础。

关于红黑树的链接:

http://blog.csdn.net/v_JULY_v/article/details/6105630

linux kernel 源码中关于红黑树的链接:
https://github.com/torvalds/linux/blob/master/lib/rbtree.c
https://github.com/torvalds/linux/blob/master/include/linux/rbtree_augmented.h
https://github.com/torvalds/linux/blob/master/include/linux/rbtree.h


源码:

//BinaryTree.h

<span style="font-size:18px;">#ifndef BINARY_TREE_H
#define BINARY_TREE_H
#include "common.h"

typedef struct BinSrchNode{
	struct BinSrchNode* left,*right,*p;
	int key;
}BSNODE,*BSTREE;


#endif

</span>


<span style="font-size:18px;">BSNODE* TreeInsert(BSNODE* root,BSNODE* node);
BSNODE* NewNode(BSNODE* node);
BSNODE* IterativeTreeSearch(BSNODE* x,int k);
BSNODE* TreeMaxmum(BSNODE* x);
BSNODE* TreeMinmum(BSNODE* x);
BSNODE* TreeSuccesor(BSNODE* x);
BSNODE* TreeDelete(BSNODE* root,BSNODE* toDel);
void SearchTree();

void SearchTree()
{
	int i,j;
	BSNODE* Root=NULL;
	BSNODE node;
	BSNODE* tmp;
	int toBeInsert[] = {5,2,8,4,1,6,9,15,12,13,11,16,14,10};
	node.key = 10;
	Root = TreeInsert(Root,&node);
					//         10
					//       /	  					//   /           					//   5           15
					// /  \         /  					//2    8       12  16
				//   /    /  \    / \  
				//  1    6    9  11  13
				//               /	  	            //              10    14
	for(i=0; i<sizeof(toBeInsert)/sizeof(int*); i++)
	{
		BSNODE node;
		node.key = toBeInsert[i];
		Root = TreeInsert(Root,&node);
	}
	for(i=0; i<17; i++)
	{
		tmp = IterativeTreeSearch(Root,i);
		if(tmp)
		{
			printf("\n%d ",tmp->key);//&& tmp->key != 5
			if (tmp->key == 12)
			{
				i = i;
			}
			Root = TreeDelete(Root,tmp);
			printf("=---=");
			for(j=0; j<20; j++)
			{
				tmp = IterativeTreeSearch(Root,j);
				if(tmp)
				{
					printf("%d ",tmp->key);
				}
			}
		}
	}
	
}

BSNODE* TreeInsert(BSNODE* root,BSNODE* node)
{
	BSNODE *predecesor = NULL,*tmp = root;
	//while循环用来寻找新节点的插入位置,小于向左大于向右走
	//循环停止条件:直到到达树叶位置。
	//predecesor保存了树叶的地址,也是循环过程中循环变量tmp的前任。
	while(tmp != NULL)
	{
		predecesor = tmp;
		if(node->key < tmp->key)
		{
			tmp = tmp->left;
		}
		else 
		{
			tmp = tmp->right;
		}
	}
	node->p = predecesor;
	tmp = NewNode(node);
	if(predecesor == NULL)		//如果是空树
	{
		return tmp;
	}

	else if(node->key < predecesor->key)
	{
		predecesor->left = tmp;
	}
	else
	{
		predecesor->right = tmp;
	}
	return root;
}
BSNODE* NewNode(BSNODE* node)
{
	BSNODE* pNode = (BSNODE*)malloc(sizeof(BSNODE));
	pNode->key = node->key;
	pNode->p = node->p;
	pNode->left = NULL;
	pNode->right = NULL;

	return pNode;
}


BSNODE* IterativeTreeSearch(BSNODE* x,int k)
{
	while(x != NULL && x->key != k)
	{
		if(k < x->key)
		{
			x = x->left;
		}
		else
		{
			x = x->right;
		}
	}
	return x;
}

BSNODE* TreeMinmum(BSNODE* x)
{
	while(x->left != NULL)
	{
		x = x->left;
	}
	return x;
}
BSNODE* TreeMaxmum(BSNODE* x)
{
	while(x->right != NULL)
	{
		x = x->right;
	}
	return x;
}

BSNODE* TreeSuccesor(BSNODE* x)
{
	BSNODE* p;
	if(x->right != NULL)//如果当前结点有右孩子那么他的后继定在其右孩子中
	{
		return TreeMinmum(x);
	}
	//如果没有右孩子,则其后继在下一个被中序遍历的结点上。
	//while循环用来寻找下一个被遍历的结点。
	//循环条件:没有到达根节点或子是父的右孩子。
	//循环截止条件为到达根节点或者到了子树是父结点的左分支结点
	p = x->p;
	while(p != NULL && x == p->right)
	{
		x = p;
		p = p->p;
	}
	return p;
}
static BSNODE* Transplant(BSNODE* root, BSNODE* oldNode,BSNODE* newNode)
{
	if(oldNode->p == NULL)//如果被替换结点是根节点
	{
		root = newNode;
	}
	else if(oldNode == oldNode->p->left)//如果被替换结点是其父结点的左分支
	{
		oldNode->p->left = newNode;
	}
	else
	{
		oldNode->p->right = newNode;
	}
	if(newNode != NULL)
	{
		newNode->p = oldNode->p;
	}
	
	return root;
}

BSNODE* TreeDelete(BSNODE* root,BSNODE* toDel)
{
	BSNODE* successor;
	if(toDel->left == NULL)			//如果被删除结点的左孩子是空,则用其右孩子将其替换掉
	{
		root = Transplant(root,toDel,toDel->right);
	}
	else if (toDel->right == NULL)	//反之
	{
		root = Transplant(root,toDel,toDel->left);
	}												//后继的位置可以直接由其右孩子继承,
	else							//否则比较复杂了,后继用来替换被删结点,因为后继的左孩子为空,
	{
		successor = TreeMinmum(toDel->right);	//右子树结点中最小的子孙结点是其后继。
		if (successor != NULL && successor->p != toDel)				
		{										//后继右旋操作。右旋可以将
			root = Transplant(root,successor,successor->right);		//
			successor->right = toDel->right;
			successor->right->p = successor;
		}
		root = Transplant(root,toDel,successor);//用后继替换被删结点
		successor->left = toDel->left;			
		successor->left->p = successor;
	}
	return root;
}



</span>







二叉搜索树

标签:二叉树   算法导论   

原文地址:http://blog.csdn.net/kee131/article/details/42709233

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