AVLTree

这回好不容易做出来的数据结构是AVLTree,做之前犹豫了好久,做的时候浪费了很多时间,做完之后还是觉得不够优化。

比如在平衡因子那一块,我不知道什么时候什么情况更新平衡因子,只好用最蠢的办法递归找。这里会浪费很多时间。

多说无益贴代码了

/*
	Author: Triose
	Data:   2016.4.8
	Mail:   [email protected]
 */

#ifndef AVLTREE_H
#define AVLTREE_H

#include<iostream>
using namespace std;

//template<class T> T Max(T a, T b) { return a > b ? a : b; }	//用于求树高, 没用了

template<class T>
class TreeElmt {					//树节点定义,适当情况适当改装
public:
	T data;
	TreeElmt * left;
	TreeElmt * right;
	bool hidden;
	int factor;
	TreeElmt(T data_) {
		this->data = data_;
		this->left = NULL;
		this->right = NULL;
		this->hidden = false;
		this->factor = 0;
	}
};

template<class T>
class AVLTree {
public:
	TreeElmt<T> *root;
	int size;
	AVLTree() {
		this->root = NULL;
		this->size = 0;
	}
	void destroy(TreeElmt<T> * _root) {
		if (_root == NULL) {
			return;
		}
		destroy(_root->left);
		destroy(_root->right);
		delete _root;
		_root = NULL;
		return;
	}
	~AVLTree() {
		destroy(this->root);
	}

	int get_high(TreeElmt<T> * _root) {
		if (!_root) {
			return -1;
		}
		if (_root->factor >= 0) {
			return get_high(_root->left) + 1;
		}
		else
			return get_high(_root->right) + 1;
		//return Max(get_high(_root->left), get_high(_root->right)) + 1;		//其实不需要这个了。如果该节点平衡因子大于等于0,则返回左子树高度加一,否则返回右子树高度加一
	}

	int get_factor(TreeElmt<T> * _root) {
		return get_high(_root->left) - get_high(_root->right);
	}

	void rotate_left(TreeElmt<T> ** _froot) {
		TreeElmt<T> * _root = (_froot ? (*_froot)->left : this->root);						//此处为平衡因子最先变成2的节点
		TreeElmt<T> * left = _root->left;
		if (left->factor == 1) {
			/* LL rotate. */
			_root->left = left->right;
			left->right = _root;
			if (_froot) {
				(*_froot)->left = left;
			}
			else {
				this->root = left;
			}
			_root->factor = 0;
			left->factor = 0;
			return;
		}
		else {
			/* LR rotate. */
			TreeElmt<T> * gchild = left->right;
			left->right = gchild->left;
			gchild->left = left;
			_root->left = gchild->right;
			gchild->right = _root;
			if (_froot) {
				(*_froot)->left = gchild;
			}
			else {
				this->root = gchild;
			}
			switch (gchild->factor) {
			case 1: _root->factor = -1; left->factor = 0; break;
			case 0: _root->factor = 0; left->factor = 0; break;
			case -1: _root->factor = 0; left->factor = 1; break;
			}
			gchild->factor = 0;
			return;
		}
	}

	void rotate_right(TreeElmt<T> ** _froot) {
		TreeElmt<T> * _root = (_froot ? (*_froot)->right : this->root);
		TreeElmt<T> * right = _root->right;
		if (right->factor == -1) {
			/* RR ratate. */
			_root->right = right->left;
			right->left = _root;
			if (_froot) {
				(*_froot)->right = right;
			}
			else {
				this->root = right;
			}
			_root->factor = 0;
			right->factor = 0;
			return;
		}
		else {
			/* RL rotate. */
			TreeElmt<T> * gchild = right->left;
			right->left = gchild->right;
			gchild->right = right;
			_root->right = gchild->left;
			gchild->left = _root;
			if (_froot) {
				(*_froot)->right = gchild;
			}
			else {
				this->root = gchild;
			}
			switch (gchild->factor) {
			case 1: _root->factor = 0; right->factor = -1; break;
			case 0: _root->factor = 0; right->factor = 0; break;
			case -1: _root->factor = 1; right->factor = 0; break;
			}
			gchild->factor = 0;
		}
	}
	void ins(TreeElmt<T> ** _froot, TreeElmt<T> ** _root, T data_) {		//作为ADTree的插入没有问题
		if (!(*_root)) {
			*_root = new TreeElmt<T>(data_);
			this->size++;
			return;
		}
		if ((*_root)->data == data_) {			//看节点是否被隐藏,如果不被隐藏则不做任何操作
			if ((*_root)->hidden == true) {
				(*_root)->hidden = false;
			}
		}
		else if ((*_root)->data < data_) {		//插入右边
			ins(_root, &((*_root)->right), data_);
			(*_root)->factor = get_factor(*_root);//更新平衡因子
		}
		else {									//插入左边
			ins(_root, &((*_root)->left), data_);
			(*_root)->factor = get_factor(*_root);//更新平衡因子
		}
		/*现在判断要不要旋转,以及怎么旋转*/
		if ((*_root)->factor == 2) {
			rotate_left(_froot);
		}
		else if ((*_root)->factor == -2) {
			rotate_right(_froot);
		}
	}
	void rem(TreeElmt<T> * _root, T data_) {		//惰性移除
		if (_root == NULL)
			return;
		if (_root->data == data_) {
			_root->hidden = true;
			return;
		}
		else if (_root->data < data_) {
			rem(_root->right, data_);
		}
		else {
			rem(_root->left, data_);
		}
		return;
	}
	void Debug(TreeElmt<T> * _root) {				//For Debug
		if (!_root)
			return;
		Debug(_root->left);
		if (!_root->hidden)
			cout << _root->data << " " << _root->factor << endl;
		Debug(_root->right);
		return;
	}
};



#endif // !AVLTREE_H


2016.4.12更新

上面的代码还是忽悠忽悠人吧,运行的时候太慢而且会出问题,因为树的规模一旦很大,递归来更新树高和平衡因子肯定不行,而且, C++的效率很不如C,如果在oj上用template这种东西超时的几率是很大的!

下面更新纯C模板。

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

#define TYPE Node

typedef struct Node_ {
	int num;
}Node;
Node* creatNode(int num_) {
	Node *newnode = (Node *)malloc(sizeof(Node));
	newnode->num = num_;
	return newnode;
}

typedef struct TreeElmt_{
	void * data;
	int hight;
	int factor;
	int hidden;
	struct TreeElmt_ * left;
	struct TreeElmt_ * right;
}TreeElmt;

TreeElmt * creatElmt(void * data_) {
	TreeElmt * newelement = (TreeElmt *)malloc(sizeof(TreeElmt));
	newelement->data = (void *)data_;
	newelement->left = NULL;
	newelement->right = NULL;
	newelement->factor = 0;
	newelement->hight = 0;
	newelement->hidden = 0;
	return newelement;
}

typedef struct AVLTree_ {
	TreeElmt * root;
	int size;
}AVLTree;

void AVL_destroy(TreeElmt * _root) {
	if (!_root)
		return;
	AVL_destroy(_root->left);
	AVL_destroy(_root->right);
	free(_root);
	_root = NULL;
	return;
}
void AVL_init(AVLTree * tree) {
	AVL_destroy(tree->root);
	tree->root = NULL;
	tree->size = 0;
}

int cmp(TYPE a, TYPE b) {	//a < b return -1;		直接写结构体的比较函数即可
	if (a.num < b.num)
		return -1;
	else if (a.num == b.num)
		return 0;
	return 1;
}
void AVL_rem(TreeElmt * _root, void * data_) {
	if (!_root)
		return;
	int ans = cmp(*((TYPE *)(_root->data)), *((TYPE *)(data_)));
	switch (ans) {
	case -1: AVL_rem(_root->right, data_); break;
	case 0:  _root->hidden = 1;free(data_); break;
	case 1:  AVL_rem(_root->left, data_); break;
	}
	return;
}
void reflash(TreeElmt * _root) {						//更新树高和平衡因子
	int lh = _root->left ? _root->left->hight : -1;
	int rh = _root->right ? _root->right->hight : -1;
	_root->factor = lh - rh;
	_root->hight = lh > rh ? (lh + 1) : (rh + 1);
	return;
}


void left_rotate(AVLTree * tree, TreeElmt ** _froot) {
	TreeElmt * _root = (_froot) ? (*_froot)->left : tree->root;
	TreeElmt * left = _root->left;
	if (left->factor == 1) {
		/* LL rotate.*/
		_root->left = left->right;
		left->right = _root;
		if (_froot) {
		(*_froot)->left = left;
		}
		else {
		tree->root = left;
		}
		_root->factor = 0;					//重置平衡因子并且更新树高(更新树高的顺序不能变!)
		left->factor = 0;
		reflash(_root);
		reflash(left);
		if (_froot) {
			reflash(*_froot);
		}
		return;
	}
	else {
		/* LR rotate.*/
		TreeElmt * gchild = left->right;
		left->right = gchild->left;
		gchild->left = left;
		_root->left = gchild->right;
		gchild->right = _root;
		if (_froot) {
		(*_froot)->left = gchild;
		}
		else {
		tree->root = gchild;
		}
		switch (gchild->factor) {
		case 1: _root->factor = -1; left->factor = 0; break;
		case 0: _root->factor = 0; left->factor = 0; break;
		case -1: _root->factor = 0; left->factor = 1; break;
		}
		gchild->factor = 0;				//重置平衡因子并且更新树高
		reflash(left);
		reflash(_root);
		reflash(gchild);
		if (_froot)
			reflash(*_froot);
		return;
	}
}
void right_rotate(AVLTree * tree, TreeElmt ** _froot) {
	TreeElmt * _root = (_froot ? (*_froot)->right : tree->root);
	TreeElmt * right = _root->right;
	if (right->factor == -1) {
		/* RR ratate.*/
		_root->right = right->left;
		right->left = _root;
		if (_froot) {
		(*_froot)->right = right;
		}
		else {
		tree->root = right;
		}
		_root->factor = 0;					//重置平衡因子并且更新树高
		right->factor = 0;
		reflash(_root);
		reflash(right);
		if (_froot) {
			reflash(*_froot);
		}
		return;
	}
	else {
		/* RL rotate.*/
		TreeElmt * gchild = right->left;
		right->left = gchild->right;
		gchild->right = right;
		_root->right = gchild->left;
		gchild->left = _root;
		if (_froot) {
		(*_froot)->right = gchild;
		}
		else {
		tree->root = gchild;
		}
		switch (gchild->factor) {
		case 1: _root->factor = 0; right->factor = -1; break;
		case 0: _root->factor = 0; right->factor = 0; break;
		case -1: _root->factor = 1; right->factor = 0; break;
		}
		gchild->factor = 0;
		reflash(right);
		reflash(_root);
		reflash(gchild);
		if (_froot)
			reflash(*_froot);
		return;
	}
}

void AVL_ins(AVLTree * tree, TreeElmt ** _froot, TreeElmt ** _root, void * data_) {
	if (!*_root) {
		(*_root) = creatElmt(data_);
		tree->size++;
		return;
	}
	int ans = cmp(*((TYPE*)((*_root)->data)), *((TYPE*)(data_)));		//比较函数
	switch (ans) {
	case 1: AVL_ins(tree, _root, &((*_root)->left), data_); reflash(*_root); break;
	case 0: {
		if ((*_root)->hidden) {
			(*_root)->hidden = 0;
			free(data_);
			}
			break;
		}
	case -1: AVL_ins(tree, _root, &((*_root)->right), data_); reflash(*_root); break;
	}
	switch ((*_root)->factor) {
	case 2: left_rotate(tree, _froot);break;
	case -2: right_rotate(tree, _froot);break;
	default: break;
	}
	return;
}
void Debug(TreeElmt * _root) {
	if (!_root)
		return;
	Debug(_root->left);
	printf("%d %d\n", ((Node*)_root->data)->num, _root->factor);
	Debug(_root->right);
}


AVLTree tree;

int main() {
	AVL_init(&tree);
	AVL_ins(&tree, NULL, &(tree.root), creatNode(27));
	AVL_ins(&tree, NULL, &(tree.root), creatNode(45));
	AVL_ins(&tree, NULL, &(tree.root), creatNode(34));
	AVL_ins(&tree, NULL, &(tree.root), creatNode(20));
	AVL_ins(&tree, NULL, &(tree.root), creatNode(11));
	AVL_ins(&tree, NULL, &(tree.root), creatNode(59));
	AVL_ins(&tree, NULL, &(tree.root), creatNode(10));
	AVL_ins(&tree, NULL, &(tree.root), creatNode(25));
	AVL_ins(&tree, NULL, &(tree.root), creatNode(29));
	AVL_ins(&tree, NULL, &(tree.root), creatNode(30));
	Debug(tree.root);
	putchar(10);
}
没有很周全的测试,不过也应该差不多了

你可能感兴趣的:(AVLTree)