二叉平衡树(C语言实现)超级简洁版

数据结构定义

#define AVL_NODE_CHILE 0
#define AVL_NODE_PARENT 1

//平衡二叉树节点
typedef struct avl_node
{
	int key;//关键字
	avl_node* left;//左孩子
	avl_node* right;//右孩子
	int height;//节点高度
}avl_node;

//二叉树本身
typedef struct avl
{
	//根节点
	avl_node* root;
	int size;//节点数目
}avl;

接口设计

//创建一个节点
avl_node* avl_create_node(int key);
//返回节点高度
int avl_height(avl_node* node);
//比较目标值和节点的大小,
//若目标值大,则返回真,反之返回假
int avl_compare_key(int key, avl_node* node);
//返回两个节点的高度较大值
int max(avl_node* x, avl_node* y);
//创建一颗平衡二叉树
avl* avl_create();
//中序遍历二叉树
void avl_inorder_traversal(avl_node* node);
//LL型,需要右转,返回子树新的根
avl_node* avl_rotate_ll(avl_node* node);
//RR型,需要左转
avl_node* avl_rotate_rr(avl_node* node);
//LR型,先右转在左转
avl_node* avl_balance_lr(avl_node* node);
//RL型,先右转在左转
avl_node* avl_balance_rl(avl_node* node);
//搜索节点
avl_node* avl_search_node(avl_node* node, int type, int key);
//插入一个节点
avl* avl_insert_node(avl* avl, int key);

测试代码

int main()
{
	avl* avl = avl_create();

	int arr[] = { 21,3,5,26,29,50,18,53,8,67,1,78,6 };
	//int arr[] = { 21,3,5,26,29,50 };
	int length = sizeof(arr) / sizeof(int);

	for (int i = 0; i < length; i++)
	{
		printf("-----------------\n");
		printf("插入:%d\n", arr[i]);
		avl_insert_node(avl, arr[i]);
		printf("中序:");
		avl_inorder_traversal(avl->root);
		printf("\n");
	}

	return 0;
}

接口实现

//创建一个节点
avl_node* avl_create_node(int key)
{
	avl_node* node = (struct avl_node*)malloc(sizeof(struct avl_node));
	if (node == NULL)return NULL;
	node->height = 1;
	node->key = key;
	node->left = NULL;
	node->right = NULL;

	return node;
}

//返回节点高度
int avl_height(avl_node* node)
{
	if (node == NULL)return 0;
	return node->height;
}

//比较目标值和节点的大小,
//若目标值大,则返回真,反之返回假
int avl_compare_key(int key, avl_node* node)
{
	if (node == NULL)return 0;
	if (key > node->key)return 1;
	return 0;
}

//返回两个节点的高度较大值
int max(avl_node* x, avl_node* y)
{
	int m = avl_height(x);
	int n = avl_height(y);
	return m > n ? m : n;
}

//创建一颗平衡二叉树
avl* avl_create()
{
	avl* avl = (struct avl*)malloc(sizeof(struct avl));
	if (avl == NULL)return NULL;
	avl->root = NULL;
	avl->size = 0;
	
	return avl;
}

//中序遍历二叉树
void avl_inorder_traversal(avl_node* node)
{
	if (node != NULL)
	{
		avl_inorder_traversal(node->left);
		printf("%d\t", node->key);
		avl_inorder_traversal(node->right);
	}

	return;
}

//LL型,需要右转,返回子树新的根
avl_node* avl_rotate_ll(avl_node* node)
{
	//新的根
	avl_node* top = node->left;
	node->left = top->right;
	top->right = node;
	
	//重新计算节点高度,从低高度节点先计算
	node->height = max(node->left, node->right) + 1;
	top->height = max(top->left, top->right) + 1;

	return top;
}

//RR型,需要左转
avl_node* avl_rotate_rr(avl_node* node)
{
	//新的根
	avl_node* top = node->right;
	node->right = top->left;
	top->left = node;

	//重新计算节点高度,从低高度节点先计算
	node->height = max(node->left, node->right) + 1;
	top->height = max(top->left, top->right) + 1;

	return top;
}

//LR型,先右转在左转
avl_node* avl_balance_lr(avl_node* node)
{
	node->left = avl_rotate_rr(node->left);
	return avl_rotate_ll(node);
}

//RL型,先右转在左转
avl_node* avl_balance_rl(avl_node* node)
{
	node->right = avl_rotate_ll(node->right);
	return avl_rotate_rr(node);
}

//搜索节点
avl_node* avl_search_node(avl_node* node, int type, int key)
{
	avl_node* cur = node;
	avl_node* parent = NULL;

	if (cur == NULL)return NULL;
	while (cur != NULL)
	{
		if (key < cur->key)
		{
			parent = cur;
			cur = cur->left;
		}
		else if (key == cur->key)
		{
			break;
		}
		else if (key > cur->key)
		{
			parent = cur;
			cur = cur->right;
		}//end_if
	}//end_while

	if (type == AVL_NODE_CHILE)return cur;
	return parent;
}

//插入一个节点
avl* avl_insert_node(avl* avl, int key)
{
	std::stack<avl_node*>stack;

	avl_node* cur = avl->root;
	avl_node* parent = NULL;

	//如果是空树则直接插入
	if (cur == NULL)
	{
		avl->root = avl_create_node(key);
		avl->size++;
		return avl;
	}

	//找到待插入节点的位置,通过栈记录路径节点值
	while (cur != NULL)
	{
		stack.push(cur);
		if (key < cur->key)
		{
			parent = cur;
			cur = cur->left;
		}
		else if (key == cur->key)
		{
			break;
		}
		else if (key > cur->key)
		{
			parent = cur;
			cur = cur->right;
		}
	}//end_whhile

	//执行到此处parent不可能为空
	if (parent == NULL)return NULL;
	//插入节点
	if (key < parent->key)
		parent->left = avl_create_node(key);
	else if (key == parent->key)
		return NULL;
	else
		parent->right = avl_create_node(key);

	//回溯栈节点,进行平衡调整
	while (!stack.empty())
	{
		cur = stack.top();
		stack.pop();

		if (stack.empty())
			parent = NULL;
		else
			parent = stack.top() ;

		//调整高度
		cur->height = max(cur->left, cur->right) + 1;
		//计算平衡因子
		int bf = avl_height(cur->left) - avl_height(cur->right);
		printf("回退:%d,left:%d,right:%d,bf:%d\n", cur->key, avl_height(cur->left), avl_height(cur->right), bf);

		//为rr或者rl型
		if (bf == -2)
		{
			//待插入key若比右子树大,则为rr型
			if (avl_compare_key(key, cur->right))
			{
				//该不平衡子树是否右父节点
				if (parent == NULL)
					avl->root = avl_rotate_rr(cur);
				else
				{
					//有父节点,需要判断该不平衡子树是parent的左子树还是右子树
					if (cur->key < parent->key)
						parent->left = avl_rotate_rr(cur);
					else
						parent->right = avl_rotate_rr(cur);
				}//end_if
			}
			//否则为rl型
			else 
			{
				if (parent == NULL)
					avl_balance_rl(cur);
				else
				{
					if (cur->key < parent->key)
						parent->left = avl_balance_rl(cur);
					else
						parent->right = avl_balance_rl(cur);
				}
			}//end_if
		}
		else if (bf == 2)
		{
			//lr型
			if (avl_compare_key(key, cur->left))
			{
				if(parent==NULL)
					avl->root=avl_balance_lr(cur);
				else
				{
					if (cur->key < parent->key)
						parent->left = avl_balance_lr(cur);
					else
						parent->right = avl_balance_lr(cur);
				}
			}
			//ll型
			else
			{
				if (parent == NULL)
					avl->root = avl_rotate_ll(cur);
				else
				{
					//有父节点,需要判断该不平衡子树是parent的左子树还是右子树
					if (cur->key < parent->key)
						parent->left = avl_rotate_ll(cur);
					else
						parent->right = avl_rotate_ll(cur);
				}
			}
		}//end_if
		if (parent != NULL)
			parent->height = max(parent->left, parent->right) + 1;
	}//end_while

	avl->size++;
	return avl;
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
平衡排序(AVL)是一种自平衡的二排序,它的左右子的高度差不超过1。下面是平衡排序的C语言实现: ```c #include <stdio.h> #include <stdlib.h> typedef struct AVLNode { int data; int height; struct AVLNode *left; struct AVLNode *right; } AVLNode; int max(int a, int b) { return a > b ? a : b; } int getHeight(AVLNode *node) { if (node == NULL) { return 0; } return node->height; } int getBalanceFactor(AVLNode *node) { if (node == NULL) { return 0; } return getHeight(node->left) - getHeight(node->right); } AVLNode *createNode(int data) { AVLNode *node = (AVLNode *)malloc(sizeof(AVLNode)); node->data = data; node->height = 1; node->left = NULL; node->right = NULL; return node; } AVLNode *leftRotate(AVLNode *node) { AVLNode *newRoot = node->right; AVLNode *temp = newRoot->left; newRoot->left = node; node->right = temp; node->height = max(getHeight(node->left), getHeight(node->right)) + 1; newRoot->height = max(getHeight(newRoot->left), getHeight(newRoot->right)) + 1; return newRoot; } AVLNode *rightRotate(AVLNode *node) { AVLNode *newRoot = node->left; AVLNode *temp = newRoot->right; newRoot->right = node; node->left = temp; node->height = max(getHeight(node->left), getHeight(node->right)) + 1; newRoot->height = max(getHeight(newRoot->left), getHeight(newRoot->right)) + 1; return newRoot; } AVLNode *insert(AVLNode *node, int data) { if (node == NULL) { return createNode(data); } if (data < node->data) { node->left = insert(node->left, data); } else if (data > node->data) { node->right = insert(node->right, data); } else { return node; } node->height = max(getHeight(node->left), getHeight(node->right)) + 1; int balanceFactor = getBalanceFactor(node); if (balanceFactor > 1 && data < node->left->data) { return rightRotate(node); } if (balanceFactor < -1 && data > node->right->data) { return leftRotate(node); } if (balanceFactor > 1 && data > node->left->data) { node->left = leftRotate(node->left); return rightRotate(node); } if (balanceFactor < -1 && data < node->right->data) { node->right = rightRotate(node->right); return leftRotate(node); } return node; } void preOrder(AVLNode *node) { if (node != NULL) { printf("%d ", node->data); preOrder(node->left); preOrder(node->right); } } int main() { AVLNode *root = NULL; root = insert(root, 10); root = insert(root, 20); root = insert(root, 30); root = insert(root, 40); root = insert(root, 50); root = insert(root, 25); printf("Preorder traversal of the constructed AVL tree is: \n"); preOrder(root); return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值