树的遍历、平衡二叉树实现

代码内容来自《大话数据结构》,程杰著。

原书中没有RightBalance函数实现,本处按照LeftBalance实现。

#include <stdio.h>
#include <stdlib.h>

#define  LH +1 //左高
#define  EH 0  //相等
#define  RH -1 //右高
typedef struct BitNode {
	int data;//结点数据
	int bf;//结点平衡因子
	struct BitNode * lchild, *rchild;
}BitNode, *pBitNode;

typedef enum {FALSE, TRUE} Status;
//右旋转
void R_Rotate(pBitNode * p) {
	pBitNode L;
	L = (*p)->lchild;
	(*p)->lchild = L->rchild;
	L->rchild = (*p);
	*p = L;
}
//左旋转
void L_Rotate(pBitNode * p) {
	pBitNode R;
	R = (*p)->rchild;
	(*p)->rchild = R->lchild;
	R->lchild = (*p);
	*p = R;
}
//左平衡调节
void LeftBalance(pBitNode *T) {
	pBitNode L, Lr;
	L = (*T)->lchild;
	switch (L->bf)
	{
	//情况2
	case LH: {
			(*T)->bf = L->bf = EH;
			R_Rotate(T);
		}
		break;
	//情况1
	case RH: {
			Lr = L->rchild;
			switch (Lr->bf)
			{
			case LH:{
					(*T)->bf = RH;
					L->bf = EH;
				}
				break;
			case EH:{
					(*T)->bf = L->bf = EH;
				}
				break;
			case RH:{
					(*T)->bf = EH;
					L->bf = LH;
				}
				break;
			}
			Lr->bf = EH;
			L_Rotate(&(*T)->lchild);
			R_Rotate(T);
		}
		break;
	}
}

void RightBalance(pBitNode *T) {
	pBitNode R, Rl;
	R = (*T)->rchild;
	switch (R->bf)
	{
	case RH: {
		(*T)->bf = R->bf = EH;
		L_Rotate(T);
		}
		break;
	case LH: {
		Rl = R->lchild;
		switch (Rl->bf)
		{
		case RH:{
			(*T)->bf = LH;
			R->bf = EH;
			}
			break;
		case EH:{
			(*T)->bf = R->bf = EH;
			}
			break;
		case LH:{
			(*T)->bf = EH;
			R->bf = RH;
			}
			break;
		}
		Rl->bf = EH;
		R_Rotate(&(*T)->rchild);
		L_Rotate(T);
		}
		break;
	}
}

Status InsertAVL(pBitNode *T, int e, Status *taller) {
	//空节点
	if (!*T) {
		*T = (pBitNode)malloc(sizeof(BitNode));
		(*T)->data = e;
		(*T)->lchild = (*T)->rchild = NULL;
		(*T)->bf = EH;
		*taller = TRUE;
		return TRUE;
	}
	//已经存在和e有相同关键字结点
	if (e == (*T)->data) {
		*taller = FALSE;
		return FALSE;
	}
	//插入结点
	if (e < (*T)->data) {
		if (!InsertAVL(&(*T)->lchild, e, taller)) {
			return FALSE;
		}
		if (*taller) {
			switch ((*T)->bf) {
			case LH:
				LeftBalance(T);
				*taller = FALSE;
				break;
			case EH:
				(*T)->bf = LH;
				*taller= TRUE;
				break;
			case RH:
				(*T)->bf = EH;
				*taller = FALSE;
				break;
			}
		}
	}
	else {
		if (!InsertAVL(&(*T)->rchild, e, taller)) {
			return FALSE;
		}
		if (*taller) {
			switch ((*T)->bf) {
			case RH:
				RightBalance(T);
				*taller = FALSE;
				break;
			case EH:
				(*T)->bf = RH;
				*taller= TRUE;
				break;
			case LH:
				(*T)->bf = EH;
				*taller = FALSE;
				break;
			}
		}
	}
	return TRUE;
}
//先根遍历
void PreOrderTraverse(pBitNode T) {
	if (T == NULL) {
		return;
	}
	printf("%d",T->data);
	PreOrderTraverse(T->lchild);
	PreOrderTraverse(T->rchild);
}
//中根遍历
void MidOrderTraverse(pBitNode T) {
	if (T == NULL) {
		return;
	}
	MidOrderTraverse(T->lchild);
	printf("%d",T->data);
	MidOrderTraverse(T->rchild);
}
//后根遍历
void LastOrderTraverse(pBitNode T) {
	if (T == NULL) {
		return;
	}
	LastOrderTraverse(T->lchild);
	LastOrderTraverse(T->rchild);
	printf("%d",T->data);
}
void main() {
	int i;
	int a[10] = {3,2,1,4,5,6,7,10,9,8};
	Status taller;
	pBitNode T=NULL;
	for (i=0; i<10; i++) {
		InsertAVL(&T, a[i], &taller);
		PreOrderTraverse(T);
		printf("  ");
		MidOrderTraverse(T);
		printf("  ");
		LastOrderTraverse(T);
		printf("\n");
	}
}

LeftBalance用于处理以下两种情况:

情况1:《树的遍历、平衡二叉树实现》     情况2:《树的遍历、平衡二叉树实现》

调整后结果:

《树的遍历、平衡二叉树实现》

情况1之所以在代码中存在两次旋转,是因为情况1需要首选左旋为情况2,后再右旋才能达到最后的调整结果。

RightBalance正好处理与LeftBalance相反情况。

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