c++写AVL二叉平衡搜索树算法

下面是我写的avl数算法模板,虽然已过三个月,现在再次想重写,仍然难以找到可以在优化的地方。
这个算法里面用到的递归操作和其他细节都很多,一旦某处写错,可能造成难以发现的bug。。。
下面是代码,注释照旧,发现不足之处或有所疑问欢迎留言。

#include
#include
#include
#include
using namespace std;
#define max(a,b) ((a)>(b)?(a):(b))  //a and by shoubld be Node* type
#define height(a) ((a)?a->height:0)				
#define left(a) ((a->left)?a->left->key:-1)		
#define right(a) ((a->right)?a->right->key:-1)

struct Node{
	int key;
	int height;
	Node *left;
	Node *right;
};

void update_height(Node* p, Node*p2=NULL){
	p->height = max( height(p->left), height(p->right) ) + 1;
	if (p2) p2->height = max(height(p->left), height(p->right)) + 1;
}

Node* create_node(int key){		//only use when a node add too the leaf
	Node *p = new Node;
	p->key = key;
	p->height = 1;
	p->left = p->right = NULL;
	return p;
}

Node* llr(Node* p){
	Node* t = p->left;
	p->left = t->right;
	t->right = p;
	update_height(p, t);  //p and t order have a very important effect.
	return t;
}

Node* rrr(Node* p){		//p->right become the next root
	Node* t = p->right;
	p->right = t->left;
	t->left = p;
	update_height(p, t);
	return t;
}

Node* lrr(Node* p){
	p->left = rrr(p->left);
	return llr(p);
}

Node* rlr(Node* p){
	p->right = llr(p->right);
	return rrr(p);
}

Node* insert(Node *tree, int key){
	if (tree == NULL) return tree = create_node(key);  //change *tree hava no effect on the parameter outside
	else if (key < tree->key){					//insert to the left tree
		tree->left = insert(tree->left, key);	//recall itself
		if (height(tree->left) > height(tree->right) + 1){		//lose the banlance.
			if (key < tree->left->key)			//the new node have add into left-left tree
				tree = llr(tree);
			else tree = lrr(tree);
		}
	}
	else if (key > tree->key){		//insert to the right tree
		tree->right = insert(tree->right, key);
		if (height(tree->right) > height(tree->left) + 1){
			if (key > tree->right->key)
				tree = rrr(tree);
			else tree = rlr(tree);
		}
	}
	else if (key == tree->key);	//change it line if you want it tree can insert two node with same key...
	update_height(tree);
	return tree;
}

// remove-operation is complex
Node* remove(Node*tree, int p){  //you should guarantee that p is exist in the tree
	if (tree == NULL) return NULL;
	// I have find the problem in remove() for a monring but find that the problem is in insert()!
	if (p < tree->key){  // search the left tree
		tree->left = remove(tree->left, p);
		update_height(tree);
		if (height(tree->left) + 1 < height(tree->right)){ //lose the banlance
			Node* temp = tree->right;
			tree = ((height(temp->left) > height(temp->right) + 1) ? rlr(tree) : rrr(tree));
		}
	}
	else if (p > tree->key){ //search the right tree
		tree->right = remove(tree->right, p);
		update_height(tree);
		if (height(tree->left) > height(tree->right) + 1){
			Node* temp = tree->left;
			tree = ((height(tree->right) > height(temp->left)) ? lrr(tree) : llr(tree));
		}
	}
	else {  //finally find the node that need to delete, p==root->key
		if (tree->left && tree->right){		//the node have two son
			if (height(tree->left) > height(tree->right)){//use the max node in the left tree to replace that node
				Node* max = tree->left;
				while (max->right)	max = max->right;
				tree->key = max->key;
				tree->left = remove(tree->left, max->key);
			}
			else{	//if right-tree taller than left-tree, use the min node in right to replace the node should delete
				Node* min = tree->right;
				while (min->left) min = min->left;
				tree->key = min->key;
				tree->right = remove(tree->right, min->key);

			}
			update_height(tree);
		}
		else{		//the node which should remove have one or no son.
			Node* temp = tree;
			tree = (tree->left ? tree->left : tree->right);
			delete temp;
		}
	}
	return tree;
}

void layerOrder(Node* r){
	queue<Node*>que;
	que.push(r);
	while (!que.empty()){
		Node* f = que.front();
		que.pop();
		if (f == NULL) continue;
		printf("%d    %d    ---> %d   ---> %d\n", f->key, height(f), left(f), right(f) );
		que.push(f->left);
		que.push(f->right);
	}
	return;
}

int test(){
	int date[20] = { 88, 70, 61, 96, 120,1, 7, 9, 12, 16, 18, 22, 44, 56, 36, 16, 17, 111 };
	Node *root = NULL;
	for (int i = 0; i <5; i++){
		root = insert(root, date[i]);
		layerOrder(root);
		cout << "==================================" << endl;
	}
	cout << endl << endl << endl;
	for (int i = 0; i < 5; i++) {
		cout << "remove   :" << date[i] << endl;
		root = remove(root, date[i]);
		layerOrder(root);
		cout << "==================================" << endl;
	}
	cout <<endl<< "The end....." << endl;
	return 0;
}

int main(){
	test();
}

你可能感兴趣的:(数据结构与算法)