Algorithm - 行者无疆 始于足下 - 行走,思考,在路上

zoj1489

题目不是很难,重点是时间限制。因此需要优化下算法,不要暴力的用pow(x, y)函数。我用的是pow(x,y)图省事,先是出现了久违的compilation error。思前想后,自己的机器上编译没有问题啊。看了zoj的输出指示:

p.cc: In function 'int main(int, char**)':
p.cc:19: error: call of overloaded 'pow(int, int&)' is ambiguous
/usr/include/bits/mathcalls.h:154: note: candidates are: double pow(double, double)
/usr/include/c++/4.2/cmath:373: note:                 long double std::pow(long double, int)
/usr/include/c++/4.2/cmath:369: note:                 float std::pow(float, int)
/usr/include/c++/4.2/cmath:365: note:                 double std::pow(double, int)
/usr/include/c++/4.2/cmath:361: note:                 long double std::pow(long double, long double)
/usr/include/c++/4.2/cmath:357: note:                 float std::pow(float, float)

估计大概是libc版本不同造成的。修改了以下程序,又出现了TLE的错误了。后来想了想,利用同余特性,改进了程序,还是TLE。程序如下:

#include <iostream>
using namespace std;

int main(int argc, char* argv[])
{
    int n, temp, result;
    
    while(cin >> n)
    {
        if((n & 0x1) == 0)
            cout << "2^? mod " << n << " = 1" << endl;
        else
        {
            temp = 1;
            result = 1;
            while(1)
            {
                temp *= 2;
                temp %= n;
                if(temp == 1)
                    break;
                ++result;
            }
            cout << "2^" << result << " mod " << n << " = 1" << endl;
        }
    }
    return 0;
}

这是怎么回事呢?百思不得其解。俗话说外事不决问google,内事不决问baidu。于是baidu之,发现只要将判断条件改进下就行,AC的程序如下:

#include <iostream>
using namespace std;

int main(int argc, char* argv[])
{
    int n, temp, result;
    
    while(cin >> n)
    {
        if((n & 0x1) == 0 || n < 2)
            cout << "2^? mod " << n << " = 1" << endl;
        else
        {
            temp = 1;
            result = 1;
            while(1)
            {
                temp *= 2;
                temp %= n;
                if(temp == 1)
                    break;
                ++result;
            }
            cout << "2^" << result << " mod " << n << " = 1" << endl;
        }
    }
    return 0;
}

一个n<2,应该无关紧要……先记着这笔帐。

AC了26道题目了。都是水题。不管怎样,先凑个数练练手也好。时间紧迫。一定的数量还是必须的。要不以后出去也忒没面子了。

zoj 1201

继续刷水题。看到这道题目有印象,想想,ms当初算法是想出来了。就是自己想写个链表却有bug,结果一直拖着没有解决。好歹前几天又研究了下STL,这下派上用场了。不过代码写的很乱,感觉不够优美,不beautiful。最后的输入输出有些小问题,导致第一次提交是Presentation Error。后来仔细看了看搞定。算了,先糊弄着看吧。15道了。还有285道。一道一道的啃。

具体解题思路就不写了。大概如下,如果是P,就进行双层循环,然后搞一个数组的索引(不知道该怎么说哎……);如果是I,建立一个链表,从Inversion[]的最后一个元素开始循环,然后分别处理每个元素。根据Inversion[i]的数值遍历链表并插入合适的元素。最后的输入输出有问题。仔细看一下就行了。

#include <iostream>
#include <list>
using namespace std;

const int max_size = 50;

int main(int argc, char *argv[])
{
    int cases;
    char method;

    while (1)
    {
        cin >> cases;

        if (cases == 0)
        {
            break;
        }

        cin >> method;
        if (method == 'P')
        {
            int P[max_size], I[max_size];

            for (int i = 0; i < cases; ++i)
            {
                cin >> P[i];
                I[i] = 0;
            }
            for (int i = 0; i < cases; ++i)
            {
                for (int j = i + 1; j < cases; ++j)
                {
                    if (P[i] > P[j])
                    {
                        I[P[j]-1]++;
                    }
                }
            }
            for (int i = 0; i < cases - 1; ++i)
            {
                cout << I[i] << " ";
            }
            cout << I[cases - 1] << endl;
        }
        else if (method == 'I')
        {
            list<int> P;
            int I[max_size];

            for (int i = 0; i < cases; ++i)
            {
                cin >> I[i];
            }

            P.push_back(cases);
                        
            for (int i = cases - 2; i >= 0; --i)
            {
                list<int>::iterator it = P.begin();
                for (int j = 0; j < I[i]; j++)
                {
                    it++;
                }
                P.insert(it, i+1);
            }

            list<int>::iterator it;
            int i;
            
            for (i = 0, it = P.begin(); i < P.size() - 1; ++it, ++i)
            {
                cout << *it << " ";
            }
            
            cout << *it << endl;
        }
        else
        {
            break;
        }
    }
    
    return 0;
}

zoj 1089

依然是很菜很菜。开始的时候有些迷惑,后来想了想原来就是给你N个整数取6个有多少种组合。然后在做一定的输出处理的题目。想到的有递归和初步的DFS,可是都不太会写。就写了一个很土的程序。土的掉渣。输入输出还是不熟练,提交了三次才AC。没脸见人了。加油加油!

#include <iostream>
using namespace std;

int main()
{
	const int max_number = 15;
	int numbers;
	
	int set[max_number];
	int cases = 0;
	
	while (1)
	{
		cin >> numbers;
		
		if (numbers == 0)
		{
			break;
		}
		
		cases++;

		if ( cases >= 2 )
		{
			cout << endl;
		}
		
		for (int i = 0; i < numbers; i++)
			cin >> set[i];
			
		int i0, i1, i2, i3, i4, i5;
		
		for (i0 = 0; i0 <= numbers - 6; i0++)
			for (i1 = i0 + 1; i1 <= numbers - 5; i1++)
				for (i2 = i1 + 1; i2 <= numbers - 4; i2++)
					for (i3 = i2 + 1; i3 <= numbers - 3; i3++)
						for (i4 = i3 + 1; i4 <= numbers - 2; i4++)
							for (i5 = i4 + 1; i5 <= numbers - 1; i5++)
								cout << set[i0] << " " << set[i1] << " " << set[i2] << " " << set[i3] << " "
									 << set[i4] << " " << set[i5] << endl;
	}
		
	return 0;
}

顺便,昨天搞了个行者无疆单车知识入门讲座,比较轰动,草坪上搭起了大大的本营帐篷,七八辆车,二十多个人,我使出浑身解数,定车、俯卧撑、拆车修车、旅行经历等等。整个讲座还算比较精彩,从7点一直唠叨到10点20左右。已经有些冷了。于是借了辆车回到yq。拉力听讲座的有大二的,也有博二的。讲完了一个小dd跑过来跟我说“谢谢你,学长”,好可爱;有个博二的说我“非常成熟”,有几个mm被我讲的羞答答的,大概是受不了行者的ws之风了;还有几个wsn,中途跑到校友林里面小便,我甚至都能听到嘘嘘声音,何况mm会羞了。后来我也去尿了一泡……

实验室又来了项目。所以今天告别了亲爱的gentoo先生,回到了VS2008的怀抱。大体来说是做一个嵌入式平台上模仿iphone界面的东西。引擎什么的基于已有的几万行代码。其实去年已经初步接触这个项目,只是课程太忙,时间上安排不过来。这次老师也实在是缺人了,把我这么菜的也拉了过来。一个毕业的研究僧学长领头,还有两个研究僧是主力。两个刚考完研的大四同学每天从下沙赶来,怪辛苦的,不过他们水平实在太菜,连c++都不会,还得我教……看来我菜,有人比我还菜……

主要战略就是在实验室泡二十天,争取能搞出点成果来。将来简历上也好有点东西。否则一片花拳绣腿,怕是饭都吃不饱了。

不过头疼的还是课程。算了,赶时间补吧。还有289道zoj题目。还有lpi。顺便有空再去刷一次我那可怜的六级成绩。

over。再来一道zoj。

zoj 1057

编程还是很菜。很简单的题,基本的输入输出格式弄了很久。没脸见人了。zoj的选拔标准有变,我看能否在两个月之内拿下三百道题。还得把lpi考掉,恐怕要顺延到暑假了。加油加油。

晚上的计算机体系结构实验搞的很崩溃,硬件的课程,该怎么办呢。也不知道对自己以后能有多大的帮助,目前策略是得过且过……组了个队,同组的竟然是个04级的,令我颇为差异。看来,计算机的毕业也不是那么简单。

is-programmer博客系统越来越强大了。最近加入的代码高亮真的是非常的棒!赞!

顺便,86版五笔初有小成,逐渐转移到五笔输入法,效率之上的生活! 

#include <iostream>
using namespace std;

int main(int argc, char *argv[])
{
    int cases;

    const int max_size = 20;

    int a[max_size];
    int b[max_size];

    int sum_a;
    int sum_b;

    int times = 0;
    while (cin >> cases)
    {
        if (cases == 0)
        {
            break;
        }
        else
        {
            times++;
            
            if (times >= 2)
            {
                cout << endl << endl;
            }
        }
        
        sum_a = sum_b = 0;

        for (int i = 0; i < cases; ++i)
        {
            cin >> a[i];
        }

        for (int i = 0; i < cases; ++i)
        {
            cin >> b[i];
        }

        for (int i = 0; i < cases; ++i)
        {
            if (a[i] == 1 && b[i] == 2)
            {
                sum_a += 6;
            }
            else if (a[i] == 2 && b[i] == 1)
            {
                sum_b += 6;
            }
            else if (a[i] - b[i] == 1)
            {
                sum_b += a[i] + b[i];
            }
            else if (b[i] - a[i] == 1)
            {
                sum_a += a[i] + b[i];
            }
            else if (a[i] - b[i] >= 2)
            {
                sum_a += a[i];
            }
            else if (b[i] - a[i] >= 2)
            {
                sum_b += b[i];
            }
            else;
        }

        cout << "A has " << sum_a << " points. B has " << sum_b << " points.";
    }

    return 0;
}

 

bst, avl, c++, inheritance, template, two days

鉴于大二上年幼无知加上某些特殊的原因,导致我大三才开始修读高级数据结构。同一屋子大二的小朋友们上课,百般滋味,心中自知。第一次课迟到了,下课的时候随便找了两个学弟,算是组了个队,并申请做Project1(因为开始的Project)会比较简单。

实践起来也不是很难,就是让你比较下BinarySearchTree, AVL Tree和Splay Tree的插入删除效率的问题。两个学弟看样子都不愿意编码,于是乎,编码的重担就落在了我这个学长身上。可是只有我自己知道,我数据结构学的实在不咋的,C++又是个半吊子。唉,谁让咱是学长呢?

学长嘛,自然要有个学长的样子。于是乎,C++、Template、Inheritance、Polymorphism,能用上的都用上……呵呵。不过主要是想练一下手。C++ Primer虽然看了大半,却没有多少应用的机会。这也算是一个练习吧。

写着写着就知道,C++的强大是一把双刃剑,强大到你无法驾驭,尤其是应用了模板后,各种小问题,都是以前闻所未闻的。比如模板的分离编译问题,看书,查资料就花了两个小时。加上昨天下午吐血恶心的同步时序电路的逻辑实验,做的我都想哭了。所以这么看上去很简单的project,我竟然写了接近两天,倍感惭愧。

不过总算出来了。但是有个瑕疵,avl的删除功能有些小问题,可能跟Balance函数和指针的引用问题有关。gdb我用的不熟,转到强大的windows下的visual studio 2008下,调试了3个小时,找到错误所在,但是却不知道怎么改正。泪奔。

计算几何最终还是低空坠毁,唉,不提也罢,看来以后不能乱选课,选了课不能随便混混。混不好就低空坠毁。你说你没事选这么一门前沿课程干嘛,你是这块料嘛……

计算几何过后开始准备计算理论的期中考试。什么有穷自动机,正则语言,上下文无关文法,等等,计算理论基础的中文版,每个小时3页,龟速前进,发现还是太抽象,看不大懂,又找来一本计算理论导引,两本结合着看,顿觉顺畅很多,看来计算机的书还是要原汁原味的英文啊。

感觉计算理论期中还不错。周一被导师叫去公司,让我参加项目,大意是让我写一个TextArea。项目代码有四万左右,光理清这个体系,补windows编程的基础知识就花了我三四天的时间。终于搞明白了什么叫windows ce,什么叫GDI,学会了windows下svn的基本用法。可是看windows ce的书还是一头雾水,什么HINSTANCE,WINAPI WinMain(),叉叉的。基本流程我还不懂。于是去找windows经典书目的书单,看到多人推荐Charles Petzoldwindows程序设计,吐血买了下来,花了150元。Microsoft的书真tn的贵。

不过书是好书。周六周日周一断续看了三天,看了四章,120页,顿时明白了很多。个人windows的技术更新太快,不想unix,二十年前的vim、emacs、grep,等,万古不变。掌握win32 API才是一切的根本。永远不要指望跟上Microsoft的脚步。

只不过到现在导师的项目还没有开工,我还夸下海口自不量力要一周写出来。这可如何是好。还有图形学作业,操作系统作业,实验的作业,呃……少壮不努力,老大做it,大二不学习,大三干苦力。要努力。恩。

BinarySearchTree.h:

#ifndef _BINARYSEARCHTREE_H_
#define _BINARYSEARCHTREE_H_

#include <iostream>
#include <stack>
using namespace std;

/// 三种遍历方式
#define PREORDERTRAVERSE 0
#define INORDERTRAVERSE 1
#define POSTORDERTRAVERSE 2

/// 求两个元素的最大值
#define max(x, y) ((x > y) ? (x) : y)

/**
 * @class BinaryNode
 * @brief 树的结点,为了方便BST和AVL用了同一种结构。BST中所有结点的height域为默认值
 */

template<typename Comparable>
struct BinaryNode
{
    Comparable element;
    BinaryNode* left;
    BinaryNode* right;

    int height;

    BinaryNode(const Comparable &theElement, BinaryNode *lt, BinaryNode *rt, const int theHeight = 0)
        : element(theElement), left(lt), right(rt), height(theHeight) {}
};

/**
 * @class BinarySearchTree
 * @brief 实现了常见的删除,插入功能。并作为AVL树的基类
 */

template<typename Comparable>
class BinarySearchTree
{
public:
    BinarySearchTree();

    ~BinarySearchTree();

    BinaryNode<Comparable>*& GetRoot();
   
    void BuildBinaryTree(Comparable *x, int length);

    const Comparable& FindMin() const;
    const Comparable& FindMax() const;
    bool Contains(const Comparable &x) const;
    bool IsEmpty() const;
    void TraverseTree(int type);

    void MakeEmpty();

    virtual void Insert(const Comparable &x);
    virtual void Remove(const Comparable &x);


private:
    BinaryNode<Comparable> *root;   
    virtual void Insert(const Comparable &x, BinaryNode<Comparable> *&t) const;
    virtual void Remove(const Comparable &x, BinaryNode<Comparable> *&t) const;
    BinaryNode<Comparable>* FindMin(BinaryNode<Comparable> *&t) const;
    BinaryNode<Comparable>* FindMax(BinaryNode<Comparable> *&t) const;
    bool Contains(const Comparable &x, BinaryNode<Comparable> *&t) const;
    void MakeEmpty(BinaryNode<Comparable> *&t);

    void PreOrderTraverse(BinaryNode<Comparable> *&t);
    void InOrderTraverse(BinaryNode<Comparable> *&t);
    void PostOrderTraverse(BinaryNode<Comparable> *&t);
};

/**
 * 构造函数,默认root=NULL
 *
 *
 * @return
 */

template<typename Comparable>
BinarySearchTree<Comparable>::BinarySearchTree() : root(NULL){}

/**
 * 析构函数
 *
 *
 * @return
 */

template<typename Comparable>
BinarySearchTree<Comparable>::~BinarySearchTree()
{
    MakeEmpty();
}

/**
 * 得到根节点的引用
 *
 *
 * @return 返回根节点的引用
 */

template<typename Comparable>
BinaryNode<Comparable>*& BinarySearchTree<Comparable>::GetRoot()
{
    return root;
}

/**
 * 建立BST树,通过数组的方式传入元素,调用Insert(x)函数
 *
 * @param x
 * @param length
 */

template<typename Comparable>
void BinarySearchTree<Comparable>::BuildBinaryTree(Comparable *x, int length)
{
    for (int i = 0; i < length; ++i)
    {
        Insert(x[i]);
    }
}

/**
 * @return BST中的最小值
 */

template<typename Comparable>
const Comparable& BinarySearchTree<Comparable>::FindMin() const
{   
    return FindMin(root)->element;
}

/**
 * @return BST中的最大值
 */

template<typename Comparable>
const Comparable& BinarySearchTree<Comparable>::FindMax() const
{
    return FindMax(root)->element;
}

/**
 * 测试x是否在BST中,调用私有函数Contains(x, root)
 *
 * @param x
 *
 * @return
 */

template<typename Comparable>
bool BinarySearchTree<Comparable>::Contains(const Comparable &x) const
{
    return Contains(x, root);
}

/**
 * 测试树是否为空
 *
 *
 * @return
 */

template<typename Comparable>
bool BinarySearchTree<Comparable>::IsEmpty() const
{
    if (root == NULL)
    {
        return true;
    }

    return false;
}

/**
 * 以三种方式遍历树
 *
 * @param type 遍历树的方式
 */

template<typename Comparable>
void BinarySearchTree<Comparable>::TraverseTree(int type)
{
    if (type == PREORDERTRAVERSE)
    {
        cout << "PreOrderTraverse the tree:" << endl;
        PreOrderTraverse(root);
        cout << endl << "PreOrderTraverse ends." << endl;
    }

    if (type == INORDERTRAVERSE)
    {
        cout << "InOrderTraverse the tree:" << endl;
        InOrderTraverse(root);
        cout << endl << "InOrderTraverse ends." << endl;
    }

    if (type == POSTORDERTRAVERSE)
    {
        cout << "PostOrderTraverse the tree:" << endl;
        PostOrderTraverse(root);
        cout << endl << "InOrderTraverse ends." << endl;
    }
}

/**
 * 清空BST树
 *
 */

template<typename Comparable>
void BinarySearchTree<Comparable>::MakeEmpty()
{
    MakeEmpty(root);
}

/**
 * 向BST中插入一个元素
 *
 * @param x 待插入的元素
 */

template<typename Comparable>
void BinarySearchTree<Comparable>::Insert(const Comparable &x)
{
    Insert(x, root);
}

/**
 * 从BST中删除一个元素
 *
 * @param x 被删除的元素
 */

template<typename Comparable>
void BinarySearchTree<Comparable>::Remove(const Comparable &x)
{
    Remove(x, root);
}

/**
 * 向树根为t的树中插入一个元素
 *
 * @param x 待插入的元素
 * @param t 树根
 */

template<typename Comparable>
void BinarySearchTree<Comparable>::Insert(const Comparable &x, BinaryNode<Comparable> *&t) const
{
    if (t == NULL)
    {
        t = new BinaryNode<Comparable>(x, NULL, NULL, -3);
    }
    else if (x < t->element)
    {
        Insert(x, t->left);
    }
    else if (x > t->element)
    {
        Insert(x, t->right);
    }
    else
        ; //dupicate; you can do something, of course   
}

/**
 * 从树根为t的树中删除元素
 *
 * @param x 被删除的元素
 * @param t 树根
 */

template<typename Comparable>
void BinarySearchTree<Comparable>::Remove(const Comparable &x, BinaryNode<Comparable> *&t) const
{
    if (t == NULL)
    {
        return;
    }
    else if (x < t->element)
    {
        Remove(x, t->left);
    }
    else if (x > t->element)
    {
        Remove(x, t->right);
    }
    else if (t->left != NULL && t->right != NULL)
    {
        t->element = FindMin(t->right)->element;
        Remove(t->element, t->right);
    }
    else
    {
        BinaryNode<Comparable> *oldNode = t;
        t = (t->left != NULL) ? t->left : t->right;
        delete oldNode;
    }
}


template<typename Comparable>
BinaryNode<Comparable>* BinarySearchTree<Comparable>::FindMin(BinaryNode<Comparable> *&t) const
{
    if (t != NULL)
    {
        while(t->left != NULL)
            t = t->left;
    }

    return t;
}

template<typename Comparable>
BinaryNode<Comparable>* BinarySearchTree<Comparable>::FindMax(BinaryNode<Comparable> *&t) const
{
    if (t != NULL)
    {
        while(t->right != NULL)
            t = t->right;
    }

    return t;
}

template<typename Comparable>
bool BinarySearchTree<Comparable>::Contains(const Comparable &x, BinaryNode<Comparable> *&t) const
{
    if (t == NULL)
    {
        return false;
    }
    else if (x < t->element)
    {
        return Contains(x, t->left);
    }
    else if (x > t->element)
    {
        return Contains(x, t->right);
    }
    else
        return true;
}

template<typename Comparable>
void BinarySearchTree<Comparable>::MakeEmpty(BinaryNode<Comparable> *&t)
{
    if (t != NULL)
    {
        MakeEmpty(t->left);
        MakeEmpty(t->right);
        delete t;
    }

    t = NULL;
}

/**
 * 前序遍历
 *
 * @param t
 */

template<typename Comparable>
void BinarySearchTree<Comparable>::PreOrderTraverse(BinaryNode<Comparable> *&t)
{
    if (t != NULL)
    {
        cout << t->element << " ";
        PreOrderTraverse(t->left);
        PreOrderTraverse(t->right);
    }
}

/**
 * 中序遍历
 *
 * @param t
 */

template<typename Comparable>
void BinarySearchTree<Comparable>::InOrderTraverse(BinaryNode<Comparable> *&t)
{
    if (t != NULL)
    {
        InOrderTraverse(t->left);
        cout << t->element << " ";
        InOrderTraverse(t->right);
    }
}

/**
 * 后序遍历
 *
 * @param t
 */


template<typename Comparable>
void BinarySearchTree<Comparable>::PostOrderTraverse(BinaryNode<Comparable> *&t)
{
    if (t != NULL)
    {
        PostOrderTraverse(t->left);
        PostOrderTraverse(t->right);
        cout << t->element << " ";
    }
}

/**
 * @class AVLTree
 * @brief 由于AVLTree本身是一种改进的BST树,所以绝大多数特性继承自BST树。其中的Insert()和Remove方法和BST树中不同,因此在BST类中将此方法声明为virtual function
 */

template<typename Comparable>
class AVLTree : public BinarySearchTree<Comparable>
{
public:
    AVLTree();
    ~AVLTree();
    int GetHeight();
    void Insert(const Comparable &x);
    void Remove(const Comparable &x);
protected:
    int GetHeight(BinaryNode<Comparable> *&t);
    void Insert(const Comparable &x, BinaryNode<Comparable> *&t);
    void Remove(const Comparable &x, BinaryNode<Comparable> *&t);
    void SingleRotateLeftChild(BinaryNode<Comparable> *&k2);
    void SingleRotateRightChild(BinaryNode<Comparable> *&k2);
    void DoubleRotateLeftChild(BinaryNode<Comparable> *&k3);
    void DoubleRotateRightChild(BinaryNode<Comparable> *&k3);
    void Balance(BinaryNode<Comparable> *&t);
};

/**
 * 构造函数,调用BST基类的构造函数
 *
 *
 * @return
 */

template<typename Comparable>
AVLTree<Comparable>::AVLTree() : BinarySearchTree<Comparable>::BinarySearchTree()
{
    //  BinaryNode<Comparable>* root = BinarySearchTree<Comparable>::GetRoot();
//    root = NULL;
}

/**
 * 析构函数,调用基类的BST::MakeEmpty()
 *
 *
 * @return
 */

template<typename Comparable>
AVLTree<Comparable>::~AVLTree()
{
    BinarySearchTree<Comparable>::MakeEmpty();
}

/**
 * 得到整棵AVL树的高度
 *
 *
 * @return
 */

template<typename Comparable>
int AVLTree<Comparable>::GetHeight()
{
    BinaryNode<Comparable>*& root = BinarySearchTree<Comparable>::GetRoot();
    return GetHeight(root);
}

/**
 * 向AVL中插入元素x
 *
 * @param x 待插入的元素
 */

template<typename Comparable>
void AVLTree<Comparable>::Insert(const Comparable &x)
{
    BinaryNode<Comparable>*& root = BinarySearchTree<Comparable>::GetRoot();
    Insert(x, root);
}

/**
 * 从AVL中删除元素x
 *
 * @param x 被删除的元素
 */


template<typename Comparable>
void AVLTree<Comparable>::Remove(const Comparable &x)
{
    BinaryNode<Comparable>*& root = BinarySearchTree<Comparable>::GetRoot();
    Remove(x, root);
}

/**
 * 得到结点t的高度
 *
 * @param t
 *
 * @return
 */

template<typename Comparable>
int AVLTree<Comparable>::GetHeight(BinaryNode<Comparable> *&t)
{
    return t == NULL ? -1 : t->height;
}


template<typename Comparable>
void AVLTree<Comparable>::Insert(const Comparable &x, BinaryNode<Comparable> *&t)
{
    if (t == NULL)
    {
        t = new BinaryNode<Comparable>(x, NULL, NULL);
    }

    else if (x < t->element)
    {
        Insert(x, t->left);
        Balance(t);
        // if (GetHeight(t->left) - GetHeight(t->right) == 2)
        // {
        //     if (x < t->left->element)
        //     {
        //         SingleRotateLeftChild(t);
        //     }
        //     else
        //         DoubleRotateLeftChild(t);
        // }
    }
    else if (x > t->element)
    {
        Insert(x, t->right);
        Balance(t);
        // if (GetHeight(t->right) - GetHeight(t->left) == 2)
        // {
        //     if (t->right->element < x)
        //     {
        //         SingleRotateRightChild(t);
        //     }
        //     else
        //         DoubleRotateRightChild(t);
        // }
    }
    else
        ;
       
    t->height = max(GetHeight(t->left), GetHeight(t->right)) + 1;
}

/**
 * 有个小bug,弄了一天也没弄出来,可能问题在Balance()和指针的引用上
 *
 * @param x
 * @param t
 */

template<typename Comparable>
void AVLTree<Comparable>::Remove(const Comparable &x, BinaryNode<Comparable> *&t)
{
    static stack<BinaryNode<Comparable>*> tStack;/// 定义一个静态堆栈,存储访问结点的路径
    int tSize = tStack.size();/// 得到栈的大小
   
    if (t == NULL)
    {
        return;
    }
    else if (x < t->element)
    {
        tStack.push(t);
        cout << "traverse through " << t->element << endl;
        Remove(x, t->left);
    }
    else if (x > t->element)
    {
        tStack.push(t);
        cout << "traverse through " << t->element << endl;
        Remove(x, t->right);
    }
    else if (t->left != NULL && t->right != NULL)
    {
        tStack.push(t);
        cout << "traverse through " << t->element << endl;
       
        BinaryNode<Comparable>*& oldT = t->right;
       
        while (oldT->left != NULL)
        {
            tStack.push(oldT);
            cout << "traverse through " << oldT->element << endl;
            oldT = oldT->left;
        }

        t->element = oldT->element;
        Remove(t->element, t->right);
    }
    else
    {
        BinaryNode<Comparable>*& oldNode = t;
        t = (t->left != NULL) ? t->left : t->right;
        delete oldNode;
    }

    BinaryNode<Comparable>* tempStack;

    tSize = tStack.size(); /// 更新堆栈大小

   
    for (int i = 0; i < tSize; i++)
    {
        tempStack = tStack.top();/// 回溯访问结点
        Balance(tempStack);/// 对每个结点做Balance处理
        tStack.pop();/// 已经做过Balance处理的结点出栈
    }/// 此处可以进一步优化
    return ;   
}


template<typename Comparable>
void AVLTree<Comparable>::SingleRotateLeftChild(BinaryNode<Comparable> *&k2)
{
    BinaryNode<Comparable> *k1 = k2->left;
    k2->left = k1->right;
    k1->right = k2;
    k2->height = max(GetHeight(k2->left), GetHeight(k2->right)) + 1;
    k1->height = max(GetHeight(k1->left), k2->height) + 1;
    k2 = k1;
}

template<typename Comparable>
void AVLTree<Comparable>::SingleRotateRightChild(BinaryNode<Comparable> *&k1)
{
    BinaryNode<Comparable> *k2 = k1->right;
    k1->right = k2->left;
    k2->left = k1;
    k1->height = max(GetHeight(k1->left), GetHeight(k1->right)) + 1;
    k2->height = max(k1->height, GetHeight(k2->right)) + 1;
    k1 = k2;
}

template<typename Comparable>
void AVLTree<Comparable>::DoubleRotateLeftChild(BinaryNode<Comparable> *&k3)
{
    SingleRotateRightChild(k3->left);
    SingleRotateLeftChild(k3);
}

template<typename Comparable>
void AVLTree<Comparable>::DoubleRotateRightChild(BinaryNode<Comparable> *&k1)
{
    SingleRotateLeftChild(k1->right);
    SingleRotateRightChild(k1);
}

/**
 * 计算t的平衡因子,分为四种不同情况分别调用不同函数处理
 *
 * @param t 树根
 */

template<typename Comparable>
void AVLTree<Comparable>::Balance(BinaryNode<Comparable> *&t)
{
    if (GetHeight(t->left) - GetHeight(t->right) == 2)
    {
        if (GetHeight(t->left->left) > GetHeight(t->left->right))
        {
            SingleRotateLeftChild(t);
        }
        else if (GetHeight(t->left->left) < GetHeight(t->left->right))
        {
            DoubleRotateLeftChild(t);
        }
        else
            ;       
    }

    if (GetHeight(t->left) - GetHeight(t->right) == -2)
    {
        if (GetHeight(t->right->right) > GetHeight(t->right->left))
        {
            SingleRotateRightChild(t);
        }
        else if (GetHeight(t->right->right) < GetHeight(t->right->left))
        {
            DoubleRotateRightChild(t);
        }
        else
            ;
    }
}

#endif /* _BINARYSEARCHTREE_H_ */
 

main.cpp:

#include <iostream>
#include "BinarySearchTree.h"

using namespace std;

int main(int argc, char *argv[])
{
    int a[10] = {5, 9, 10, 1, 3, 6, 4, 7, 8, 2};

    AVLTree<int> avl;
    avl.BuildBinaryTree(a, 10);
    avl.Insert(11);
    avl.TraverseTree(0);

    avl.Remove(9);
    avl.TraverseTree(0);

    avl.Remove(10);
    avl.TraverseTree(0);
   
    return 0;
}




Host by is-Programmer.com | Power by Chito 1.3.3 beta | © 2007 LinuxGem | Design by Matthew "Agent Spork" McGee