Beispiel #1
0
avltree insert(int data, avltree T){
	if(!T){
		T=(avltree)malloc(sizeof(struct avltreeNode));
		T->data=data;
		T->height=0;
		T->left=T->right=NULL;
	//	printf("%d\n",T->data);
	}
	
	else if(data < T->data){
		T->left=insert(data,T->left);
		if(GetHeight(T->left)-GetHeight(T->right)==2)
			if(data < T->left->data)
				T=SingleLeftRotation(T);
			else
				T=DoubleLeftRightRotation(T);
	//	printf("%d\n",T->data);
	}
	else if(data > T->data){
		T->right=insert(data,T->right);
		if(GetHeight(T->left)-GetHeight(T->right)==-2)
			if(data > T->right->data)
				T=SingleRightRotation(T);
			else
				T=DoubleRightLeftRotation(T);
	//	printf("%d\n",T->data);
	}

	T->height=Max(GetHeight(T->left),GetHeight(T->right))+1;
//	printf("height:%d\n",T->height);
	return T;
}
Beispiel #2
0
AVLTree AVL_Insertion(ElementType x, AVLTree T)
{
	if(!T)
	{
		T = (AVLTree)malloc(sizeof(AVLTreeNode));
		T->Data = x;
		T->Height = 0;
		T->Left = T->Right = NULL;
	}
	else if(x < T->Data)
	{
		T->Left = AVL_Insertion(x, T->Left);
		if(GetHeight(T->Left) - GetHeight(T->Right) == 2)
		{
			if(x < T->Left->Data)
				T = SingleLeftRotation(T);
			else
				T = DoubleLeftRightRotation(T);
		}
	}
	else if(x > T->Data)
	{
		T->Right = AVL_Insertion(x, T->Right);
		if(GetHeight(T->Right) - GetHeight(T->Left) == 2)
		{
			if(x > T->Right->Data)
				T = SingRightRotation(T);
			else
				T = DoubleRightLeftRotation(T);
		}
	}
	T->Height = Max(GetHeight(T->Left), GetHeight(T->Right)) + 1;
	return T;
}
Beispiel #3
0
/*******************************************************************************
  Função que faz o reequilíbrio do nó pretendido da AVL.
  
  Function that balances the tree if necessary in each node that does not respect
  the equilibrium rule, after insertion and deletion operations.
*******************************************************************************/
static void Balance (PtAVLNode *proot)
{
	unsigned int LeftH, RightH;

	if (*proot == NULL) return;	/* subárvore vazia - empty tree */
	LeftH = AVLHeight ((*proot)->PtLeft);	/* altura subárvore esquerda - left subtree height */
	RightH = AVLHeight ((*proot)->PtRight);	/* altura subárvore direita - right subtree height */

	if (LeftH - RightH == 2)	/* subárvore esquerda desequilibrada? - left subtree unbalanced? */
	{
		LeftH = AVLHeight ((*proot)->PtLeft->PtLeft);
		RightH = AVLHeight ((*proot)->PtLeft->PtRight);
		if (LeftH >= RightH) SingleRightRotation (proot);
		else DoubleLeftRightRotation (proot);
	}
	else	if (RightH - LeftH == 2)	/* subárvore direita desequilibrada? - right subtree unbalanced? */
			{
				RightH = AVLHeight ((*proot)->PtRight->PtRight);
				LeftH = AVLHeight ((*proot)->PtRight->PtLeft);
				if (RightH >= LeftH) SingleLeftRotation (proot);
				else DoubleRightLeftRotation (proot);
			}
			else (*proot)->Height = LeftH > RightH ? LeftH + 1 : RightH + 1;
				/* atualizar a altura do nó - updationg the node height */
}
 AVLTree DoubleLeftRightRotation ( AVLTree A )
 { /* 注意:A必须有一个左子结点B,且B必须有一个右子结点C */
   /* 将A、B与C做两次单旋,返回新的根结点C */
      
     /* 将B与C做右单旋,C被返回 */
     A->Left = SingleRightRotation(A->Left);
     /* 将A与C做左单旋,C被返回 */
     return SingleLeftRotation(A);
 }
Beispiel #5
0
AVLTree DoubleLeftRightRotation(AVLTree A)
{
	A->Left = SingRightRotation(A->Left);
	return SingleLeftRotation(A);	
	// AVLTree B = A->Left;
	// AVLTree C = B->Right;
	// A->Left = C->Right;
	// B->Right = C->Left;
	// C->Left = B;
	// C->Right = A;
	// A->Height = Max(GetHeight(A->Left), GetHeight(A->Right)) + 1;
	// B->Height = Max(GetHeight(B->Left), GetHeight(B->Right)) + 1;
	// C->Height = Max(GetHeight(C->Left), GetHeight(C->Right)) + 1;
}
 AVLTree Insert( AVLTree T, ElementType X )
 { /* 将X插入AVL树T中,并且返回调整后的AVL树 */
     if ( !T ) { /* 若插入空树,则新建包含一个结点的树 */
         T = (AVLTree)malloc(sizeof(struct AVLNode));
         T->Data = X;
         T->Height = 0;
         T->Left = T->Right = NULL;
     } /* if (插入空树) 结束 */
  
     else if ( X < T->Data ) {
         /* 插入T的左子树 */
         T->Left = Insert( T->Left, X);
         /* 如果需要左旋 */
         if ( GetHeight(T->Left)-GetHeight(T->Right) == 2 )
             if ( X < T->Left->Data ) 
                T = SingleLeftRotation(T);      /* 左单旋 */
             else 
                T = DoubleLeftRightRotation(T); /* 左-右双旋 */
     } /* else if (插入左子树) 结束 */
      
     else if ( X > T->Data ) {
         /* 插入T的右子树 */
         T->Right = Insert( T->Right, X );
         /* 如果需要右旋 */
         if ( GetHeight(T->Left)-GetHeight(T->Right) == -2 )
             if ( X > T->Right->Data ) 
                T = SingleRightRotation(T);     /* 右单旋 */
             else 
                T = DoubleRightLeftRotation(T); /* 右-左双旋 */
     } /* else if (插入右子树) 结束 */
  
     /* else X == T->Data,无须插入 */
  
     /* 别忘了更新树高 */
     T->Height = Max( GetHeight(T->Left), GetHeight(T->Right) ) + 1;
      
     return T;
 }
Beispiel #7
0
void CObAvlTree::DoubleRightRotation( CNode* pNode )
{
	SingleLeftRotation(pNode->pLChild);
	SingleRightRotation(pNode);
}
Beispiel #8
0
void CObAvlTree::RemoveAt(POSITION position)
{
	//avl tree removing. 
	//For a node having children, the concept model is to find the inorder successor of the removing node,
	//copy the data of IOS to the removing node, then remove the IOS rather than the removing node.
	//the rotation balance begins from the parent of the IOS and traces back to its ancestors.
	//however, the implementation removes the true removing node so that the iterator won't point to a garbage node.

	ASSERT_VALID(this);

	CNode* pOldNode = (CNode*) position;
	ASSERT(AfxIsValidAddress(pOldNode, sizeof(CNode)));

	//block 1. regular binary tree remove, except makeing pRotateNode point to the start tracing node for rotation,
	//and the bubble node's height is replaced the height of the removed node
	
	//case 1. single child, just bubble the child the the parent place
	//case 2. double children, bubble the in order successor to the parent place.
	CNode* pBubbleNode = NULL;
	CNode* pRotateNode = NULL;
	if( pOldNode->pLChild==NULL ){
		pBubbleNode = pOldNode->pRChild;
		pRotateNode = pOldNode->pParent;
	}else if( pOldNode->pRChild==NULL ){
		pBubbleNode = pOldNode->pLChild;
		pRotateNode = pOldNode->pParent;
	}else{
		//case 2
		pBubbleNode = pOldNode->pRChild;
		while( pBubbleNode->pLChild )pBubbleNode = pBubbleNode->pLChild;
		//now pBubbleNode is the IOS, but if bubble node is the right child of the removing node,
		//do not change the right child of the bubble node
		if( pBubbleNode->pParent!=pOldNode ){ //the bubble node is more than one height below the removing node
			pBubbleNode->pParent->pLChild = pBubbleNode->pRChild;
			if( pBubbleNode->pRChild )pBubbleNode->pRChild->pParent=pBubbleNode->pParent;
			//save the rotation place.
			pRotateNode = pBubbleNode->pParent;
			//link the right child of the removing node to bubble node
			pBubbleNode->pRChild = pOldNode->pRChild;
			pOldNode->pRChild->pParent = pBubbleNode;
		}else{
			pRotateNode = pBubbleNode;
		}
		//link the left child of the removing node to the bubble node
		pBubbleNode->pLChild = pOldNode->pLChild;
		pOldNode->pLChild->pParent = pBubbleNode;

		//replace the height of the bubble node by the removed node
		ASSERT(AfxIsValidAddress(pBubbleNode, sizeof(CNode)));
		pBubbleNode->nHeight = pOldNode->nHeight;
	}
	CNode** ppNode=NULL;
	if( pOldNode==m_pNodeRoot )ppNode = &m_pNodeRoot;
	else if( pOldNode->pParent->pLChild==pOldNode )ppNode=&pOldNode->pParent->pLChild;
	else ppNode=&pOldNode->pParent->pRChild;

	*ppNode = pBubbleNode;
	if( pBubbleNode )pBubbleNode->pParent = pOldNode->pParent;

	FreeNode(pOldNode);
	
	//block 2, avl tree balance rotation
	//the loop goes upward to find the rotation node until the root node is reached or the current subtree's height is not changed.
	//if a rotation is done, LOOP CONTINUE beause the height of the subtree at the rotation node may decrease,
	//so the ancestors may need rotation.
	//if the rotation is not done for the node, then adjust the height of the current node.
	while( pRotateNode ){
		int nOldHeight = NODEHEIGHT(pRotateNode);
		if( NODEHEIGHT(pRotateNode->pLChild)-NODEHEIGHT(pRotateNode->pRChild)==2 ){
			//left subtree is too high, rotate to right
			CNode* pChildNode = pRotateNode->pLChild;
			ASSERT( pChildNode!=NULL );
			if( NODEHEIGHT(pChildNode->pLChild)>=NODEHEIGHT(pChildNode->pRChild) ){
				SingleRightRotation( pRotateNode );
			}else{
				ASSERT( NODEHEIGHT(pChildNode->pLChild)<NODEHEIGHT(pChildNode->pRChild) );
				DoubleRightRotation( pRotateNode );
			}
			//after the rotation, the pRotateNode becomes a child of the node at the rotation point
			pRotateNode = pRotateNode->pParent;
		}else if( NODEHEIGHT(pRotateNode->pRChild)-NODEHEIGHT(pRotateNode->pLChild)==2 ){
			//right subtree is too high, rotate to left
			CNode* pChildNode = pRotateNode->pRChild;
			ASSERT( pChildNode!=NULL );
			if( NODEHEIGHT(pChildNode->pLChild)<=NODEHEIGHT(pChildNode->pRChild) ){
				SingleLeftRotation( pRotateNode );
			}else{
				ASSERT( NODEHEIGHT(pChildNode->pLChild)>NODEHEIGHT(pChildNode->pRChild) );
				DoubleLeftRotation( pRotateNode );
			}
			//after the rotation, the pRotateNode becomes a child of the node at the rotation point
			pRotateNode = pRotateNode->pParent;
		}else{
			//no rotation happend here, adjust the height
			CalcHeight( pRotateNode );
		}

		if( nOldHeight==NODEHEIGHT(pRotateNode) ){
			//since the subtree's height is not changed, STOP LOOP since the ancestors' height is maintained.
			break;
		}
		pRotateNode = pRotateNode->pParent;
	}
}
Beispiel #9
0
POSITION CObAvlTree::Insert(CObject* newElement)
{
	ASSERT_VALID(this);

	//block 1, regular binary insertion
	CNode* pParent = m_pNodeRoot;
	CNode** ppNode = &m_pNodeRoot;

	while( *ppNode ){
		pParent = *ppNode;
		int nRet = CompareNode( (LPVOID)&newElement, (LPVOID)&pParent->data );
		if( nRet<=0 ){
			ppNode = &pParent->pLChild;
		}else if( nRet>0 ){
			ppNode = &pParent->pRChild;
		}
	}

	CNode* pNewNode = NewNode(pParent, NULL, NULL);
	pNewNode->data = newElement;
	*ppNode = pNewNode;
	
	//block 2, avl tree balance rotation
	//the loop goes upward to find the rotation node, 
	//whenever a rotation is done, STOP LOOP beause the ancestors' height are the same after rotation.
	//if the rotation is not yet found, then adjust the height of the current node.
	CNode* pRotateNode = pParent;
	while( pRotateNode ){
		if( NODEHEIGHT(pRotateNode->pLChild)-NODEHEIGHT(pRotateNode->pRChild)==2 ){
			//left subtree is too high, rotate to right
			CNode* pChildNode = pRotateNode->pLChild;
			ASSERT( pChildNode!=NULL );
			if( NODEHEIGHT(pChildNode->pLChild)>NODEHEIGHT(pChildNode->pRChild) ){
				SingleRightRotation( pRotateNode );
			}else{
				ASSERT( NODEHEIGHT(pChildNode->pLChild)<NODEHEIGHT(pChildNode->pRChild) );
				DoubleRightRotation( pRotateNode );
			}
			break;
		}else if( NODEHEIGHT(pRotateNode->pRChild)-NODEHEIGHT(pRotateNode->pLChild)==2 ){
			//right subtree is too high, rotate to left
			CNode* pChildNode = pRotateNode->pRChild;
			ASSERT( pChildNode!=NULL );
			if( NODEHEIGHT(pChildNode->pLChild)<NODEHEIGHT(pChildNode->pRChild) ){
				SingleLeftRotation( pRotateNode );
			}else{
				ASSERT( NODEHEIGHT(pChildNode->pLChild)>NODEHEIGHT(pChildNode->pRChild) );
				DoubleLeftRotation( pRotateNode );
			}
			break;
		}
		//no rotation happend here, adjust the height
		CalcHeight( pRotateNode );
		pRotateNode = pRotateNode->pParent;
	}
		
/*	CNode* pRotateNode = pParent;
	CNode* pChildNode = pNewNode;
	CNode* pGrandChdNode = pNewNode;
	
	while( pRotateNode ){
		if( pRotateNode->pLChild==pChildNode ){
			//inserted in the left subtree.
			if( NODEHEIGHT(pRotateNode->pLChild)-NODEHEIGHT(pRotateNode->pRChild)==2 ){
				ASSERT( pChildNode!=pGrandChdNode );
				if( pChildNode->pLChild==pGrandChdNode ){
					SingleRightRotation( pRotateNode );
				}else{
					DoubleRightRotation( pRotateNode );
				}
				break;
			}
		}else{
			//inserted in the right subtree
			if( NODEHEIGHT(pRotateNode->pRChild)-NODEHEIGHT(pRotateNode->pLChild)==2 ){
				ASSERT( pChildNode!=pGrandChdNode );
				if( pChildNode->pRChild==pGrandChdNode ){
					SingleRightRotation( pRotNode );
				}else{
					DoubleRightRotation( pRotNode );
				}
				break;
			}
		}
		//no rotation happend here, adjust the height
		CalcuHeight( pRotateNode );
		//change the family
		pGrandChdNode = pChildNode;
		pChildNode = pRotateNode;
		pRotateNode = pRotateNode->pParent;
	}*/

/*	CNode* pRotateNode = pParent;
	CNode* pNode = pNewNode;
	while( pRotateNode ){
		CalcuHeight( pRotateNode );
		if( pRotateNode->pLChild==pNode ){
			//inserted in the left subtree.
			if( NODEHEIGHT(pRotateNode->pLChild)-NODEHEIGHT(pRotateNode->pRChild)==2 ){
				int nRet = CompareNode( (LPVOID)&newElement, (LPVOID)&pNode->data );
				if( nRet<=0 ){
					SingleRightRotation( pRotNode );
				}else{
					DoubleRightRotation( pRotNode );
				}
				break;
			}
		}else{
			//inserted in the right subtree
			if( NODEHEIGHT(pRotateNode->pRChild)-NODEHEIGHT(pRotateNode->pLChild)==2 ){
				int nRet = CompareNode( (LPVOID)&newElement, (LPVOID)&pNode->data );
				if( nRet<=0 ){
					SingleRightRotation( pRotNode );
				}else{
					DoubleRightRotation( pRotNode );
				}
				break;
			}
		}
		//no rotation happend here, adjust the height
		CalcuHeight( pRotateNode );
		pNode = pRotateNode;
		pRotateNode = pRotateNode->pParent;
	}*/
	return (POSITION) pNewNode;

}
Beispiel #10
0
/*******************************************************************************
  Função que faz a rotação dupla à direita a partir do nó pretendido da AVL.
  
  Function that makes the left-right double rotation.
*******************************************************************************/
static void DoubleLeftRightRotation (PtAVLNode *pnode)
{
	SingleLeftRotation (&(*pnode)->PtLeft);
	SingleRightRotation (pnode);
}
Beispiel #11
0
avltree DoubleRightLeftRotation(avltree A){
	A->right=SingleLeftRotation(A->right);
	return SingleRightRotation(A);
}
    /* 对称的右单旋与右-左双旋请自己实现 */
    AVLTree DoubleRightLeftRotation(AVLTree A){
        A->Right = SingleLeftRotation(A->Right);

        return SingleRightRotation(A);
    }