二叉查找树的基本操作之查找插入删除

        二叉查找树(BinarySearch Tree,也叫二叉搜索树,或称二叉排序树Binary Sort Tree)或者是一棵空树,或者是具有下列性质的二叉树:

1,若它的左子树不为空,则左子树上所有结点的值均小于它的根结点的值;

2,若它的右子树不为空,则右子树上所有结点的值均大于它的根结点的值;

3,它的左、右子树也分别为二叉查找树。

类型定义:

typedef struct BinTreeNode * BinTree;
typedef struct BinTreeNode
{
	int data;
	BinTree lchild,rchild;
} BinTreeNode;

查找:

BinTree searchTree(BinTree T,int key)
{
	while(T){
		if (key == T->data) return T;
		if (key < T->data)
			T = T->lchild;
		else
			T = T->rchild;
	}
	return NULL;
}
插入:

a,若二叉查找树的根结点为NULL,直接使新节点成为根结点;

b,查找到有插入位置的结点(如果关键子已存在返回NULL并且退出);

c,若新结点的关键字小于插入点的关键字,使新节点称为插入点的左儿子结点,否则使之称为插入点的右儿子结点。

void insertBinTreeNode(BinTree *T,int data)
{
	BinTree ptr = new BinTreeNode;
	ptr->data = data;
	ptr->lchild = ptr->rchild = NULL;
	
	if(*T == NULL)
		*T = ptr;
	else{
		BinTree t,s;
		s = *T;
		while(s){
			t = s;
			if (data == s->data){
				delete ptr;
				return;
			}
			else if (data < s->data)
					s = s->lchild;
			else 
				s = s->rchild;
		}
		if (data < t->data)
			t->lchild = ptr;
		else
			t->rchild = ptr;
	}
}

删除:

a,若删除的结点是叶子结点,直接删除结点。

b,若删除的结点只有左儿子或者右儿子,删除目标结点后用唯一的子结点代替原来的位置。

c,删除的结点有两个儿子结点时,首先用其左子树中的最大元素或者右子树中的最小元素代替该结点。然后将替代结点从其子树中删除。

void deleteBinTreeNode(BinTree *T,int key)
{
	BinTree s = *T,t,p;
	
	if (s == NULL)
		return;
	
	if (s->data == key){
		/* leaf node */
		if ( s->lchild == NULL && s->rchild == NULL) {
			*T = NULL;
			delete s;
		}
		/* lchild only */
		else if (s->rchild == NULL) {
			*T = s->lchild;
			delete s;
		}
		/* rchild only */
		else if (s->lchild == NULL) {
			*T = s->rchild;
			delete s;
		}
		/* both lchild and rchild */
		else{
			/* locate the min val in the right sub tree */
			t = s->rchild;
			if(t->lchild == NULL){
				s->rchild = t->rchild;
				/* copy data of t into s :(*T) */
				s->data = t->data; 
				delete t;
			}
			else{
				while (t->lchild){
					/* p : parent of t */
					p = t;
					t = t->lchild;
				}
				s->data = t->data;
				p->lchild = t->rchild;
				delete t;
			}
			//if(t->lchild == NULL)
			//	t->lchild = s->lchild;
			//else{
			//	while(t->lchild){
			//		/* p : parent */
			//		p = t;
			//		t = t->lchild;
			//	}
			//	
			//	p->lchild = t->rchild;
			//	t->lchild = s->lchild;
			//	t->rchild = s->rchild;	
			//}
			//*T = t;
			//delete s;
		}
	}
	else if (key < s->data) {
		deleteBinTreeNode(&(s->lchild),key);
	}
	else if (key > s->data) {
		deleteBinTreeNode(&(s->rchild),key);
	}
	
}


测试结果

插入 5 4 3

       5      
     /        
   4          
 /            
 3            
插入 7 6

       5      
     /   \    
   4       7  
 /       /    
 3       6    
删除 8 7

       5      
     /   \    
   4       6  
 /            
 3            
插入 9 8

               5              
             /   \            
       4               6      
     /                   \    
   3                       9  
                         /    
                         8    
删除 6  插入10

       5      
     /   \    
   4       9  
 /       /   \
 3       8  10
删除 9  插入7

               5              
             /   \            
       4              10      
     /               /        
   3               8          
                 /            
                 7            

删除 5

       7      
     /   \    
   4      10  
 /       /    
 3       8    

REF:

1,http://blog.csdn.net/npy_lp/article/details/7426431

2,数据结构(C语言版)Ellis Horowitz , Sartaj Sahni , Susan Anderson-Freed






  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值