万恶的AVL树,我只是想为机考热热身……虽然说对于AVL树只求理解不求实现,但既然碰到了,还是力求AC吧。就这样,做了整整一天(我才刚摆脱那邪恶的一万字英语论文……)
AVL树,书上和百度百科的代码都很长,而且书上的用了继承,百度百科的没有缩进,烦,没看。按照自己的理解慢慢写,但一直都程序崩溃,就像同时的选课系统崩溃一样。崩溃的原因费了很大精力,还是只能定位在旋转这个过程上而已。个人感觉是在指针引用上的处理不当引起的,虽然说我怎么也看不出具体问题所在,断点调试跟踪各种办法试遍,却都得到一个很怪异的情况:指针引用的赋值执行了,却没有实现,并且这个过程发生在函数内,貌似不关引用的事,具体原因不详……
最后决定在旋转这个过程中放弃使用引用,然后增设父母节点,改了很多,还是不成功;后来用栈代替递归,其他内容原封不动,结果AC了。
AC的代码很麻烦,若能实现递归的话会简明很多。
Run Time: 0sec
Run Memory: 312KB
Code length: 2570Bytes
Submit Time: 2012-01-05 21:56:44
// Problem#: 3825
// Submission#: 1175812
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include <iostream>
#include <stack>
using namespace std;
struct Node {
int data;
Node *left, *right;
Node( int n ) { data = n; left = NULL; right = NULL; }
};
Node *root;
stack<Node*> s;
int getHeight( Node *sub );
void insert( Node* &sub, int data );
void rotLeft( Node *sub, Node *parent );
void rotRight( Node *sub, Node *parent );
void balance();
void preorder( Node *sub );
void release( Node* &sub );
int main()
{
int t;
int n, data;
cin >> t;
while ( t-- ) {
root = NULL;
cin >> n;
while ( n-- ) {
cin >> data;
insert( root, data );
balance();
}
preorder( root );
cout << endl;
release( root );
}
return 0;
}
int getHeight( Node* sub ) {
return sub != NULL ? 1 + max( getHeight( sub->left ), getHeight( sub->right ) ): 0;
}
void insert( Node* &sub, int data ) {
if ( sub != NULL ) {
s.push( sub );
insert( data < sub->data ? sub->left: sub->right, data );
}
else
sub = new Node( data );
}
void rotLeft( Node *sub, Node *parent ) {
Node *right = sub->right;
sub->right = right->left;
right->left = sub;
if ( parent == NULL )
root = right;
else
sub == parent->left ? parent->left = right: parent->right = right;
}
void rotRight( Node *sub, Node *parent ) {
Node *left = sub->left;
sub->left = left->right;
left->right = sub;
if ( parent == NULL )
root = left;
else
sub == parent->left ? parent->left = left: parent->right = left;
}
void balance() {
Node *sub;
while ( !s.empty() ) {
sub = s.top();
s.pop();
int LHeight = getHeight( sub->left );
int RHeight = getHeight( sub->right );
if ( LHeight - RHeight == 2 ) {
if ( getHeight( sub->left->right ) - getHeight( sub->left->left ) == 1 )
rotLeft( sub->left, sub );
rotRight( sub, s.empty() ? NULL: s.top() );
}
else if ( RHeight - LHeight == 2 ) {
if ( getHeight( sub->right->left ) - getHeight( sub->right->right ) == 1 )
rotRight( sub->right, sub );
rotLeft( sub, s.empty() ? NULL: s.top() );
}
}
}
void preorder( Node *sub ) {
if ( sub != NULL ) {
cout << sub->data << " ";
preorder( sub->left );
preorder( sub->right );
}
}
void release( Node* &sub ) {
if ( sub != NULL ) {
release( sub->left );
release( sub->right );
delete sub;
}
}