樹:
定義:一個(gè)樹至多有一個(gè)根節(jié)點(diǎn),每一個(gè)路徑的終端都叫終端節(jié)點(diǎn),也叫葉子結(jié)點(diǎn)。既不是根也不是葉子節(jié)點(diǎn)叫中間節(jié)點(diǎn),節(jié)點(diǎn)與節(jié)點(diǎn)連接的線叫邊。從底下往上看叫高度,從上往低看叫深度。
PS:樹整體高度和深度取最大值。
度:看當(dāng)前節(jié)點(diǎn)有n個(gè)子節(jié)點(diǎn)就叫n度。

二叉樹(Binary Tree)
定義:樹里的每個(gè)節(jié)點(diǎn)至多允許有兩個(gè)節(jié)點(diǎn)。
滿二叉樹
定義:每一層都是滿節(jié)點(diǎn)(2個(gè)節(jié)點(diǎn))除最后一層的二叉樹。
完全二叉樹
定義:只允許最后一層有空缺,且空缺的方式從右向左的二叉樹。
ps:滿二叉樹是完全二叉樹的一種特殊形勢。
平衡二叉樹
定義:樹中任意節(jié)點(diǎn),左右子樹高度差不超過1。
ps:完全二叉樹一定是平衡二叉樹。
排序二叉樹
定義:左孩子的值比父親小,右節(jié)點(diǎn)的值比父節(jié)點(diǎn)的大。
二叉樹的性質(zhì)
- $k$層滿二叉樹,葉子節(jié)點(diǎn)的個(gè)數(shù)是$ 2^{k-1} $
- $k$層滿二叉樹,總節(jié)點(diǎn)個(gè)數(shù)為$2^{k}-1$
- 對于任意一個(gè)二叉樹而言,度為0的節(jié)點(diǎn)比度為2的節(jié)點(diǎn)少一個(gè)。($n_0=n_2+1$),PS:對于一個(gè)完全二叉樹而言,度為1的節(jié)點(diǎn)至多有一個(gè)。
- 一個(gè)有$n$個(gè)節(jié)點(diǎn)的完全二叉樹,它的深度是$ K=\lfloor log2^{n}\rfloor +1$(向下取整) 例如:3.33 取3
- 對一個(gè)有$n$個(gè)節(jié)點(diǎn)的完全二叉樹,按照從上到下,從左到右的順序從1開始,開始編號,
- $i=1$時(shí)是根節(jié)點(diǎn)。
- $2i<=n $ ,$i$有左子樹,否則沒有。
- $2i+1<=n$時(shí),$i$有右子樹,否則沒有。
- 從$1$ ~ $\displaystyle\frac{n}2 $之間的節(jié)點(diǎn)都是父節(jié)點(diǎn),$\displaystyle\frac{n}2 $都是向下取整。
二叉樹的遍歷
- 深度(遞歸版)
- 前序遍歷:根左右
- 中序遍歷:左根右
- 后序遍歷:左右根
- 廣度遍歷(層序遍歷):從上到下,從左到右
#include<stdio.h>
#include<stdlib.h>
typedef struct Node
{
int nValue;
struct Node *pLeft;
struct Node *pRight;
}BinaryTree;
typedef struct node3
{
BinaryTree *nValue;
struct node3 *pNext;
}MyQueue;
typedef struct node4
{
int nCount;
MyQueue* pHead;
MyQueue *pTail;
}Queue;
BinaryTree * CreateTree();
void RecPreOrderTraversal(BinaryTree *pRoot)
{
if(pRoot == NULL)return;
//前序遍歷 根左右
printf("%d ",pRoot->nValue);
RecPreOrderTraversal(pRoot->pLeft);
RecPreOrderTraversal(pRoot->pRight);
}
void RecInOrderTraversal(BinaryTree *pRoot)
{
if(pRoot == NULL)return;
//中序遍歷 左根右
RecInOrderTraversal(pRoot->pLeft);
printf("%d ",pRoot->nValue);
RecInOrderTraversal(pRoot->pRight);
}
void RecLastOrderTraversal(BinaryTree *pRoot)
{
if(pRoot == NULL)return;
//后序遍歷 左右根
RecLastOrderTraversal(pRoot->pLeft);
RecLastOrderTraversal(pRoot->pRight);
printf("%d ",pRoot->nValue);
}
void q_Init(Queue **pQueue)
{
if(pQueue == NULL)return;
*pQueue = (Queue*)malloc(sizeof(Queue));
(*pQueue)->nCount = 0;
(*pQueue)->pHead = NULL;
(*pQueue)->pTail = NULL;
}
void q_Push(Queue *pQueue,BinaryTree *nNum)
{
MyQueue *pTemp = NULL;
if(pQueue == NULL)return;
pTemp = (MyQueue*)malloc(sizeof(MyQueue));
pTemp->nValue = nNum;
pTemp->pNext = NULL;
if(pQueue->pHead == NULL)
{
pQueue->pHead = pTemp;
}
else
{
pQueue->pTail->pNext = pTemp;
}
pQueue->pTail = pTemp;
pQueue->nCount++;
}
BinaryTree* q_Pop(Queue *pQueue)
{
MyQueue *pDel = NULL;
BinaryTree *Temp = NULL;
if(pQueue == NULL || pQueue->pHead == NULL)return NULL;
pDel = pQueue->pHead;
Temp = pDel->nValue;
pQueue->pHead = pQueue->pHead->pNext;
free(pDel);
pDel = NULL;
pQueue->nCount--;
if(pQueue->nCount == 0)
{
pQueue->pTail = NULL;
}
return Temp;
}
int q_IsEmpty(Queue *pQueue)
{
if(pQueue == NULL )return -1;
return pQueue->nCount ? 0:1;
}
void EveryTravelsalTree(BinaryTree *Tree)
{
//層序遍歷
Queue *M_Queue = NULL;
BinaryTree *Temp = NULL;
if(Tree == NULL)return;
q_Init(&M_Queue);
q_Push(M_Queue,Tree);
while(!q_IsEmpty(M_Queue))
{
Temp = q_Pop(M_Queue);
printf("%d ",Temp->nValue);
if(Temp->pLeft != NULL)
{
q_Push(M_Queue,Temp->pLeft);
}
if (Temp->pRight != NULL)
{
q_Push(M_Queue,Temp->pRight);
}
}
}
例二叉樹

前序:X Y F X R B K G D
中序:X B R Y Z F D G K
后序:X Y F Z R B K G D
二叉樹的創(chuàng)建
手動(dòng)創(chuàng)建二叉樹,最慢最基礎(chǔ)零技術(shù)的創(chuàng)建方法
#include<stdio.h>
#include<stdlib.h>
typedef struct Node
{
int nValue;
struct Node *pLeft;
struct Node *pRight;
}BinaryTree;
BinaryTree * CreateTree()
{
BinaryTree *pRoot = NULL;
pRoot = (BinaryTree*)malloc(sizeof(BinaryTree));
pRoot ->nValue = 1;
//根的左2
pRoot->pLeft = (BinaryTree*)malloc(sizeof(BinaryTree));
pRoot->pLeft->nValue = 2;
//左的左4
pRoot->pLeft->pLeft = (BinaryTree*)malloc(sizeof(BinaryTree));
pRoot->pLeft->pLeft->nValue = 4;
pRoot->pLeft->pLeft->pLeft = NULL;
pRoot->pLeft->pLeft->pRight = NULL;
//左的右5
pRoot->pLeft->pRight = (BinaryTree*)malloc(sizeof(BinaryTree));
pRoot->pLeft->pRight->nValue = 5;
pRoot->pLeft->pRight->pLeft = NULL;
pRoot->pLeft->pRight->pRight = NULL;
//根的右3
pRoot->pRight = (BinaryTree*)malloc(sizeof(BinaryTree));
pRoot->pRight->nValue = 3;
pRoot->pRight->pRight = NULL;
//右的左6
pRoot->pRight->pLeft = (BinaryTree*)malloc(sizeof(BinaryTree));
pRoot->pRight->pLeft->nValue = 6;
pRoot->pRight->pLeft->pLeft = NULL;
pRoot->pRight->pLeft->pRight = NULL;
return pRoot;
}
遞歸創(chuàng)建二叉樹(反序列創(chuàng)建二叉樹)
根據(jù)層序遍歷特點(diǎn)來創(chuàng)建二叉樹
void DynamicRecPreOrder(BinaryTree **Temp)
{
//前序動(dòng)態(tài)創(chuàng)建二叉樹,叫遞歸創(chuàng)建二叉樹或者反序列化創(chuàng)建二叉樹
int j;
scanf_s("%d",&j);
if(Temp==NULL)return;
if(j == 0)return;
*Temp = (BinaryTree*)malloc(sizeof(BinaryTree));
(*Temp)->nValue = j;
(*Temp)->pLeft = NULL;
(*Temp)->pRight = NULL;
DynamicRecPreOrder(&((*Temp)->pLeft));
DynamicRecPreOrder(&((*Temp)->pRight));
return;
}
動(dòng)態(tài)創(chuàng)建二叉樹(用數(shù)組的形勢)
根據(jù)二叉樹的性質(zhì)5
BinaryTree *DynamicArryCreateTree(int Temp[],int Num)
{
BinaryTree *Templ = NULL;
int i = 0;
int m = 0;
Templ = (BinaryTree*)malloc(sizeof(BinaryTree)*Num);
for(;i<Num;i++)
{
Templ[i].nValue = Temp[i];
Templ[i].pLeft = NULL;
Templ[i].pRight = NULL;
}
for (m = 0; m <= (Num/2) - 1 ; m++)
{
if(2*m+1<Num)
{
Templ[m].pLeft = &Templ[2*m+1];
}
if(2*m+2<Num)
{
Templ[m].pRight = &Templ[2*m+2];
}
}
return Templ;
}
二叉樹的循環(huán)高級遍歷(非遞歸)
敘述流程
- 申請棧stack
- 檢驗(yàn)參數(shù)
- (前序:打印節(jié)點(diǎn))節(jié)點(diǎn)入棧
- 判斷節(jié)點(diǎn)是否有左
- 有,重復(fù)3 4
- 沒有,下一步(中序:打印節(jié)點(diǎn))
- 棧頂彈出,彈出棧頂是否為空
- 是,結(jié)束
- 無,重復(fù)5
- 判斷彈出節(jié)點(diǎn)是否有右
- 有,把右變成當(dāng)前節(jié)點(diǎn),之后重復(fù)3 4
- 無,重復(fù)5
用循環(huán)實(shí)現(xiàn)前序遍歷
void OnRecTraversal(BinaryTree* Temp)
{
Stack *m_Stack = NULL;
if(Temp == NULL)return;
s_Init(&m_Stack);
while(1)
{
while (Temp)
{
printf("%d\n",Temp->nValue);
s_Push(m_Stack,Temp);
Temp = Temp->pLeft;
}
//棧頂彈出
Temp = s_Pop(m_Stack);
//判斷節(jié)點(diǎn)是否為空
if(Temp == NULL)return;
//向右處理
Temp = Temp->pRight;
}
}
用循環(huán)實(shí)現(xiàn)中序遍歷
void MidTraversal(BinaryTree* Temp)
{
Stack *m_Stack = NULL;
if(Temp == NULL)return;
s_Init(&m_Stack);
while(1)
{
while (Temp)
{
s_Push(m_Stack,Temp);
Temp = Temp->pLeft;
}
//棧頂彈出
Temp = s_Pop(m_Stack);
//判斷節(jié)點(diǎn)是否為空
if(Temp == NULL)return;
printf("%d\n",Temp->nValue);
//向右處理
Temp = Temp->pRight;
}
}
用循環(huán)實(shí)現(xiàn)后序遍歷
void RecLastOrderTraversal(BinaryTree* Temp)
{
Stack *m_Stack = NULL;
BinaryTree* pTemp = 0;
if(Temp == NULL)return;
s_Init(&m_Stack);
while(1)
{
while (Temp)
{
s_Push(m_Stack,Temp);
Temp = Temp->pLeft;
}
if(m_Stack->pTop == NULL)return;
if(m_Stack->pTop->nValue->pRight == NULL||m_Stack->pTop->nValue->pRight == pTemp)
{
pTemp = s_Pop(m_Stack);
printf("%d\n",pTemp->nValue);
}else
{
Temp = m_Stack->pTop->nValue->pRight;
}
}
return;
}
在二叉樹中插入一個(gè)結(jié)點(diǎn)
首先先寫一個(gè)查找的API
在一個(gè)二叉樹中查找一個(gè)結(jié)點(diǎn)
BinaryTree * Chop(BinaryTree *pRoot,int nNum)
{
Queue *pQueue = NULL;
BinaryTree *pTemp = NULL;
if(pRoot == NULL)return NULL;
q_Init(&pQueue);
//根入隊(duì)
q_Push(pQueue,pRoot);
while(!q_IsEmpty(pQueue))
{
pTemp = q_Pop(pQueue);
if(pTemp->nValue == nNum)
{
//記得清空隊(duì)列
return pTemp;
}
//左右非空入隊(duì)
if(pTemp->pLeft != NULL)
{
q_Push(pQueue,pTemp->pLeft);
}
if(pTemp->pRight != NULL)
{
q_Push(pQueue,pTemp->pRight);
}
}
return NULL;
}
在一個(gè)二叉樹中插入一個(gè)結(jié)點(diǎn),傳入方向,值
//傳入樹,放在那個(gè)節(jié)點(diǎn)的下面,放入得值,放入的方向
void InsertNode(BinaryTree **pRoot,int nNum,int nValue,int nDirection)
{
BinaryTree *pNode = NULL;
BinaryTree *pTemp = NULL;
if(pRoot == NULL || *pRoot == NULL)return;
//查找
pNode = Chop(*pRoot,nNum);
//檢測
//不存在
if(pNode == NULL)
{
printf("值不存在~~~\n");
return;
}
//存在
pTemp = (BinaryTree*)malloc(sizeof(BinaryTree));
pTemp->nValue = nValue;
pTemp->pLeft = NULL;
pTemp->pRight = NULL;
//被插入方向
if(nDirection == LEFT)
{
pTemp->pLeft = pNode->pLeft;
pNode->pLeft = pTemp;
return;
}
if(nDirection == RIGHT)
{
pTemp->pRight = pNode->pRight;
pNode->pRight = pTemp;
return;
}
}
創(chuàng)建一個(gè)排序二叉樹
創(chuàng)建流程
- 將值放入結(jié)點(diǎn)
- 檢測樹是否為空樹,若是空結(jié)點(diǎn),則新結(jié)點(diǎn)即為根,結(jié)束
- 若樹為非空樹
比較結(jié)點(diǎn)值大小
若值比結(jié)點(diǎn)值大,則向右子樹方向走
- 空樹:放入結(jié)點(diǎn)
- 非空樹:向右走,重復(fù)3步驟
若值比結(jié)點(diǎn)值小,則向左子樹方向走
- 空樹:放入結(jié)點(diǎn)
- 非空樹:向左走,重復(fù)3步驟
值相同的話,違背排序二叉樹的步驟,釋放新建結(jié)點(diǎn)空間,結(jié)束
void InsertNode(BinaryTree **pRoot,int nNum)
{
BinaryTree *pTemp = NULL;
BinaryTree *pMark = NULL;
if(pRoot == NULL)return;
pTemp = (BinaryTree*)malloc(sizeof(BinaryTree));
pTemp->nValue = nNum;
pTemp->pLeft = NULL;
pTemp->pRight = NULL;
//空樹
if(*pRoot == NULL)
{
*pRoot = pTemp;
return;
}
//標(biāo)記根
pMark = *pRoot;
while(1)
{
//新來的節(jié)點(diǎn)值小
if(nNum < pMark->nValue)
{
//左空
if(pMark->pLeft == NULL)
{
pMark->pLeft = pTemp;
return;
}
//非空 向左走
pMark = pMark->pLeft;
}
//新來的節(jié)點(diǎn)值大
else if(nNum > pMark->nValue)
{
//右空
if(pMark->pRight == NULL)
{
pMark->pRight = pTemp;
return;
}
//非空 向右走
pMark = pMark->pRight;
}
//新來值已經(jīng)存在 違背性質(zhì) 結(jié)束
else
{
free(pTemp);
pTemp = NULL;
return;
}
}
}
BinaryTree *CreateSrtTree(int arr[],int nLength)
{
BinaryTree *pRoot = NULL;
int i;
if(arr == NULL || nLength <=0)return NULL;
for(i = 0;i<nLength;i++)
{
InsertNode(&pRoot,arr[i]);
}
return pRoot;
}
從排序二叉樹中刪除一個(gè)結(jié)點(diǎn)
刪除的流程
- 葉子節(jié)點(diǎn),直接刪除
- 有一個(gè)孩子(即只有一個(gè)左子樹或者右子樹),刪除當(dāng)前結(jié)點(diǎn),用孩子代替它
- 有兩個(gè)孩子,找到其右的最左或者左的最右的結(jié)點(diǎn),將找到的結(jié)點(diǎn)的值覆蓋刪除結(jié)點(diǎn)的值,之后進(jìn)行步驟1,2
在一個(gè)排序二叉樹查找一個(gè)結(jié)點(diǎn)的代碼
//參數(shù):樹,被查找的值,被刪除節(jié)點(diǎn)的地址,被刪除節(jié)點(diǎn)的父親
void Search(BinaryTree *pTree,int nNum,BinaryTree **pDel,BinaryTree **pDelFather)
{
if(pTree == NULL)return;
while(pTree)
{
//找到 記住被刪除位置 結(jié)束
if(pTree->nValue == nNum)
{
*pDel = pTree;
return;
}
//查找的值比當(dāng)前節(jié)點(diǎn)的小 記住被刪除節(jié)點(diǎn)的父親 而后向左走
else if(pTree->nValue > nNum)
{
*pDelFather = pTree;
pTree = pTree->pLeft;
}
//查找的值比當(dāng)前節(jié)點(diǎn)的大 記住被刪除節(jié)點(diǎn)的父親 而后向右走
else
{
*pDelFather = pTree;
pTree = pTree->pRight;
}
}
//查找結(jié)束 沒找到 清空標(biāo)記刪除節(jié)點(diǎn)父親的指針
*pDelFather = NULL;
return ;
}
在排序二叉樹刪除一個(gè)節(jié)點(diǎn)代碼
void DelOneChild(BinaryTree **pRoot, BinaryTree *pDel,BinaryTree *pDelFather)
{
if(pRoot == NULL)return;
//被刪除節(jié)點(diǎn)是根
if(pDelFather == NULL)
{
*pRoot = pDel->pLeft ? pDel->pLeft:pDel->pRight;
free(pDel);
pDel = NULL;
return;
}
//檢測被刪除節(jié)點(diǎn)是父親的左還是右
if(pDel == pDelFather->pLeft)
{
//將被刪除節(jié)點(diǎn)非空的孩子與pdelfather關(guān)聯(lián)
pDelFather->pLeft = pDel->pLeft ? pDel->pLeft:pDel->pRight;
free(pDel);
pDel = NULL;
return;
}
if(pDel == pDelFather->pRight)
{
pDelFather->pRight = pDel->pLeft ? pDel->pLeft:pDel->pRight;
free(pDel);
pDel = NULL;
return;
}
}
void DelNode(BinaryTree **pTree,int nNum)
{
BinaryTree *pDel = NULL;
BinaryTree *pDelFather = NULL;
BinaryTree *pMark =NULL;
if(pTree == NULL || *pTree == NULL)return;
//查找
Search(*pTree,nNum,&pDel,&pDelFather);
//沒找到
if(pDel == NULL)return;
//找到
//有兩個(gè)孩子 向右找最小的
if(pDel->pLeft!= NULL && pDel->pRight != NULL)
{
pMark = pDel;
//移動(dòng)到右
pDelFather = pDel;
pDel = pDel->pRight;
//找右的最左
while(pDel->pLeft)
{
pDelFather = pDel;
pDel = pDel->pLeft;
}
//值覆蓋
pMark->nValue = pDel->nValue;
}
//刪除有一個(gè)孩子的或者沒孩子的
DelOneChild(pTree,pDel,pDelFather);
}
排序二叉樹轉(zhuǎn)換成一個(gè)排序雙向鏈表
流程
- 根據(jù)中序遍歷特點(diǎn),左根右
- 將二叉樹左看成鏈表的上指針,將二叉樹的右看鏈表的下指針.
- 在中序遍歷輸出的位置,將二叉樹變成鏈表式連接
代碼
void SortTreeToList(BinaryTree *pRoot, BinaryTree **pHead,BinaryTree **pTail)
{
if(pRoot == NULL)return;
if(pHead == NULL || pTail == NULL)return;
//找到左側(cè)
SortTreeToList(pRoot->pLeft,pHead,pTail);
//尾添加節(jié)點(diǎn)
if(*pHead == NULL)
{
*pHead = pRoot;
}
else
{
//雙向指向關(guān)聯(lián)
//left = 上一個(gè)pre
//right = 下一個(gè)next
(*pTail)->pRight = pRoot;
pRoot->pLeft = *pTail;
}
*pTail = pRoot;
//找到右側(cè)
SortTreeToList(pRoot->pRight,pHead,pTail);
}
平衡二叉樹的兩種旋轉(zhuǎn)
普通二叉樹深度:后序遍歷查棧里元素的個(gè)數(shù)
將差一步的平衡二叉樹變成平衡二叉樹
右旋
在原有的二叉樹里,添加一個(gè)父親的指針
在左子樹的左子樹添加一個(gè)結(jié)點(diǎn)F,進(jìn)行右旋
A交支點(diǎn)長的一邊B - D - F掰下來

兩個(gè)步驟:
記:A->pLeft = pMark
先處理兒子:
- A ->Father->left = pmark
- pmark->right = A
- pmark = pmark->right
父親: - pmark ->father = A->father
- A->father = pmark
- pmark->right->father = A
左旋
與右旋相反
創(chuàng)建一個(gè)不平衡二叉樹
void CreateBiTree(BinaryTree **root)
{
if(root == NULL)return;
(*root) = (BinaryTree*)malloc(sizeof(BinaryTree));
(*root)->nValue = 1;
(*root)->pFather = NULL;
//左子樹
(*root)->pLeft = (BinaryTree*)malloc(sizeof(BinaryTree));
(*root)->pLeft->nValue = 2;
(*root)->pLeft->pFather = *root;
//右子樹
(*root)->pRight = NULL;
//左的左
(*root)->pLeft->pLeft = (BinaryTree*)malloc(sizeof(BinaryTree));
(*root)->pLeft->pLeft->nValue = 3;
(*root)->pLeft->pLeft->pFather = (*root)->pLeft;
//左的左的左
(*root)->pLeft->pLeft->pLeft = (BinaryTree*)malloc(sizeof(BinaryTree));
(*root)->pLeft->pLeft->pLeft->nValue = 5;
(*root)->pLeft->pLeft->pLeft->pFather = (*root)->pLeft->pLeft;
(*root)->pLeft->pLeft->pLeft->pLeft = NULL;
(*root)->pLeft->pLeft->pLeft->pRight = NULL;
//左的左的右
(*root)->pLeft->pLeft->pRight = (BinaryTree*)malloc(sizeof(BinaryTree));
(*root)->pLeft->pLeft->pRight ->nValue = 6;
(*root)->pLeft->pLeft->pRight ->pFather = (*root)->pLeft->pLeft;
(*root)->pLeft->pLeft->pRight ->pLeft = NULL;
(*root)->pLeft->pLeft->pRight ->pRight = NULL;
//左的右
(*root)->pLeft->pRight = (BinaryTree*)malloc(sizeof(BinaryTree));
(*root)->pLeft->pRight->nValue = 4;
(*root)->pLeft->pRight->pFather = (*root)->pLeft;
(*root)->pLeft->pRight->pLeft = NULL;
(*root)->pLeft->pRight->pRight = NULL;
}
右旋,左旋代碼
void RightRotate(BinaryTree **pTree)
{
BinaryTree *pMark = NULL;
if(pTree == NULL)return;
//右旋標(biāo)記左側(cè)
pMark = (*pTree)->pLeft;
//處理兒子關(guān)系
(*pTree)->pLeft = pMark->pRight;
pMark->pRight = *pTree;
//支點(diǎn)父親是否存在
if((*pTree)->pFather != NULL)
{
//將支點(diǎn)的左和支點(diǎn)的父親關(guān)聯(lián)起來
((*pTree)->pFather->pLeft == *pTree)?((*pTree)->pFather->pLeft = pMark):((*pTree)->pFather->pRight= pMark);
}
//關(guān)聯(lián)父親
//支點(diǎn)的左是否存在
if((*pTree)->pLeft != NULL)
{
(*pTree)->pLeft->pFather = *pTree;
}
pMark->pFather = (*pTree)->pFather;
(*pTree)->pFather = pMark;
//支點(diǎn)是根節(jié)點(diǎn) 旋轉(zhuǎn)之后根節(jié)點(diǎn)更改
if(pMark->pFather == NULL)
{
*pTree = pMark;
}
}
void LeftRotate(BinaryTree **pTree)
{
BinaryTree *pMark = NULL;
if(pTree == NULL)return;
//右旋標(biāo)記左側(cè)
pMark = (*pTree)->pRight;
//處理兒子關(guān)系
(*pTree)->pRight = pMark->pLeft;
pMark->pLeft = *pTree;
//支點(diǎn)父親是否存在
if((*pTree)->pFather != NULL)
{
//將支點(diǎn)的左和支點(diǎn)的父親關(guān)聯(lián)起來
((*pTree)->pFather->pLeft == *pTree)?((*pTree)->pFather->pLeft = pMark):((*pTree)->pFather->pRight= pMark);
}
//關(guān)聯(lián)父親
//支點(diǎn)的左是否存在
if((*pTree)->pRight != NULL)
{
(*pTree)->pRight->pFather = *pTree;
}
pMark->pFather = (*pTree)->pFather;
(*pTree)->pFather = pMark;
//支點(diǎn)是根節(jié)點(diǎn) 旋轉(zhuǎn)之后根節(jié)點(diǎn)更改
if(pMark->pFather == NULL)
{
*pTree = pMark;
}
}