Geeks - AVL Tree Deletion 平衡二叉树 删除操作

注意:

1 判断一个节点是否平衡的方法

2 平衡一个节点的方法 :

我这里比原文改进一点,独立出一个平衡节点的函数balanceNode(),这样一个函数可以用来平衡插入和删除操作,使得代码更加简洁了。

这样修改之后就使得平衡二叉树好像和一般二叉树的操作比较,就是多了一个平衡操作。

3 删除操作情况很多,很困难,一定要理清思路。十分容易出bug的地方。

这里是查找后继节点的值,填补上到需要删除的节点,然后删除后继节点,然后从后继节点往上判断,一个一个节点做平衡操作。


原文参考:http://www.geeksforgeeks.org/avl-tree-set-2-deletion/


#pragma once
#include <stdio.h>
#include <algorithm>

using std::max;

class AVL_Deletion
{
	struct Node
	{
		int key;
		Node *left, *right;
		int h;
		Node(int k) : key(k), left(NULL), right(NULL), h(1) {}
		~Node()
		{
			if (left) delete left;
			if (right) delete right;
		}
	};

	void updateHeight(Node *n)
	{
		n->h = max(getHeight(n->left), getHeight(n->right)) + 1;
	}

	int getHeight(Node *n)
	{
		if (!n) return 0;
		return n->h;
	}

	Node *leftRotate(Node *y)
	{
		Node *x = y->right;
		y->right = x->left;
		x->left = y;

		updateHeight(y);
		updateHeight(x);
		return x;
	}

	Node *rightRotate(Node *y)
	{
		Node *x = y->left;
		y->left = x->right;
		x->right = y;

		updateHeight(y);
		updateHeight(x);
		return x;
	}

	int getBalance(Node *n)
	{
		if (!n) return 0;
		return getHeight(n->left) - getHeight(n->right);
	}

	Node *balanceNode(Node *n)
	{
		if (!n) return n;

		updateHeight(n);

		int balance = getBalance(n);

		if (balance > 1 && getBalance(n->left) >= 0)
			return rightRotate(n);
		if (balance < -1 && getBalance(n->right) <= 0)
			return leftRotate(n);
		if (balance > 1 && getBalance(n->left) < 0)
		{
			n->left = leftRotate(n->left);
			return rightRotate(n);
		}
		if (balance < -1 && getBalance(n->right) > 0)
		{
			n->right = rightRotate(n->right);
			return leftRotate(n);
		}
		return n;
	}

	Node *insert(Node *n, int key)
	{
		if (!n) return new Node(key);

		if (key < n->key) n->left = insert(n->left, key);
		else n->right = insert(n->right, key);

		return balanceNode(n);
	}

	Node *minValueNode(Node *n)
	{
		if (!n) return n;
		Node *cur = n;
		while (cur->left) cur = cur->left;
		return cur;
	}

	Node *delNode(Node *r, int key)
	{
		if (!r) return r;

		if (key < r->key) r->left = delNode(r->left, key);
		else if (r->key < key) r->right = delNode(r->right, key);
		else
		{
			if (!r->left || !r->right)
			{
				Node *t = r->left? r->left : r->right;
				if (!t)
				{
					t = r;
					r = NULL;
				}
				else *r = *t;//copy content, be careful about the *
				free(t);
			}
			else
			{
				//key step: get inorder successor
				Node *t = minValueNode(r->right);
				r->key = t->key;
				r->right = delNode(r->right, t->key);
			}
		}		
		return balanceNode(r);
	}

	void preOrder(Node *root)
	{
		if(root != NULL)
		{
			printf("%d ", root->key);
			preOrder(root->left);
			preOrder(root->right);
		}
	}
public:
	AVL_Deletion()
	{
		Node *root = NULL;

		/* Constructing tree given in the above figure */
		root = insert(root, 9);
		root = insert(root, 5);
		root = insert(root, 10);
		root = insert(root, 0);
		root = insert(root, 6);
		root = insert(root, 11);
		root = insert(root, -1);
		root = insert(root, 1);
		root = insert(root, 2);

		/* The constructed AVL Tree would be
		9
		/  \
		1    10
		/  \     \
		0    5     11
		/    /  \
		-1   2    6
		*/

		printf("Pre order traversal of the constructed AVL tree is \n");
		preOrder(root);

		root = delNode(root, 10);

		/* The AVL Tree after deletion of 10
		1
		/  \
		0    9
		/     /  \
		-1    5     11
		/  \
		2    6
		*/

		printf("\nPre order traversal after deletion of 10 \n");
		preOrder(root);
	}
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值