平衡二叉树(AVLTREE,双链表实现)
首先说下好久没更新了,最近打游戏和工作都有点多,o(^▽^)o。
写这个AVL发现自己的代码风格好差,尤其是变量命名这块,后来意识到了,想去改,但是太多了,改了几个就不想改了,做这个是记录下自己的成长吧。
另外说下,调这个AVL真心有点烦了,前面写了一个,但是逻辑有点乱,基本的删除都测差不多ok了,发现一个bug,实在不想去看那代码,太乱了,后来强b这自己去重新写,花了1个多小时(当然是加班的时候理),理清了,晚上9点多回来,大概3个小时,把del这块从新改完了,写代码真的是一个时候一个思想,发现处理节点只有单个分支的时候,还是第一次的思想好,直接指针操作一下,逻辑很精简,具体可以看code708的那2段逻辑处理,在处理删除节点有2个孩子节点时,在思考用指针直接处理,还是用一个临时变量来操作,最后选择了临时变量节点来处理,具体为什么,因为简单,而且仔细想了想这样处理是没错的,node里data基本只是一个keyValue,用在avl里查找,删除,构造做参考的,这个地方也有考虑用指针,也实现了,基本没多大问题,后来出bug的时候在那理了半天,实在受不了,把他改造了。
另外printAVL的函数直接copy BTree的,这个没什么好说的,还有AVL查找,这个真的不用我写了。本文主要就实现任意的一个数组构造AVLTree,删除AVLTree的任意个节点,保证AVLTree的特性。
具体贴代码,如下,测试的例子,都ok的,具体的放开,还有千万一定要吐槽我的变量命名及注释及很多,我在改,下次写的时候一定注意。
/*运行环境QT C */
#include <stdio.h>
#define DEBUG 0
//参考图http://www.cnblogs.com/skywang12345/p/3577360.html
#define PRINTTREEINIT(a)\
printf("------------------init Tree begin-------------\n");\
PrintBTree(a);\
printf("------------------init Tree end-------------\n");
#define PRINTTREEAVL(a)\
printf("------------------AVL Tree begin-------------\n");\
PrintBTree(a);\
printf("------------------AVL Tree end-------------\n"); #define PRINTTREEDEL(a)\
printf("------------------after del node Tree begin-------------\n");\
PrintBTree(a);\
printf("------------------after del nodeTree end-------------\n"); #define PRINTTREEADJ(a)\
printf("------------------after adjust Tree begin-------------\n");\
PrintBTree(a);\
printf("------------------after adjust Tree end-------------\n");
#define L 1
#define R -1
#define BTREE AVLTree
typedef struct treenode
{
int data;
int hight;
struct treenode *parent;
struct treenode *lchild;
struct treenode *rchild;
} TreeNode;
typedef enum {LL=,LR,RR,RL,RLR} TURNFLAG;
typedef TreeNode* AVLTree;
typedef int DATATYPE;
int IsLeafNode(TreeNode* Node);
//void DeleteNode(AVLTree* btree, DATATYPE delData);
void DeleteNode(AVLTree* btree, DATATYPE delData); TreeNode* InitNode(int data);
void InitAVLTree(AVLTree *avlTree, TreeNode *root); TreeNode *GetFixNode(AVLTree *btree, DATATYPE data);
int GetTreeHight(AVLTree *btree);
TreeNode *InsertNode(TreeNode* parNode, DATATYPE data);
int GetDiffHeight(TreeNode* rootNode);
int AdjustNode(TreeNode* posNode, AVLTree *avlTree);
int GetSymDiffHeight(TreeNode* rootNode);
int IsRoot(TreeNode* rootNode);
int IsLChild(TreeNode* rootNode);
TreeNode *GetMaxNode(TreeNode* rootNode);
TreeNode *GetMinNode(TreeNode* rootNode);
TreeNode* AdjustNodeByTurnFlag(TreeNode** Node,TURNFLAG a, AVLTree *avlTree);
void PrintNTab(int num);
void PrintBTree(BTREE* btree);
void PrintViewTreeNode(TreeNode* treeNode, int num);
TreeNode* GetPosByKeyValue(TreeNode* rootNode,int key);
int GetChildNum(TreeNode* rootNode);
int GetChildNum(TreeNode* curNode)
{
if((NULL != curNode->lchild)&&(NULL != curNode->rchild)) return ;
if((NULL != curNode->lchild)&&(NULL == curNode->rchild)) return ;
if((NULL == curNode->lchild)&&(NULL != curNode->rchild)) return -;
if((NULL == curNode->lchild)&&(NULL == curNode->rchild)) return ; }
TreeNode *GetMaxNode(TreeNode* rootNode)
{
if(rootNode == NULL) return NULL;
if(NULL == rootNode->rchild) return rootNode;
TreeNode *curNode = rootNode;
while((NULL != curNode)&&(NULL != curNode->rchild))
{
curNode = curNode->rchild;
}
return curNode;
} TreeNode *GetMinNode(TreeNode* rootNode)
{
if(rootNode == NULL) return NULL;
if(NULL == rootNode->lchild) return rootNode;
TreeNode *curNode = rootNode;
while((NULL != curNode)&&(NULL != curNode->lchild))
{
curNode = curNode->lchild;
}
return curNode;
} TreeNode* GetPosByKeyValue(TreeNode* rootNode,int data)
{
if(rootNode == NULL) return NULL;
if(data == rootNode->data) return rootNode; TreeNode* curTreeNode = rootNode; while( NULL != curTreeNode )
{
if(data > curTreeNode->data)
{
if(curTreeNode->rchild != NULL)
{
//printf("curTreeNode->rchild != NULL rchild[%d]\n", curTreeNode->rchild->data);
curTreeNode = curTreeNode->rchild;
}else{
curTreeNode = NULL;
break;
}
}
else if(data < curTreeNode->data)
{
if(curTreeNode->lchild != NULL)
{
curTreeNode = curTreeNode->lchild;
}else{
curTreeNode = NULL;
break;
}
}
else
{
printf("find key.\n", __LINE__);
return curTreeNode;
} }
if(NULL == curTreeNode)
{
printf("Not find key.\n", __LINE__);
return curTreeNode;
} }
void PrintViewTreeNode(TreeNode* treeNode, int num)
{
if(NULL == treeNode) return ;
num++;
printf("%d", treeNode->data);
if(treeNode->lchild == NULL)
{
printf("\n");
PrintNTab(num);
printf("*");
}
else
{ printf("\n");
PrintNTab(num);
PrintViewTreeNode(treeNode->lchild, num);
}
if(treeNode->rchild == NULL)
{
printf("\n");
PrintNTab(num);
printf("&"); }
else
{
printf("\n");
PrintNTab(num);
PrintViewTreeNode(treeNode->rchild, num); } }
void PrintBTree(BTREE* btree)
{
int num = ;
if(btree==NULL)
{
printf("empty tree.\n");
} printf("***********TREE View BEGIN***********\n");
//PrintTreeNode((*btree));
PrintViewTreeNode(*btree, num);
printf("\n");
printf("***********TREE View END ***********\n");
printf("\n"); printf("\n"); }
void PrintNTab(int num)
{
int i = ; while(i<num)
{
printf(" ");
i++;
}
}
TreeNode* AdjustNodeByTurnFlag(TreeNode** node,TURNFLAG tFlag,AVLTree *avlTree)
{//* > ->优先级
TreeNode* nodeTmp = (TreeNode* )malloc(sizeof(TreeNode));
TreeNode* freeNode = NULL;
int isRootNode = ;
int sdh = ;
int iRet = ;
memset(nodeTmp, 0x00, sizeof(TreeNode));
if(((tFlag>) ||(tFlag <)|| ((*node)==NULL))) return NULL;
switch (tFlag){
case LL:
freeNode = *node;
memcpy(nodeTmp,(*node)->lchild,sizeof(TreeNode));
*node = (*node)->lchild; (*node)->parent = nodeTmp->parent;
iRet = IsLChild(freeNode);
if(iRet == -)
{
//root
isRootNode = ;
}
else if( == iRet)
{
//isLchild
freeNode->parent->lchild = *node;
}
else if( == iRet)
{
//isRchild
freeNode->parent->rchild = *node;
} (*node)->rchild = freeNode;
freeNode->parent = *node; freeNode->lchild = nodeTmp->rchild;
if(NULL != nodeTmp->rchild)
{
freeNode->lchild->parent = freeNode;
}
if(isRootNode)
{
*avlTree = *node;
}
free(nodeTmp);
break;
case LR:
freeNode = *node;
memcpy(nodeTmp,(*node)->lchild->rchild,sizeof(TreeNode));
*node = (*node)->lchild->rchild;
(*node)->parent = freeNode->parent;
iRet = IsLChild(freeNode);
if(iRet == -)
{
//root
isRootNode = ;
}
else if( == iRet)
{
//isLchild
freeNode->parent->lchild = *node;
}
else if( == iRet)
{
//isRchild
freeNode->parent->rchild = *node; }
(*node)->lchild = freeNode->lchild;
freeNode->lchild->parent = *(node);
freeNode->lchild->rchild = NULL;
freeNode->lchild = NULL; (*node)->rchild = freeNode;
freeNode->parent = *(node); freeNode->lchild = nodeTmp->rchild;
(*node)->lchild->rchild = nodeTmp->lchild;
if(NULL != nodeTmp->rchild)
{
nodeTmp->rchild->parent = freeNode;
}
if(NULL != nodeTmp->lchild)
{
nodeTmp->lchild->parent = (*node)->lchild;
} if(isRootNode)
{
*avlTree = *node;
}
free(nodeTmp);
break; case RR:
//直接改变指针,所以入参是二级指针
freeNode = *node;
memcpy(nodeTmp,*node,sizeof(TreeNode));
*node=(*node)->rchild; if(nodeTmp->parent != NULL)
{
if(IsLChild(nodeTmp)){nodeTmp->parent->lchild = *node;}
else {nodeTmp->parent->rchild = *node;}
}
else
{
//说明nodeTmp是根节点,要改变树的节点
isRootNode = ;
} if((*node)->lchild){
nodeTmp->rchild = (*node)->lchild;
(*node)->lchild->parent = nodeTmp;
}
(*node)->parent = nodeTmp->parent;
(*node)->lchild = nodeTmp;
nodeTmp->parent = *node;
if(isRootNode)
{
*avlTree = *node;
}
free(freeNode);
//树的根节点被改了,这里要注意,刚好玩玩二级指针
break;
case RL:
freeNode = *node;
memcpy(nodeTmp,(*node)->rchild->lchild,sizeof(TreeNode));
*node = (*node)->rchild->lchild;
(*node)->parent = freeNode->parent;
iRet = IsLChild(freeNode);
if(iRet == -)
{
//root
isRootNode = ;
}
else if( == iRet)
{
//isLchild
freeNode->parent->lchild = *node;
}
else if( == iRet)
{
//isRchild
freeNode->parent->rchild = *node; }
(*node)->rchild = freeNode->rchild;
freeNode->rchild->parent = *(node);
freeNode->rchild->lchild = NULL;
freeNode->rchild = NULL; (*node)->lchild = freeNode;
freeNode->parent = *(node); freeNode->rchild = nodeTmp->lchild;
(*node)->rchild->lchild = nodeTmp->rchild;
if(NULL != nodeTmp->lchild)
{
nodeTmp->lchild->parent = freeNode;
}
if(NULL != nodeTmp->rchild)
{
nodeTmp->rchild->parent = (*node)->rchild;
} if(isRootNode)
{
*avlTree = *node;
}
free(nodeTmp);
break;
default:
break;
}
return *node; } //1->is
int IsLChild(TreeNode* sonNode)
{
if(sonNode->parent ==NULL)return -;
return ((sonNode->parent->lchild == sonNode)?:);
} //1->is
int IsRoot(TreeNode* rootNode)
{
return(rootNode->parent == NULL);
}
int GetDiffHeight(TreeNode* rootNode)
{ int lh=GetTreeHight((AVLTree*)&(rootNode->lchild));//L
int rh=GetTreeHight((AVLTree*)&(rootNode->rchild));//R
return ((lh>rh)?(lh-rh):(rh-lh));
} int GetSymDiffHeight(TreeNode* rootNode)
{
int lh=GetTreeHight((AVLTree*)&(rootNode->lchild));//L
int rh=GetTreeHight((AVLTree*)&(rootNode->rchild));//L
return (lh-rh);
} int AdjustNode(TreeNode* posNode, AVLTree* avlTree)
{//这个函数写的有点问题,如果传入的posNode dh = 2时候,而起父节点平衡了,就会少调整一部分,所以入posNode尽量用son
int dh = GetDiffHeight(posNode);
int sdh = ;
int sSondh = ;
if(== dh)return ;
if( == dh)
{
//这个地方后补上去的,感觉这个AVL树写的到处是漏洞啊汗
if(NULL != posNode->lchild)
{
posNode = posNode->lchild;
}
else if(NULL != posNode->rchild)
{
posNode = posNode->rchild;
}
} TreeNode *parNode = posNode->parent;
if(NULL == parNode ) return ;
dh = GetDiffHeight(parNode);
//l-r =0
while(parNode&&dh)
{
if(==dh)
{
sdh = GetSymDiffHeight(parNode);
if(- == sdh)
{
//in RL
sSondh = GetSymDiffHeight((parNode->rchild));
if(==sSondh)
{
//RL
AdjustNodeByTurnFlag(&parNode,RL,avlTree);
PrintBTree(avlTree);
}
else
{
//RR
AdjustNodeByTurnFlag(&parNode,RR,avlTree);
}
}
else
{
//in L
sSondh = GetSymDiffHeight(parNode->lchild);
if(==sSondh)
{
//LL
AdjustNodeByTurnFlag(&parNode,LL,avlTree);
}
else
{
//LR
AdjustNodeByTurnFlag(&parNode,LR,avlTree);
}
}
break;
}
parNode = parNode->parent;
if(parNode != NULL)
{
dh = GetDiffHeight(parNode); }
} }
TreeNode *InsertNode(TreeNode* parNode, DATATYPE data)
{
TreeNode* sonTreeNode = InitNode(data);
if((parNode->lchild != NULL)&&(parNode->rchild == NULL)) parNode->rchild = sonTreeNode;
if((parNode->rchild != NULL)&&(parNode->lchild == NULL)) parNode->lchild = sonTreeNode;
if((parNode->rchild == NULL)&&(parNode->lchild == NULL))
{
if(data < parNode->data)
{
parNode->lchild = sonTreeNode;
}
else{
parNode->rchild = sonTreeNode; }
}
sonTreeNode->parent = parNode; return sonTreeNode; } int IsLeafNode(TreeNode* Node)
{
return ((Node->lchild == NULL)&&(Node->rchild == NULL));
} int GetTreeHight(AVLTree *btree)
{//这里后来处理,空树的高度是0,根节点的高度1
TreeNode*curNode = *btree;
if((curNode ==NULL)) return ;
if(IsLeafNode(curNode)) return ; if(((curNode->lchild != NULL)&&(curNode->rchild ==NULL)&&IsLeafNode(curNode->lchild))
||((curNode->lchild == NULL)&&(curNode->rchild !=NULL)&&IsLeafNode(curNode->rchild))
||((curNode->lchild != NULL)&&(curNode->rchild !=NULL)&&IsLeafNode(curNode->rchild)&&IsLeafNode(curNode->lchild))
)
return ;
int leftHeight = GetTreeHight((AVLTree*)&((*btree)->lchild));
int rightHeight = GetTreeHight((AVLTree*)&((*btree)->rchild));
return ((leftHeight>rightHeight)?leftHeight:rightHeight)+; }
TreeNode* InitNode(int data)
{
TreeNode* newNode = (TreeNode*)malloc(sizeof(TreeNode));
memset(newNode, 0x00, sizeof(TreeNode));
newNode->data = data;
newNode->hight = ;
return newNode;
}
//return rootNode addr
void InitAVLTree(AVLTree *avlTree, TreeNode *root)
{
*avlTree = root;
} //查找合适的位置来插入新元素(find parent)
TreeNode* GetFixNode(AVLTree *AVLTree, DATATYPE data)
{
if((AVLTree == NULL ))
{
return NULL;
} if(((*AVLTree)->lchild == NULL)
&&((*AVLTree)->rchild == NULL))
{
//InsertNode(*AVLTree ,data);
#if DEBUG
printf("insert under root \n");
#endif
return *AVLTree;
}
TreeNode* curTreeNode = (TreeNode*)malloc(sizeof(TreeNode));
curTreeNode = *AVLTree;
while( (curTreeNode->lchild != NULL)
||(curTreeNode->rchild !=NULL) )
{
if(data > curTreeNode->data)
{
#if DEBUG
printf(" data=[%d] curData=[%d] insert R \n", data, curTreeNode->data);
#endif
if(curTreeNode->rchild != NULL)
{
#if DEBUG
printf("curTreeNode->rchild != NULL rchild[%d]\n", curTreeNode->rchild->data);
#endif
curTreeNode = curTreeNode->rchild; }else{ break;
}
}
else if(data < curTreeNode->data)
{
#if DEBUG
printf(" data=[%d] curData=[%d] insert L \n", data, curTreeNode->data);
#endif
if(curTreeNode->lchild != NULL)
{
curTreeNode = curTreeNode->lchild;
}else{ break;
}
}
else
{
printf("invaild elem here at line %d.\n", __LINE__);
return NULL;
} }
return curTreeNode; } //contruct tree
AVLTree* InitBTree(DATATYPE oriData[], int size)
{
int iRet = -;
AVLTree* avlTree = NULL;
avlTree = (AVLTree*)malloc(sizeof(AVLTree));
//*avlTree = (TreeNode*)malloc(sizeof(TreeNode));
int pos = size;
TreeNode* rootNode = InitNode(oriData[]);
InitAVLTree(avlTree, rootNode); TreeNode *posNode = (TreeNode*)malloc(sizeof(TreeNode));
while(pos>)
{
#if DEBUG
printf("********begin one*************\n");
printf("pos = [%d] index =[%d] data[%d]\n", pos, size-pos+, oriData[size-pos+]);
#endif
posNode = GetFixNode(avlTree, oriData[size-pos+]);
#if DEBUG
printf("Parent = [%d] Insert data=[%d] \n", posNode->data, oriData[size-pos+] );
#endif
InsertNode(posNode, oriData[size-pos+]);
//judge and confit
//PrintBTree(avlTree); iRet = AdjustNode(posNode, avlTree);
pos--;
#if DEBUG
printf("********end one*************\n\n");
#endif
//PrintBTree(avlTree); }
//PrintBTree(avlTree);
return avlTree; } void DeleteNode(AVLTree* avlTree, DATATYPE delKey)
{
TreeNode* posNode = GetPosByKeyValue(*avlTree,delKey);
int iIsRootNode = ;
int iIsLchlid = ; int iHight = ; /*处理传入节点in,freeNode 是 in的直接孩子节点情况,这个最早写的时候考虑不周*/ if(posNode == *avlTree)
{
printf("del root node\n");
iIsRootNode = ;
}
/*看到定义的变量没用,感觉好恶心*/
//TreeNode* parNode = NULL;//这个是临时变量,后面写,发现定义parnode是错的,应该定义tmpNode
TreeNode* freeNode = NULL;//这个是临时变量,后面写 ,应该定义tmpNode
//TreeNode* freeNodePar = NULL;//这个是临时变量,后面写 ,应该定义tmpNode
//TreeNode* curNode = NULL;//这个是临时变量,后面写 ,应该定义tmpNode //TreeNode* pLeftChildOfPosNode = NULL;
//TreeNode* pRightChildOfPosNode = NULL;
TreeNode* pParentOfPosNode = NULL;
//TreeNode* pCurPosNode = NULL; //TreeNode* pLeftChildOfFreeNode = NULL;
//TreeNode* pRightChildOfFreeNode = NULL;
TreeNode* pParentOfFreeNode = NULL;
TreeNode stTmpNode;
memset(&stTmpNode, 0x00, sizeof(TreeNode)); int iFlagLR = ;//judge isLchild
int iTagIsSon = ;//judge isLchild int sdh = ;//diff LR height of node
int iChildNum = ;
int iNum = ;
if(NULL != posNode )
{
iChildNum = GetChildNum(posNode);
iFlagLR = IsLChild(posNode); if( == iChildNum)
{
if(iIsRootNode)
{
free(posNode);
*avlTree = NULL;
return;
}
else
{
//isLeafNode
pParentOfPosNode = posNode->parent; if( == iFlagLR)
{
//L
pParentOfPosNode->lchild = NULL; }else if( == iFlagLR)
{
pParentOfPosNode->rchild = NULL;
}
free(posNode);
AdjustNode(pParentOfPosNode, avlTree); } }
else if( == iChildNum)
{
/*这段逻辑是最早写的,后来重理逻辑,理的很复杂,后来的逻辑基本是处理节点方法*/
pParentOfPosNode = posNode;
posNode = posNode->lchild;
if(iIsRootNode)
{
*avlTree = posNode;
}
else
{
if( == iFlagLR)
{
//L
pParentOfPosNode->parent->lchild = posNode ;
}else if( == iFlagLR)
{
pParentOfPosNode->parent->rchild = posNode ;
}
}
posNode->parent = pParentOfPosNode->parent;
free(pParentOfPosNode);
AdjustNode(posNode, avlTree);
}
else if(- == iChildNum)
{
pParentOfPosNode = posNode;
posNode = posNode->rchild;
if(iIsRootNode)
{
*avlTree = posNode;
}
else
{
if( == iFlagLR)
{
//L
pParentOfPosNode->parent->lchild = posNode ;
}
else if( == iFlagLR)
{
pParentOfPosNode->parent->rchild = posNode ;
}
}
posNode->parent = pParentOfPosNode->parent;
free(pParentOfPosNode);
AdjustNode(posNode, avlTree);
}
else if( == iChildNum)
{ /*********begin**********/
sdh = GetSymDiffHeight(posNode);
if(( == sdh)
||( == sdh))
{
//左子树比右子树高,调整左子树
//pCurPosNode = posNode;
freeNode = GetMaxNode(posNode->lchild);
iNum = GetChildNum(freeNode);
memset(&stTmpNode, 0x00, sizeof(TreeNode));
memcpy(&stTmpNode, freeNode, sizeof(TreeNode));
memcpy(freeNode, posNode, sizeof(TreeNode));
freeNode->data = stTmpNode.data;
if(iIsRootNode){
*avlTree = freeNode;
}
else
{
if(iFlagLR)
{
posNode->parent->lchild = freeNode;
}
else
{
posNode->parent->rchild = freeNode;
}
}
if( == iNum)
{/*process*/ pParentOfFreeNode = stTmpNode.parent;
if(stTmpNode.parent != posNode)
{
posNode->lchild->parent = freeNode;
posNode->rchild->parent = freeNode;
pParentOfFreeNode->rchild = NULL;
}
else
{
freeNode->lchild = NULL;
} free(posNode); if(stTmpNode.parent != posNode)
{
AdjustNode(pParentOfFreeNode, avlTree);
}
else
{
AdjustNode(freeNode, avlTree);
} }
else if( == iNum)
{
/*这个属于异常分支,会指向自己*/
//process posNode
if(stTmpNode.parent != posNode)
{
posNode->lchild->parent = freeNode;
posNode->rchild->parent = freeNode; }
else
{
stTmpNode.lchild->parent = freeNode;
posNode->rchild->parent = freeNode;
}
//process freeNode
if(stTmpNode.parent != posNode)
{
stTmpNode.lchild->parent = stTmpNode.parent;
stTmpNode.parent->rchild = stTmpNode.lchild;
}
else
{
stTmpNode.lchild->parent = freeNode;
freeNode->lchild = stTmpNode.lchild;
} free(posNode);
//AdjustNode(stTmpNode.parent, avlTree);
if(stTmpNode.parent != posNode)
{
AdjustNode(stTmpNode.parent, avlTree);
}
else
{
AdjustNode(freeNode, avlTree);
} }
}
else if(- == sdh)
{
//左子树比右子树低,调整右子树
//pCurPosNode = posNode;
freeNode = GetMinNode(posNode->rchild);
iNum = GetChildNum(freeNode);
memset(&stTmpNode, 0x00, sizeof(TreeNode));
memcpy(&stTmpNode, freeNode, sizeof(TreeNode));
memcpy(freeNode, posNode, sizeof(TreeNode));
freeNode->data = stTmpNode.data;
if(iIsRootNode){
*avlTree = freeNode;
}
else
{
if(iFlagLR)
{
posNode->parent->lchild = freeNode;
}
else
{
posNode->parent->rchild = freeNode;
}
}
if( == iNum)
{/*process*/
pParentOfFreeNode = stTmpNode.parent;
if(stTmpNode.parent != posNode)
{
posNode->lchild->parent = freeNode;
posNode->rchild->parent = freeNode;
pParentOfFreeNode->lchild = NULL;
}
else
{
freeNode->rchild = NULL;
} free(posNode); if(stTmpNode.parent != posNode)
{
AdjustNode(pParentOfFreeNode, avlTree);
}
else
{
AdjustNode(freeNode, avlTree);
}
#if 0
pParentOfFreeNode = stTmpNode.parent; posNode->lchild->parent = freeNode;
posNode->rchild->parent = freeNode;
pParentOfFreeNode->lchild = NULL;
free(posNode);
AdjustNode(pParentOfFreeNode, avlTree);
#endif }
else if(- == iNum)
{
/*这个属于异常分支,会指向自己*/
//process posNode
if(stTmpNode.parent != posNode)
{
posNode->lchild->parent = freeNode;
posNode->rchild->parent = freeNode; }
else
{
stTmpNode.rchild->parent = freeNode;
posNode->lchild->parent = freeNode;
}
//process freeNode
if(stTmpNode.parent != posNode)
{
stTmpNode.rchild->parent = stTmpNode.parent;
stTmpNode.parent->lchild = stTmpNode.rchild;
}
else
{
stTmpNode.rchild->parent = freeNode;
freeNode->rchild = stTmpNode.rchild;
} free(posNode);
if(stTmpNode.parent != posNode)
{
AdjustNode(stTmpNode.parent, avlTree);
}
else
{
AdjustNode(freeNode, avlTree);
} }
}
}
}
else
{
printf("can not find the key .\n");
}
}
void DelNodeTestCase()
{
#if 0
int arr[]={, , , , };//del root
AVLTree *avlTree = InitBTree(arr, );
PRINTTREEINIT(avlTree); int delKey = ;
DeleteNode(avlTree, delKey);
PRINTTREEDEL(avlTree);
#endif
#if 0
int arr[]={};//del root
AVLTree *avlTree = InitBTree(arr, );
PRINTTREEINIT(avlTree); int delKey = ;
DeleteNode(avlTree, delKey);
PRINTTREEDEL(avlTree);
#endif
#if 0
int arr[]={,};//del root
AVLTree *avlTree = InitBTree(arr, );
PRINTTREEINIT(avlTree); int delKey = ;
DeleteNode(avlTree, delKey);
PRINTTREEDEL(avlTree);
#endif
#if 0
int arr[]={,, };//del root
AVLTree *avlTree = InitBTree(arr, );
PRINTTREEINIT(avlTree); int delKey = ;
DeleteNode(avlTree, delKey);
PRINTTREEDEL(avlTree);
#endif #if 0
int arr[]={,, };
AVLTree *avlTree = InitBTree(arr, );
PRINTTREEINIT(avlTree); int delKey = ;
DeleteNode(avlTree, delKey);
PRINTTREEDEL(avlTree);
#endif #if 0
int arr[]={,, ,, , ,};
AVLTree *avlTree = InitBTree(arr, );
PRINTTREEINIT(avlTree); int delKey = ;
DeleteNode(avlTree, delKey);
PRINTTREEDEL(avlTree);
#endif
#if 0
int arr[]={,, ,, , ,};
AVLTree *avlTree = InitBTree(arr, );
PRINTTREEINIT(avlTree); int delKey = ;
DeleteNode(avlTree, delKey);
PRINTTREEDEL(avlTree);
#endif
#if 0
int arr[]={,, ,, , ,};
AVLTree *avlTree = InitBTree(arr, );
PRINTTREEINIT(avlTree); int delKey = ;
DeleteNode(avlTree, delKey);
PRINTTREEDEL(avlTree);
#endif
#if 0
int arr[]={,, ,, , };
AVLTree *avlTree = InitBTree(arr, sizeof(arr)/sizeof(arr[]));
PRINTTREEINIT(avlTree); int delKey = ;
DeleteNode(avlTree, delKey);
PRINTTREEDEL(avlTree);
#endif
#if 0
int arr[]={,, ,, };
AVLTree *avlTree = InitBTree(arr, sizeof(arr)/sizeof(arr[]));
PRINTTREEINIT(avlTree); int delKey = ;
DeleteNode(avlTree, delKey);
PRINTTREEDEL(avlTree);
#endif
#if 0
int arr[]={,, ,, , ,, , , ,,, };
AVLTree *avlTree = InitBTree(arr, sizeof(arr)/sizeof(arr[]));
PRINTTREEINIT(avlTree); int delKey = ;
DeleteNode(avlTree, delKey);
PRINTTREEDEL(avlTree);
#endif
#if 0
int arr[]={,, ,, , ,, , , ,,, };
AVLTree *avlTree = InitBTree(arr, sizeof(arr)/sizeof(arr[]));
PRINTTREEINIT(avlTree); int delKey = ;
DeleteNode(avlTree, delKey);
PRINTTREEDEL(avlTree);
#endif #if 0
/*左子树中max叶子节点*/
int arr[]={,, ,,,,,,,,,, };
AVLTree *avlTree = InitBTree(arr, );
PRINTTREEINIT(avlTree); int delKey = ;
DeleteNode(avlTree, delKey);
PRINTTREEDEL(avlTree);
#endif #if 0
/*左子树中max叶子节点*/
int arr[]={,, ,,,,,,,,,, };
AVLTree *avlTree = InitBTree(arr, sizeof(arr)/sizeof(arr[]));
PRINTTREEINIT(avlTree); int delKey = ;
DeleteNode(avlTree, delKey);
PRINTTREEDEL(avlTree);
#endif
#if 0
int arr[]={,, ,, , ,, , , ,,, };
AVLTree *avlTree = InitBTree(arr, sizeof(arr)/sizeof(arr[]));
PRINTTREEINIT(avlTree); int delKey = ;
DeleteNode(avlTree, delKey);
PRINTTREEDEL(avlTree);
#endif
/*这个地方调整影响到其他的地方了*/
#if 0
int arr[]={,, ,, , ,, , , ,,, };
AVLTree *avlTree = InitBTree(arr, sizeof(arr)/sizeof(arr[]));
PRINTTREEINIT(avlTree); int delKey = ;
DeleteNode(avlTree, delKey);
PRINTTREEDEL(avlTree);
#endif #if 0
/*左子树中max非叶子节点*/
int arr[]={,, ,,,,,,,,,, };
AVLTree *avlTree = InitBTree(arr, );
PRINTTREEINIT(avlTree); int delKey = ;
DeleteNode(avlTree, delKey);
PRINTTREEDEL(avlTree);
#endif #if 0
/*左子树中max非叶子节点*/
int arr[]={,, ,,,,};
AVLTree *avlTree = InitBTree(arr, );
PRINTTREEINIT(avlTree); int delKey = ;
DeleteNode(avlTree, delKey);
PRINTTREEDEL(avlTree);
#endif
#if 1
/*左子树中max非叶子节点3个节点情况*/
int arr[]={,, ,,,};
AVLTree *avlTree = InitBTree(arr, );
PRINTTREEINIT(avlTree); int delKey = ;
DeleteNode(avlTree, delKey);
PRINTTREEDEL(avlTree);
#endif
}
void ConstAVLTree()
{
#if 1
//int arr[6]={10, 8, 14, 12, 15, 16};//RR
//int arr[6]={10, 8, 18, 12, 25, 19};//RR
//int arr[6]={10, 8, 14, 12, 15, 11};//RL(L)
//int arr[6]={10, 8, 14, 12, 15, 13};//RL(R)
//int arr[6]={20, 17, 25, 14, 18, 15};//LL(L)
//int arr[6]={20, 17, 25, 14, 18, 16};//LL(R)
//int arr[6]={20, 16, 25, 14, 18, 17};//LR(L)
int arr[]={, , , , , };//LR(R)
AVLTree *avlTree = InitBTree(arr, sizeof(arr)/sizeof(arr[]));
PRINTTREEAVL(avlTree);
//int arr[12]={25, 14, 30, 8, 20, 28, 39, 7, 9, 18, 22, 19};//LR(R)
//int arr[12]={25, 14, 30, 8, 20, 28, 39, 7, 9, 18, 22, 17};//LR(L)
//int arr[12]={25, 14, 30, 8, 20, 28, 39, 7, 9, 18, 22, 6};//LL(L)
//int arr[12]={25, 10, 35, 8, 15, 29, 40, 27, 33, 38, 45, 26};//RL(L)
//int arr[12]={25, 10, 35, 8, 15, 29, 40, 27, 33, 38, 45, 50};//RR(L) //AVLTree *avlTree = InitBTree(arr, 12);
#endif
}
int main(void)
{
ConstAVLTree();
DelNodeTestCase();
return ;
}
运行结果:------------------AVL Tree begin-------------
***********TREE View BEGIN***********
18
16
14
*
&
&
20
19
*
&
25
*
&
***********TREE View END ***********
------------------AVL Tree end-------------
------------------init Tree begin-------------
***********TREE View BEGIN***********
28
21
18
*
19
*
&
25
*
&
40
30
*
&
&
***********TREE View END ***********
------------------init Tree end-------------
要写的数据结构又少一个哈哈哈哈哈哈
平衡二叉树(AVLTREE,双链表实现)的更多相关文章
- JAVA 链表操作:单链表和双链表
主要讲述几点: 一.链表的简介 二.链表实现原理和必要性 三.单链表示例 四.双链表示例 一.链表的简介 链表是一种比较常用的数据结构,链表虽然保存比较复杂,但是在查询时候比较便捷,在多种计算机语言都 ...
- java实现双链表(差点没写吐系列...)
刚才把单链表写完了,现在又把双链表写了,双链表和单链表的区别就是每个节点有prior和next两个指针,不同于单链表的一个next指针,而且,正是因为有这两个指针,所以双链表可以前后两个方向去移动指针 ...
- 数据结构图文解析之:数组、单链表、双链表介绍及C++模板实现
0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...
- C和指针 第十二章 使用结构和指针 双链表和语句提炼
双链表中每个节点包含指向当前和之后节点的指针,插入节点到双链表中需要考虑四种情况: 1.插入到链表头部 2.插入到链表尾部 3.插入到空链表中 4.插入到链表内部 #include <stdio ...
- [C++11][数据结构]自己的双链表实现
这个双链表,是我模仿stl的list制作的,只实现了一些基本功能,像merge,transfer这些就没有实现,用户可以用基本操作来自己做外部实现. 我没有选用stl的[begin,end)迭代器模式 ...
- C#双链表
单链表允许从一个结点直接访问它的后继结点,所以, 找直接后继结点的时间复杂度是 O(1).但是,要找某个结点的直接前驱结点,只能从表的头引用开始遍历各结点.如果某个结点的 Next 等于该结点,那么, ...
- Linux 底下使用C语言的 单链表 ,双链表,二叉树 读取文件,并排序
直接上代码 单链表Linux读文件排序: 双链表Linux读取文件排序: 二叉树LinuX读取文件并排序:
- 再谈LRU双链表内存管理
N年前我写了个双链表也发了博客,还添了代码.但是那个代码不但复杂,而且还有有问题的,一直懒得整理,放在空间误导别人.最近在写服务端,今天抽点空补一篇. 关于LRU网上随便搜,有过后端经验的人应该很多都 ...
- 数组、单链表和双链表介绍 以及 双向链表的C/C++/Java实现
概要 线性表是一种线性结构,它是具有相同类型的n(n≥0)个数据元素组成的有限序列.本章先介绍线性表的几个基本组成部分:数组.单向链表.双向链表:随后给出双向链表的C.C++和Java三种语言的实现. ...
随机推荐
- 使用multiprocessing模块操作进程
1.Process模块介绍 process模块是一个创建进程的模块,借助这个模块,就可以完成进程的创建. Process([group [, target [, name [, args [, kwa ...
- github删除项目or仓库
1. 登录 github (要注册账号) 2. 登录后点击右上侧头像,选择 Your profile . 3. 选择Repositories,可以查看已有的库,选择要删除的库进入. 4. 选择Sett ...
- [HDU1052]Tian Ji -- The Horse Racing(田忌赛马)
题目大意:田忌赛马问题,给出田忌和齐威王的马的数量$n$和每匹马的速度$v$,求田忌最多赢齐威王多少钱(赢一局得200,输一局扣200,平局不得不扣). 思路:贪心. 1.若田忌最慢的马可以战胜齐王最 ...
- Android开发进度03
1,今日:目标:实现登录界面 2,昨天:实现第一个Android项目Helloworld 3,收获:会使用手机进行测试,会使用SQlite数据库 4,问题:创建项目时出错
- 数字签名技术与https
1,非对称加密技术 非对称加密算法需要两个密钥,公开密钥(publickey)和私有密钥(privatekey):公钥和私钥是成对出现的. 非对称加密例子:B想把一段信息传给A,步骤:1)A把公钥传给 ...
- 怎样更好的深入学习andorid
把主要的控件 基本布局 基本组件 数据存储都熟悉一边,在看网络的时候,有点不知道怎么搞了.由于一直用c开发,但接触socket也不多,这两天把java的socket编程熟悉了下.找了非常多书,可是 ...
- iOS开发中的NSDateFormatter日期格式解析总结
在工作中,常常遇到将时间解析出来转换成自己相应要求的时间格式,之前也有收集相应的转换格式,如今将自己收集的一部分了做个分享,应该比較完好了,欢迎大家继续补充 年 y 将年份 (0-9) 显示为不带前导 ...
- 使用Dagger2创建的第一个小样例
将Dagger系列的咖啡壶样例再做一下简化,作为Dagger2的入门的第一个小样例. 场景描写叙述:有一个电水壶,它使用一个加热器来烧水.电水壶具备的功能有:開始加热(on方法),结束加热(off方法 ...
- 基于Zepto移动端下拉加载(刷新),上拉加载插件开发
写在前面:本人水平有限,有什么分析不到位的还请各路大神指出,谢谢. 这次要写的东西是类似于<今日头条>的效果,下拉加载上啦加载,这次做的效果是简单的模拟,没有多少内容,下面是今日头条的移动 ...
- VC6.0 设置动态链接库工程生成dll以及lib文件的位置
在"Projet"->"Settings..."的"Link"选项卡中 "Output file name"中设置 ...