平衡二叉树AVL的基本操作之删除

        接文章《平衡二叉树的基本操作之插入》,这里给出删除操作的一种是实现。这里借用文章《平衡二叉树(AVL)的插入和删除详解(上)》中的删除思路:

      删除的结点不一定是叶子结点,可能是树中的任何一个结点。在二叉查找树中,我们知道删除的结点可能有三种情况:(1)为叶子结点,(2)左子树或右子树有一个为空,(3)左右子树都不空。对第三种情况的处理有三种处理方式,这里采用删除前驱的方式。注意到我们仍然采用的是递归删除,然后判断删除后树是否“变矮”了,然后进行相应的处理。对(1)(2)中情况,很好处理,树的确是“变矮”了。对于第(3)种情况,我们不能直接找到前驱结点,然后把数据拷贝到原本要删除的根结点,最后直接删除前驱结点。因为这么做,我们无法判断原先根结点子树高度的变化情况。所以我们在找到前驱结点后,不是直接删除,而是采用在根结点左子树中递归删除前驱的方式。同样利用文章《平衡二叉树的基本操作之插入》的左旋和右旋函数实现:

bool AVLDelete(AVLTree *root,int x,bool *unbalanced)
{
	if(*root == NULL){
		return false;
	}
	else if (x == (*root)->data) {
		if ((*root)->lchild == NULL) {
			AVLTree t = *root;
			*root = (*root)->rchild;
			delete t;
			*unbalanced = true;
		}
		else if ((*root)->rchild == NULL) {
			AVLTree t = *root;
			*root = (*root)->lchild;
			delete t;
			*unbalanced = true;
		}
		else {
			AVLTree t = (*root)->lchild;
			while (t->rchild){
				t = t->rchild;
			}
			(*root)->data = t->data;
			AVLDelete(&((*root)->lchild),t->data,unbalanced);
		}
	}
	else if (x < (*root)->data) {
		if(!AVLDelete(&((*root)->lchild),x,unbalanced)){
			return false;
		}
		if (*unbalanced) {
			switch ((*root)->bf) {
				case 1:		(*root)->bf = 0;
							*unbalanced = true;
							break;
				case 0:		(*root)->bf = -1;
							*unbalanced = false;
							break;
				case -1:	rightRotate(root,unbalanced);
				 
			}
		}
	}
	else {
		if(!AVLDelete(&((*root)->rchild),x,unbalanced)) {
			return false;
		}
		if (*unbalanced) {
			switch ((*root)->bf) {
				case -1:	(*root)->bf = 0;
							*unbalanced = true;
							break;
				case 0:		(*root)->bf = 1;
							*unbalanced = false;
							break;
				case 1:		leftRotate(root,unbalanced);
			}
		}
	}
	return true;
}

测试程序:

int main()
{
	
	
	AVLTree T = NULL;
	bool unbalanced = false;
	for(int i = 0; i < 10; i++) {
		AVLInsert(&T,i,&unbalanced);
		AVLTreeDisplay(T);
		cout<<"---------------------cut---------------------"<<endl;
	}

	int a[] = {7,5,4,3,8,9,2,1,6,0};
	for(int i = 0; i < 10; i++){
		unbalanced = false; 
		AVLDelete(&T,a[i],&unbalanced);
		AVLTreeDisplay(T);
		cout<<"---------------------cut---------------------"<<endl;
	}
	//AVLTreeDisplay(T);
	return 0;
}

测试结果:

 0
---------------------cut---------------------
   0  
     \
     1
---------------------cut---------------------
   1  
 /   \
 0   2
---------------------cut---------------------
       1      
     /   \    
   0       2  
             \
             3
---------------------cut---------------------
       1      
     /   \    
   0       3  
         /   \
         2   4
---------------------cut---------------------
       3      
     /   \    
   1       4  
 /   \       \
 0   2       5
---------------------cut---------------------
       3      
     /   \    
   1       5  
 /   \   /   \
 0   2   4   6
---------------------cut---------------------
               3              
             /   \            
       1               5      
     /   \           /   \    
   0       2       4       6  
                             \
                             7
---------------------cut---------------------
               3              
             /   \            
       1               5      
     /   \           /   \    
   0       2       4       7  
                         /   \
                         6   8
---------------------cut---------------------
               3              
             /   \            
       1               7      
     /   \           /   \    
   0       2       5       8  
                 /   \       \
                 4   6       9
---------------------cut---------------------
               3              
             /   \            
       1               6      
     /   \           /   \    
   0       2       5       8  
                 /           \
                 4           9
---------------------cut---------------------
               3              
             /   \            
       1               6      
     /   \           /   \    
   0       2       4       8  
                             \
                             9
---------------------cut---------------------
       3      
     /   \    
   1       8  
 /   \   /   \
 0   2   6   9
---------------------cut---------------------
       2      
     /   \    
   1       8  
 /       /   \
 0       6   9
---------------------cut---------------------
       2      
     /   \    
   1       6  
 /           \
 0           9
---------------------cut---------------------
       2      
     /   \    
   1       6  
 /            
 0            
---------------------cut---------------------
   1  
 /   \
 0   6
---------------------cut---------------------
   0  
     \
     6
---------------------cut---------------------
 0
---------------------cut---------------------
---------------------cut---------------------

REF:

1,数据结构(C语言版) Ellis Horowitz

2,http://blog.csdn.net/sysu_arui/article/details/7897017

    原文作者:平衡二叉树
    原文地址: https://blog.csdn.net/flyapy/article/details/37536261
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞