90分求c++描述的AVL树数据结构实现!

broadarms 2005-12-01 12:32:58
如题
请帮个忙。
可以贴在下面,也可以发给我fun@njnc.edu.cn
thanks
...全文
409 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
rrqq 2006-03-10
  • 打赏
  • 举报
回复
北大张铭的最新的数据结构好像有的
javalin3012 2006-01-23
  • 打赏
  • 举报
回复
怎么C++实现的代码比JAVA实现的还多?
爱摸鱼de老邪 2006-01-21
  • 打赏
  • 举报
回复
晕,看样子分数诱惑还真是大。
programfanny 2006-01-20
  • 打赏
  • 举报
回复
厉害,很厉害啊
jack1219 2006-01-15
  • 打赏
  • 举报
回复
抄的很厉害啊
yelling 2005-12-04
  • 打赏
  • 举报
回复
发完了
yelling 2005-12-04
  • 打赏
  • 举报
回复
file name: AVLTree.cpp (main)

#include <iostream>
#include <time.h>
#include "AVLTree.h"
#include "Elem.h"


using namespace std;

int main()
{
int num;
AVL<int, int, KEComp, EEComp> A;
//srand(time(0));
for (int i=0; i<25; i++)
{
cout<<"===================";
num=rand()%100+12;
cout<<"insert number "<<num<<endl;
A.insert(num);
A.print();
}
return 0;
}

 
yelling 2005-12-04
  • 打赏
  • 举报
回复
//if isRoot, we don't need isLeft, it is useful when it is not root and
//we need to know which son it is in
template <class Key, class Elem, class KEComp, class EEComp>
BinNode<Elem>* AVL<Key, Elem, KEComp, EEComp>::singleRotate(BinNode<Elem>* parent,
bool isRoot, bool left2right)
{
BinNode<Elem>* oldRoot=parent, *son, *t1;
bool isLeft=((AVLNodePtr<Elem>*)parent)->getSide();

if (isRoot)
{
son=parent->getSon(isLeft);
t1=son->getSon(!left2right);
son->setSon(parent, !left2right);
parent->setSon(t1, left2right);
//because parent is at lower level now, we need adjust parent first!!!
adjustHeight(parent);//sequence is VERY IMPORTANT!
adjustHeight(son);//sequence is VERY IMPORTANT!

root=son;
return son;//because now, we need return son as parent;
}
else
{
//for non-root rotation, parent doesn't change!!!!!
//it is now very concise!!
oldRoot=parent->getSon(isLeft);
son=oldRoot->getSon(left2right);//this is the trick!
t1=son->getSon(!left2right);
parent->setSon(son, isLeft);
oldRoot->setSon(t1, left2right);
son->setSon(oldRoot, !left2right);
//sequence is very important!!!
adjustHeight(oldRoot);
adjustHeight(son);
adjustHeight(parent);//adjust sequence: from low to high!!!
return parent;
}

}

//check the direction of rotation by returning value in reference
template<class Key, class Elem, class KEComp, class EEComp>
void AVL<Key, Elem, KEComp, EEComp>::checkDir(BinNode<Elem>* subroot,
bool& isSingle, bool& left2right)
{
BinNode<Elem>* son;
int parentFactor, sonFactor;
bool isLeft;
isLeft=((AVLNodePtr<Elem>*)subroot)->getSide();
son=subroot->getSon(isLeft);
parentFactor=getFactor(subroot);
sonFactor=getFactor(son);
isSingle=parentFactor*sonFactor>0;//same sign
left2right=parentFactor>0;
}

//if isroot, isLeft will be ignored.
template <class Key, class Elem, class KEComp, class EEComp>
void AVL<Key, Elem, KEComp, EEComp>::adjust(BinNode<Elem>*& subroot, bool isRoot)
{
BinNode<Elem>* temp;
bool isSingle, left2right, isLeft;
if (isRoot)
{
temp=subroot;
}
else
{
//use its son to check
isLeft=((AVLNodePtr<Elem>*)subroot)->getSide();
temp=subroot->getSon(isLeft);
}

checkDir(temp, isSingle, left2right);
if (isSingle)
{
//it helps reading and for singleRotate isLeft is ignored when it is isRoot
subroot=singleRotate(subroot, isRoot, left2right);
}
else
{
subroot=doubleRotate(subroot, isRoot, left2right);
}
}


template <class Key, class Elem, class KEComp, class EEComp>
int AVL<Key, Elem, KEComp, EEComp>::getFactor(BinNode<Elem>* subroot)
{
int lHeight, rHeight;
AVLNodePtr<Elem>* ptr, *l, *r;
if (subroot==NULL)
{
return 0;
}
ptr=(AVLNodePtr<Elem>*)subroot;
l=(AVLNodePtr<Elem>*)(ptr->left());
r=(AVLNodePtr<Elem>*)(ptr->right());
if (l==NULL)
{
lHeight=0;
}
else
{
lHeight= l->getHeight();
}
if (r==NULL)
{
rHeight=0;
}
else
{
rHeight=r->getHeight();
}
return lHeight-rHeight;
}

template <class Key, class Elem, class KEComp, class EEComp>
void AVL<Key, Elem, KEComp, EEComp>::updateHeight(BinNode<Elem>*& subroot)
{
int factor, sonFactor;
bool isLeft;
BinNode<Elem> *son;
if (subroot==NULL)
{
return;
}

adjustHeight(subroot);

factor=getFactor(subroot);

isLeft=((AVLNodePtr<Elem>*)subroot)->getSide();
son=subroot->getSon(isLeft);
sonFactor=getFactor(son);
//first situation: the first 2/-2 we meet from bottom-up
if ((factor==2||factor==-2)&&subroot==root)
{
//a special case!!! as we search from bottom up
//we may wait to adjust until we reach its father
//the father happens to be root. But it is not a
//root adjustment!!!
if (sonFactor==1||sonFactor==-1)
{
adjust(subroot, true);
}
else
{
adjust(subroot, false);
}
}
else
{

if (sonFactor==2||sonFactor==-2)
{
adjust(subroot, false);
}
}
}




template <class Key, class Elem, class KEComp, class EEComp>
BinNode<Elem>* AVL<Key, Elem, KEComp, EEComp>::inserthelp(BinNode<Elem>* subroot,
const Elem& val)
{
if (subroot == NULL) // Empty tree: create node
{
return (new AVLNodePtr<Elem>(val, NULL, NULL, 1));
}
if (EEComp::lt(val, subroot->val())) // Insert on left
{
((AVLNodePtr<Elem>*)subroot)->setSide(true);
subroot->setLeft(inserthelp(subroot->left(), val));
updateHeight(subroot);
}
else
{
((AVLNodePtr<Elem>*)subroot)->setSide(false);
subroot->setRight(inserthelp(subroot->right(), val));
updateHeight(subroot);
}
return subroot; // Return subtree with node inserted
}


template <class Key, class Elem, class KEComp, class EEComp>
void AVL<Key, Elem, KEComp, EEComp>::clearhelp(BinNode<Elem>* subroot)
{
if (subroot == NULL)
{
return;
}
clearhelp(subroot->left());
clearhelp(subroot->right());
delete subroot;
}
Kid4you 2005-12-04
  • 打赏
  • 举报
回复
...
yelling 2005-12-04
  • 打赏
  • 举报
回复
file name: AVLTree.h
#include "BST.h"

template<class Elem>
struct Descriptor
{
BinNode<Elem>* parent;
bool isRoot;
bool isLeft;
bool isSingle;
bool left2right;
};


template<class Key, class Elem, class KEComp, class EEComp>
class AVL: public BST<Key, Elem, KEComp, EEComp>
{
protected:
// BinNode<Elem>* startPtr;
void clearhelp(BinNode<Elem>*);
BinNode<Elem>* inserthelp(BinNode<Elem>*, const Elem&);
BinNode<Elem>* removehelp(BinNode<Elem>*, const Key&,
BinNode<Elem>*&);
bool findhelp(BinNode<Elem>*, const Key&, Elem&) const;
void printhelp(BinNode<Elem>*, int) const;
void updateHeight(BinNode<Elem>*& subroot);
int getFactor(BinNode<Elem>* subroot);
void adjust(BinNode<Elem>*& subroot, bool isRoot);
int getTreeHeight(BinNode<Elem>* subroot);
void adjustHeight(BinNode<Elem>* subroot);
BinNode<Elem>* singleRotate(BinNode<Elem>* parent, bool isRoot, bool left2right);
BinNode<Elem>* doubleRotate(BinNode<Elem>* parent, bool isRoot, bool left2right);
void checkDir(BinNode<Elem>* subroot, bool& isSingle, bool& left2right);
BinNode<Elem>* doDouble(BinNode<Elem>* oldRoot, bool left2right);

public:
AVL() { root = NULL; nodecount = 0; } // Constructor
~AVL() { clearhelp(root); root=NULL; } // Destructor
bool insert(const Elem& e)
{
root = inserthelp(root, e);
nodecount++;
return true;
}
};

//do not use recursive!!!!!
template <class Key, class Elem, class KEComp, class EEComp>
int AVL<Key, Elem, KEComp, EEComp>::getTreeHeight(BinNode<Elem>* subroot)
{
AVLNodePtr<Elem>* ptr, *l, *r;
int newHeight, lHeight, rHeight;//, factor;//, sonFactor;

if (subroot==NULL)
{
return 0;
}

ptr=(AVLNodePtr<Elem>*)subroot;
l=(AVLNodePtr<Elem>*)ptr->left();
r=(AVLNodePtr<Elem>*)ptr->right();
if (l==NULL)
{
lHeight=0;
}
else
{
lHeight=l->getHeight();
}
if (r==NULL)
{
rHeight=0;
}
else
{
rHeight=r->getHeight();
}
newHeight=1+(lHeight>rHeight?lHeight:rHeight);
return newHeight;
}

template <class Key, class Elem, class KEComp, class EEComp>
void AVL<Key, Elem, KEComp, EEComp>::adjustHeight(BinNode<Elem>* subroot)
{
int height;
if (subroot==NULL)
{
return;
}
height=getTreeHeight(subroot);
((AVLNodePtr<Elem>*)(subroot))->setHeight(height);
}

template <class Key, class Elem, class KEComp, class EEComp>
BinNode<Elem>* AVL<Key, Elem, KEComp, EEComp>::doDouble(BinNode<Elem>* oldRoot,
bool left2right)
{
BinNode<Elem> *small, *mid, *big,*t1,*t2,*t3,*t4;
if (left2right)
{
big=oldRoot;//the root;
small=oldRoot->left();
mid=small->right();
t1=small->left();
t2=mid->left();
t3=mid->right();
t4=big->right();
}
else
{
small=oldRoot;
big=small->right();
mid=big->left();
t1=small->left();
t2=mid->left();
t3=mid->right();
t4=big->right();
}
mid->setLeft(small);
mid->setRight(big);
small->setLeft(t1);
small->setRight(t2);
big->setLeft(t3);
big->setRight(t4);
adjustHeight(small);
adjustHeight(big);
adjustHeight(mid);
return mid;
}

template <class Key, class Elem, class KEComp, class EEComp>
BinNode<Elem>* AVL<Key, Elem, KEComp, EEComp>::doubleRotate(BinNode<Elem>* parent,
bool isRoot, bool left2right)
{
BinNode<Elem>* oldRoot;
bool isLeft;

if (isRoot)
{
oldRoot=parent;
root=doDouble(oldRoot, left2right);

return root;//because we need parent return as real root
}
else
{
isLeft=((AVLNodePtr<Elem>*)parent)->getSide();
oldRoot=parent->getSon(isLeft);
parent->setSon(doDouble(oldRoot, left2right), isLeft);
adjustHeight(parent);
return parent;
}
}


yelling 2005-12-04
  • 打赏
  • 举报
回复
file name: BST.h
// This file includes all of the pieces of the BST implementation

#include "dictionary.h"

#include "binnode.h"

// Binary Search Tree implementation for the Dictionary ADT
template <class Key, class Elem, class KEComp, class EEComp>
class BST : public Dictionary<Key, Elem, KEComp, EEComp> {
protected:
BinNode<Elem>* root; // Root of the BST
int nodecount; // Number of nodes in the BST
// Private "helper" functions
void clearhelp(BinNode<Elem>*);
BinNode<Elem>* inserthelp(BinNode<Elem>*, const Elem&);
BinNode<Elem>* deletemin(BinNode<Elem>*, BinNode<Elem>*&);
BinNode<Elem>* removehelp(BinNode<Elem>*, const Key&,
BinNode<Elem>*&);
bool findhelp(BinNode<Elem>*, const Key&, Elem&) const;
void printhelp(BinNode<Elem>*, int) const;
public:
BST() { root = NULL; nodecount = 0; } // Constructor
~BST() { clearhelp(root); } // Destructor
void clear()
{ clearhelp(root); root = NULL; nodecount = 0; }
bool insert(const Elem& e) {
root = inserthelp(root, e);
nodecount++;
return true;
}
bool remove(const Key& K, Elem& e) {
BinNode<Elem>* t = NULL;
root = removehelp(root, K, t);
if (t == NULL) return false; // Nothing found
e = t->val();
nodecount--;
delete t;
return true;
}
bool removeAny(Elem& e) { // Delete min value
if (root == NULL) return false; // Empty tree
BinNode<Elem>* t;
root = deletemin(root, t);
e = t->val();
delete t;
nodecount--;
return true;
}
bool find(const Key& K, Elem& e) const
{ return findhelp(root, K, e); }
int size() { return nodecount; }
void print() const {
if (root == NULL) cout << "The BST is empty.\n";
else printhelp(root, 0);
}
};

template <class Key, class Elem, class KEComp, class EEComp>
void BST<Key, Elem, KEComp, EEComp>::
clearhelp(BinNode<Elem>* subroot) {
if (subroot == NULL) return;
clearhelp(subroot->left());
clearhelp(subroot->right());
delete subroot;
}

template <class Key, class Elem, class KEComp, class EEComp>
BinNode<Elem>* BST<Key, Elem, KEComp, EEComp>::
inserthelp(BinNode<Elem>* subroot, const Elem& val) {
if (subroot == NULL) // Empty tree: create node
return (new BinNodePtr<Elem>(val, NULL, NULL));
if (EEComp::lt(val, subroot->val())) // Insert on left
subroot->setLeft(inserthelp(subroot->left(), val));
else subroot->setRight(inserthelp(subroot->right(), val));
return subroot; // Return subtree with node inserted
}

template <class Key, class Elem, class KEComp, class EEComp>
BinNode<Elem>* BST<Key, Elem, KEComp, EEComp>::
deletemin(BinNode<Elem>* subroot, BinNode<Elem>*& min) {
if (subroot->left() == NULL) { // Found min
min = subroot;
return subroot->right();
}
else { // Continue left
subroot->setLeft(deletemin(subroot->left(), min));
return subroot;
}
}

template <class Key, class Elem, class KEComp, class EEComp>
BinNode<Elem>* BST<Key, Elem, KEComp, EEComp>::
removehelp(BinNode<Elem>* subroot, const Key& K,
BinNode<Elem>*& t) {
if (subroot == NULL) return NULL; // Val is not in tree
else if (KEComp::lt(K, subroot->val())) // Check left
subroot->setLeft(removehelp(subroot->left(), K, t));
else if (KEComp::gt(K, subroot->val())) // Check right
subroot->setRight(removehelp(subroot->right(), K, t));
else { // Found it: remove it
BinNode<Elem>* temp;
t = subroot;
if (subroot->left() == NULL) // Only a right child
subroot = subroot->right(); // so point to right
else if (subroot->right() == NULL) // Only a left child
subroot = subroot->left(); // so point to left
else { // Both children are non-empty
subroot->setRight(deletemin(subroot->right(), temp));
Elem te = subroot->val();
subroot->setVal(temp->val());
temp->setVal(te);
t = temp;
}
}
return subroot;
}

template <class Key, class Elem, class KEComp, class EEComp>
bool BST<Key, Elem, KEComp, EEComp>:: findhelp(
BinNode<Elem>* subroot, const Key& K, Elem& e) const {
if (subroot == NULL) return false; // Empty tree
else if (KEComp::lt(K, subroot->val())) // Check left
return findhelp(subroot->left(), K, e);
else if (KEComp::gt(K, subroot->val())) // Check right
return findhelp(subroot->right(), K, e);
else { e = subroot->val(); return true; } // Found it
}

template <class Key, class Elem, class KEComp, class EEComp>
void BST<Key, Elem, KEComp, EEComp>::
printhelp(BinNode<Elem>* subroot, int level) const {
if (subroot == NULL) return; // Empty tree
printhelp(subroot->left(), level+1); // Do left subtree
for (int i=0; i<level; i++) // Indent to level
cout << " ";
cout << subroot->val() << "\n"; // Print node value
printhelp(subroot->right(), level+1); // Do right subtree
}

 
file name: dictionary.h
 
// The Dictionary abstract class. KEComp compares a key
// and an element. EEComp compares two elements.
template <class Key, class Elem, class KEComp, class EEComp>
class Dictionary {
public:
// Reinitialize dictionary
virtual void clear() = 0;
// Insert an element. Return true if insert is
// successful, false otherwise.
virtual bool insert(const Elem&) = 0;
// Remove some element matching Key. Return true if such
// exists, false otherwise. If multiple entries match
// Key, an arbitrary one is removed.
virtual bool remove(const Key&, Elem&) = 0;
// Remove and return an arbitrary element from dictionary.
// Return true if some element is found, false otherwise.
virtual bool removeAny(Elem&) = 0;
// Return a copy of some Elem matching Key. Return true
// if such exists, false otherwise. If multiple elements
// match Key, return an arbitrary one.
virtual bool find(const Key&, Elem&) const = 0;
// Return the number of elements in the dictionary.
virtual int size() = 0;
};

 
file name: Elem.h
//This is the element of login system

class KEComp
{
public:
static bool lt(int key, int elem) {return key<elem;}
static bool eq(int key, int elem) {return key==elem;}
static bool gt(int key, int elem) {return key>elem;}
};

class EEComp
{
public:
static bool lt(int e1, int e2)
{ return e1<e2;}
static bool eq(int e1, int e2)
{ return e1==e2;}
static bool gt(int e1, int e2)
{ return e1>e2;}
};
yelling 2005-12-04
  • 打赏
  • 举报
回复
file name: BinNode.h
// Binary tree node abstract class
template <class Elem> class BinNode {
public:
// Return the node's element
virtual Elem& val() = 0;
// Set the node's element
virtual void setVal(const Elem&) = 0;
// Return the node's left child
virtual BinNode* left() const = 0;
// Set the node's left child
virtual void setLeft(BinNode*) = 0;
// Return the node's right child
virtual BinNode* right() const = 0;
// Set the node's right child
virtual void setRight(BinNode*) = 0;
// Return true iff the node is a leaf
virtual bool isLeaf() = 0;
//my personal preference
virtual BinNode<Elem>* getSon(bool isLeft)const=0;
//my personal preference
virtual void setSon(BinNode<Elem>* son, bool isLeft)=0;
};

// Binary tree node class
template <class Elem>
class BinNodePtr : public BinNode<Elem> {
private:
Elem it; // The node's value
BinNodePtr* lc; // Pointer to left child
BinNodePtr* rc; // Pointer to right child
public:
// Two constructors -- with and without initial values
BinNodePtr() { lc = rc = NULL; }
BinNodePtr(Elem e, BinNodePtr* l =NULL,
BinNodePtr* r =NULL)
{ it = e; lc = l; rc = r; }
~BinNodePtr() {} // Destructor
Elem& val() { return it; }
void setVal(const Elem& e) { it = e; }
inline BinNode<Elem>* left() const { return lc; }
void setLeft(BinNode<Elem>* b) { lc = (BinNodePtr*)b; }
inline BinNode<Elem>* right() const { return rc; }
void setRight(BinNode<Elem>* b) { rc = (BinNodePtr*)b; }
bool isLeaf() { return (lc == NULL) && (rc == NULL); }
BinNode<Elem>* getSon(bool isLeft)const {return isLeft?lc:rc;}
void setSon(BinNode<Elem>* son, bool isLeft)
{
isLeft?setLeft(son):setRight(son);
}
};


template <class Elem>
class AVLNodePtr : public BinNode<Elem>
{
protected:
Elem it; // The node's value
AVLNodePtr* lc; // Pointer to left child
AVLNodePtr* rc; // Pointer to right child
int height;
bool inLeft;
public:
// Two constructors -- with and without initial values
AVLNodePtr() { lc = rc = NULL; height=1; inLeft=true; }
AVLNodePtr(Elem e, AVLNodePtr<Elem>* l =NULL,
AVLNodePtr<Elem>* r =NULL, int newHeight=1)
{ it = e; lc = l; rc = r; height=newHeight; inLeft=true;}
~AVLNodePtr() {} // Destructor
Elem& val() { return it; }
void setVal(const Elem& e) { it = e; }
BinNode<Elem>* left() const { return lc; }
void setLeft(BinNode<Elem>* b) { lc = (AVLNodePtr*)b; }
inline BinNode<Elem>* right() const { return rc; }
void setRight(BinNode<Elem>* b) { rc = (AVLNodePtr*)b; }
bool isLeaf() { return (lc == NULL) && (rc == NULL); }
void setHeight(int newHeight){height=newHeight;}
int getHeight(){return height;}
BinNode<Elem>* getSon(bool isLeft)const {return isLeft?lc:rc;}
bool getSide() const {return inLeft;}
void setSide(bool isLeft){ inLeft=isLeft;}
void setSon(BinNode<Elem>* son, bool isLeft)
{
isLeft?setLeft(son):setRight(son);
}

};

33,010

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧