二叉树的旋转操作是针对AVL平衡二叉树或RBT红黑树而言的,为了优化查找,当发现树不平衡时,使用旋转操作。旋转方式分为3类:
- 左旋
- 右旋
- 双旋转:对于不平衡情况LR , 下方先左旋然后整体右旋;不平衡情况RL类似。
代码如下:
#include <stdlib.h>
#include <stdio.h>
typedef struct tree
{
int nValue;
struct tree *pLeft;
struct tree *pRight;
struct tree *pFat;
}BinaryTree;
BinaryTree *CreateBinaryTree()
{
BinaryTree *pRoot = NULL;
pRoot = (BinaryTree*)malloc(sizeof(BinaryTree));
pRoot->nValue = 10;
pRoot->pFat = NULL;
pRoot->pLeft = (BinaryTree*)malloc(sizeof(BinaryTree));
pRoot->pLeft->nValue = 5;
pRoot->pLeft->pFat = pRoot;
pRoot->pLeft->pLeft = (BinaryTree*)malloc(sizeof(BinaryTree));
pRoot->pLeft->pLeft->nValue = 4;
pRoot->pLeft->pLeft->pRight = NULL;
pRoot->pLeft->pLeft->pFat = pRoot->pLeft;
pRoot->pLeft->pLeft->pLeft = (BinaryTree*)malloc(sizeof(BinaryTree));
pRoot->pLeft->pLeft->pLeft->nValue = 1;
pRoot->pLeft->pLeft->pLeft->pLeft = NULL;
pRoot->pLeft->pLeft->pLeft->pRight = NULL;
pRoot->pLeft->pLeft->pLeft->pFat = pRoot->pLeft->pLeft;
pRoot->pLeft->pRight = (BinaryTree*)malloc(sizeof(BinaryTree));
pRoot->pLeft->pRight->nValue = 7;
pRoot->pLeft->pRight->pLeft = NULL;
pRoot->pLeft->pRight->pRight = NULL;
pRoot->pLeft->pRight->pFat = pRoot->pLeft;
pRoot->pRight = (BinaryTree*)malloc(sizeof(BinaryTree));
pRoot->pRight->nValue = 19;
pRoot->pRight->pLeft = NULL;
pRoot->pRight->pRight = NULL;
pRoot->pRight->pFat = pRoot;
return pRoot;
}
void PreOrderTraversal(BinaryTree *pRoot)
{
//前序
if(pRoot == NULL) return;
printf("%d ", pRoot->nValue);
PreOrderTraversal(pRoot->pLeft);
PreOrderTraversal(pRoot->pRight);
}
//旋转操作实质:至多改变4个节点3对父子关系
//右旋
void RightRotate(BinaryTree **pTree)
{
if(*pTree == NULL || (*pTree)->pLeft == NULL) return;
BinaryTree *pNode = (*pTree); // A
BinaryTree *pMark = (*pTree)->pLeft; //B
pNode->pLeft = pMark->pRight;
pMark->pRight = pNode;
if(pNode->pFat != NULL)
{
if(pNode->pFat->pLeft == pNode)
{
pNode->pFat->pLeft = pMark;
}
else
{
pNode->pFat->pRight = pMark;
}
}
else
{
(*pTree) = pMark;
}
if(pNode->pLeft != NULL) //E
{
pNode->pLeft->pFat = pNode;
}
pMark->pFat = pNode->pFat;
pNode->pFat = pMark;
}
//左旋
void LeftRotate(BinaryTree **pTree)
{
if(*pTree == NULL || (*pTree)->pRight == NULL) return;
BinaryTree *pNode = (*pTree); // A
BinaryTree *pMark = (*pTree)->pRight; //B
pNode->pRight = pMark->pLeft;
pMark->pLeft = pNode;
if(pNode->pFat != NULL)
{
if(pNode->pFat->pLeft == pNode)
{
pNode->pFat->pLeft = pMark;
}
else
{
pNode->pFat->pRight = pMark;
}
}
else
{
(*pTree) = pMark;
}
if(pNode->pRight != NULL) //E
{
pNode->pRight->pFat = pNode;
}
pMark->pFat = pNode->pFat;
pNode->pFat = pMark;
}
int main()
{
BinaryTree *pRoot = NULL;
pRoot = CreateBinaryTree();
PreOrderTraversal(pRoot);
printf("\n");
RightRotate(&pRoot);
PreOrderTraversal(pRoot);
printf("\n");
LeftRotate(&pRoot);
PreOrderTraversal(pRoot);
printf("\n");
return 0;
}