AVL树的实现(源码)

原创 2004年01月13日 10:09:00

AVLTree

http://www.staroceans.com/AVLTree.htm

This is first edition of my AVL Tree and I never expect it takes so long as almost one week to finish! Of course
it is partly because of Christmas when I was continually interrupt by the earthly issues such as visiting a 
friend and wasting some meaningful time on meaningless matters. 
C.The idea of program
 

By adding a little piece of code in "insert" method of BST, I actually try to do the keeping-balance

job along the "insert" operation from bottom-up which always keep each node up-to-date balanced. It

is believed by me the best solution to implement it. Unfortunately I have to keep the clue of the

path which leads to the newly-inserted node at leaf position. So, I was obliged to add one more

field in node---"inLeft" which is a boolean value indicating which side the path goes down to the

new leaf. Along with it is the "height" data which is the absolute height of a subtree rooted as

current node. I thought it is a cheating in pseudo code by using "balancing-factor" as instead of

using "real height" of each node. But after finishing the program with several big changes, I

realized I might do some stupid things on assuming that absolute height is necessary. Maybe in

second edition I should combine both "inLeft" and "height" together with "factor"----balancing

factor.

 
 
// 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);
	}

};
 
// 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
}
 
 
// 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;
};
 
//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;}
};
 
#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;
	}
}


//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;	
}
 
#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;
}
 
===================insert number 53
53
===================insert number 79
53
  79
===================insert number 46
  46
53
  79
===================insert number 12
    12
  46
53
  79
===================insert number 81
    12
  46
53
  79
    81
===================insert number 36
    12
  36
    46
53
  79
    81
===================insert number 90
    12
  36
    46
53
    79
  81
    90
===================insert number 70
    12
  36
    46
53
      70
    79
  81
    90
===================insert number 74
    12
  36
    46
53
      70
    74
      79
  81
    90
===================insert number 76
    12
  36
    46
53
      70
    74
      76
  79
    81
      90
===================insert number 17
    12
      17
  36
    46
53
      70
    74
      76
  79
    81
      90
===================insert number 57
    12
      17
  36
    46
53
        57
      70
    74
      76
  79
    81
      90
===================insert number 93
    12
      17
  36
    46
53
        57
      70
    74
      76
  79
      81
    90
      93
===================insert number 39
    12
      17
  36
      39
    46
53
        57
      70
    74
      76
  79
      81
    90
      93
===================insert number 73
    12
      17
  36
      39
    46
53
        57
      70
        73
    74
      76
  79
      81
    90
      93
===================insert number 103
    12
      17
  36
      39
    46
53
        57
      70
        73
    74
      76
  79
      81
    90
      93
        103
===================insert number 107
    12
      17
  36
      39
    46
53
        57
      70
        73
    74
      76
  79
      81
    90
        93
      103
        107
===================insert number 54
    12
      17
  36
      39
    46
53
        54
      57
    70
        73
      74
        76
  79
      81
    90
        93
      103
        107
===================insert number 39
    12
      17
  36
      39
    39
      46
53
        54
      57
    70
        73
      74
        76
  79
      81
    90
        93
      103
        107
===================insert number 48
    12
      17
  36
      39
    39
      46
        48
53
        54
      57
    70
        73
      74
        76
  79
      81
    90
        93
      103
        107
Press any key to continue
 
	

                                 back.gif (341 bytes)       up.gif (335 bytes)         next.gif (337 bytes)

 

AVL树及C语言实现

概念   平衡二叉树(Balanced binary tree)是由苏联数学家Adelson-Velskii and Landis于1962年首先提出的,所以又称为AVL树。 定义:平衡二叉树或...
  • IT_PCode
  • IT_PCode
  • 2014年03月28日 23:34
  • 1868

AVL树的旋转图解和简单实现

AVL树是带有平衡条件的查找二叉树。这个平衡条件要容易保持,而且他要保证树的深度为O(logN)原文地址:http://blog.csdn.net/qq_25806863/article/detail...
  • qq_25806863
  • qq_25806863
  • 2017年07月07日 18:03
  • 481

自己动手实现数据结构——AVL树(C++实现)

这类教程有很多了,就用C++简单实现下以供记录和参考,以后再有补充版本。 实现了查找和插入、删除操作有些复杂,感觉个人实现的效率不是很高,以后再补充,先把做过的东西记录下来。 Avl.h #ifn...
  • sshhiixx
  • sshhiixx
  • 2015年08月10日 13:06
  • 1438

AVL树的java实现

AVL树的定义自己百度去,这里给出自己用java的一个实现。 package test; /** * @时间 2014-3-30 * @version 0.1 * @encode UTF-8...
  • dahlwuyn
  • dahlwuyn
  • 2014年03月31日 16:07
  • 4353

C++模板实现的AVL树

1 AVL树的定义 AVL树是一种自平衡二叉排序树,它的特点是任何一个节点的左子树高度和右子树的高度差在-1,0,1三者之间。AVL树的任何一个子树都是AVL树。 2 AVL树的实现 AVL树本质是一...
  • zhuhuangtianzi
  • zhuhuangtianzi
  • 2014年11月03日 18:40
  • 1002

AVL树实现与分析

AVL是高度平的二叉搜索树,它能降低二叉树的高度,减少树的平均搜索长度
  • he_shuai20
  • he_shuai20
  • 2017年04月27日 23:50
  • 868

平衡二叉搜索树(AVL树)的原理及实现源代码(有图文详解和C++、Java实现代码)

这几天学习了AVL树(平衡二叉搜索树),遂写一篇总结与大家分享。包括五个部分: 一、AVL树(平衡二叉搜索树)是什么? 二、为什么要用AVL树? 三、AVL树的实现原理 四、完整的实现代码(C++和J...
  • u013149325
  • u013149325
  • 2014年11月22日 21:46
  • 1714

AVL树原理通俗解释与例子

AVL(Adelson-Velskii and Landis)树是带有平衡条件(balance condition)的二叉查找树。 这个平衡条件必须容易保持,而且必须保证树的深度是O(logN)。 A...
  • songzige
  • songzige
  • 2016年04月21日 16:37
  • 1003

AVL树的C++实现 Implement of AVL tree

AVL是一种自平衡的二叉查找树。 不同于普通的二叉查找树之处在于:每个节点的左右子树高度差最多为1,故每个节点多了一个高度(height)属性。 其实现难点在于插入和删除时要检测节点高度差是否满足上述...
  • showonstage1
  • showonstage1
  • 2014年03月31日 22:51
  • 1440

Avl树的基本操作(c语言实现)

#include #include typedef struct AvlNode *Position; typedef struct AvlNode *AvlTree; typedef int El...
  • Stephen_Curry_
  • Stephen_Curry_
  • 2016年03月17日 16:42
  • 1259
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:AVL树的实现(源码)
举报原因:
原因补充:

(最多只允许输入30个字)