手写数据结构:AVL树

Posted 看,未来

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了手写数据结构:AVL树相关的知识,希望对你有一定的参考价值。

刚开始比较懒,写的不多。代码部分测试,等整个系列写完再完整的测一遍

#include<iostream>
#include<vector>

using namespace std;

class TreeNode {
public:
	//这几个数据放做公有的,方便操作
	int depth; //深度,这里计算每个结点的深度,通过深度的比较可得出是否平衡
	TreeNode* parent; //该结点的父节点,方便操作
	int val;
	TreeNode* left;
	TreeNode* right;

	TreeNode(int x) : val(x), depth(0), left(NULL), right(NULL) {}
	TreeNode() : val(0), depth(0), left(NULL), right(NULL) {}

	void setnode(int val) {
		this->val = val;
	}

	void setleft(TreeNode* node) {
		this->left = node;
	}

	void setright(TreeNode* node) {
		this->right = node;
	}
};




class AVL_Tree {
public:
	AVL_Tree() {

	}
	
	TreeNode* right_rotate(TreeNode* root) {
		TreeNode* temp = root->left;
		root->left = temp->right;
		temp->right = root;

		return temp;
	}

	TreeNode* left_rotate(TreeNode* root) {
		TreeNode* temp = root->right;
		root->right = temp->left;
		temp->left = root;

		return temp;
	}

	TreeNode* right_left_rotate(TreeNode* root) {
		return left_rotate(right_rotate(root));
	}

	TreeNode* left_right_rotate(TreeNode* root) {
		return right_rotate(left_rotate(root));
	}

	int get_depth(TreeNode* node) {

		if (!node) {
			return 0;
		}

		int maxL = 0;
		int maxR = 0;

		//2.计算左子树的最大深度; 
		if (node->left != NULL)
			maxL = get_depth(node->left);

		//3.计算右子树的最大深度; 
		if (node->right != NULL)
			maxR = get_depth(node->right);

		//4.当前树的最大深度=左子树的最大深度和右子树的最大深度中的较大者+1 
		return maxL > maxR ? maxL + 1 : maxR + 1; 
	}

	int getbalance(TreeNode* node) {
		return get_depth(node->left) - get_depth(node->right);
	}

	//先假设这个二叉树足够高
	TreeNode* insert_node(TreeNode* head,int val) {	//插入一个节点,不管三七二十一先插到叶子节点再说
		
		if (head != NULL) {
			if (val < head->val) {
				head->left = insert_node(head->left, val);
			}
			else {
				head->left = insert_node(head->right, val);
			}
		}
		head = new TreeNode(val);

		//插入之后就该旋转了
		if (getbalance(head) == 2) {	//如果需要旋转(左边高)
			if (getbalance(head->left) == 1) {	//左左,需要右右旋转
				return right_rotate(head);	//这里还需要向上衔接
			}
			else if (getbalance(head->left) == -1) {	//左右,这里需要右左旋转
				return right_left_rotate(head);
			}
		}
		else if (getbalance(head) == -2) {	//如果需要旋转(右边高)
			if (getbalance(head->right) == -1) {	//右右,需要左左旋转
				return left_rotate(head);	//这里还需要向上衔接
			}
			else if (getbalance(head->right) == -1){	//左右,这里需要右左旋转
				return left_right_rotate(head);
			}
		}
	}

	TreeNode* delete_node(TreeNode* head,int val) {

		if (head!=NULL) {
			if (val < head->val) {
				head->left = delete_node(head->left, val);
			}
			else if(val > head->val){
				head->left = delete_node(head->right, val);
			}
			else {
				TreeNode* temp = head->left;
				while (temp && temp->right) {
					temp = temp->right;
				}
				head->val = temp->val;
				if (temp->left) {	//如果最右子节点还有左子节点
					//那顶多就一个节点
					temp->val = temp->left->val;
					//temp->left = temp->left->left;
					//temp->right = temp->left->right;
					temp->left->val = NULL;
					delete temp->left;
				}
				else {
					temp->val = NULL;
					delete temp;
				}
				return NULL;
			}
		}

		//插入之后就该旋转了
		if (getbalance(head) == 2) {	//如果需要旋转(左边高)
			if (getbalance(head->left) == 1) {	//左左,需要右右旋转
				return right_rotate(head);	//这里还需要向上衔接
			}
			else if (getbalance(head->left) == -1) {	//左右,这里需要右左旋转
				return right_left_rotate(head);
			}
		}
		else if (getbalance(head) == -2) {	//如果需要旋转(右边高)
			if (getbalance(head->right) == -1) {	//右右,需要左左旋转
				return left_rotate(head);	//这里还需要向上衔接
			}
			else if (getbalance(head->right) == -1) {	//左右,这里需要右左旋转
				return left_right_rotate(head);
			}
		}
	}

};

int main() {

}

以上是关于手写数据结构:AVL树的主要内容,如果未能解决你的问题,请参考以下文章

数据结构手写平衡二叉树(AVL)

AVL树手写笔记

AVL树手写笔记

AVL树手写笔记

数据结构系列之Java手写实现红黑树

数据结构系列之Java手写实现红黑树