Реализация АВЛ-дерева

Реализация АВЛ-дерева

Ниже предложены возможная программная реализация АВЛ-дерева.


Код класса на Object Pascal.

unit mAVLTree;
 
interface
 
type
 
  TAVLTree = class;
 
  TAVLTreeNode = class (TObject)
  private
    FKey: Cardinal;
    FData: TObject;
 
    FBalance,
    FLeftBalance,
    FRightBalance: Byte;
 
    FLeft,
    FRight,
    FParent: TAVLTreeNode;
 
    FOwner: TAVLTree;
 
    procedure RefreshBalance;
  public
    constructor Create(AOwner: TAVLTree; AKey: Cardinal; AData: TObject; AParent: TAVLTreeNode);
    destructor Destroy; override;
 
    function GetNext(AKey: Cardinal): TAVLTreeNode;
 
    property Key: Cardinal read FKey write FKey;
    property Data: TObject read FData write FData;
 
    property Parent: TAVLTreeNode read FParent write FParent;
    property Left: TAVLTreeNode read FLeft write FLeft;
    property Right: TAVLTreeNode read FRight write FRight;
 
    property Balance: Byte read FBalance;
    property LeftBalance: Byte read FLeftBalance;
    property RightBalance: Byte read FRightBalance;
  end;
 
  TAVLTree = class (TObject)
  private
    FRoot: TAVLTreeNode;
    FOwnedObjects: Boolean;
    procedure Balance(const ANode: TAVLTreeNode);
  public
    constructor Create(AOwnedObjects: Boolean);
    destructor Destroy; override;
 
    function IsEmpty: Boolean;
    function FindData(AKey: Cardinal): Pointer;
    function FindNode(AKey: Cardinal): TAVLTreeNode;
    function FindOrInsert(AKey: Cardinal; AData: TObject): TAVLTreeNode;
    function Delete(AKey: Cardinal): Boolean;
    procedure Clear;
 
    property Root: TAVLTreeNode read FRoot write FRoot;
  end;
 
implementation
 
uses SysUtils;
 
{ TAVLTreeNode }
 
procedure TAVLTreeNode.RefreshBalance;
begin
  if Assigned(Left) then
    FLeftBalance := Left.Balance
  else
    FLeftBalance := 0;
 
  if Assigned(Right) then
    FRightBalance := Right.Balance
  else
    FRightBalance := 0;
 
  if RightBalance > LeftBalance then
    FBalance := RightBalance + 1
  else
    FBalance := LeftBalance + 1;
end;
 
constructor TAVLTreeNode.Create(AOwner: TAVLTree; AKey: Cardinal; AData: TObject; AParent: TAVLTreeNode);
begin
  inherited Create;
 
  FKey := AKey;
  FData := AData;
  Parent := AParent;
  FBalance := 1;
  FOwner := AOwner;
end;
 
destructor TAVLTreeNode.Destroy;
begin
  if FOwner.FOwnedObjects then
    FreeAndNil(FData);
 
  inherited;  
end;
 
function TAVLTreeNode.GetNext(AKey: Cardinal): TAVLTreeNode;
begin
  if Key > AKey then
    Result := Left
  else
    Result := Right;
end;
 
{ TAVLTree }
 
procedure TAVLTree.Balance(const ANode: TAVLTreeNode);
var
  NodeA,
  NodeB,
  NodeC,
  CurrentNode: TAVLTreeNode;
begin
  CurrentNode := ANode;
 
  while Assigned(CurrentNode) do
  begin
    CurrentNode.RefreshBalance;
 
    if Abs(CurrentNode.LeftBalance - CurrentNode.RightBalance) <= 1 then
      CurrentNode := CurrentNode.Parent
    else
      if CurrentNode.RightBalance > CurrentNode.LeftBalance then
      begin
        if CurrentNode.Right.LeftBalance > CurrentNode.Right.RightBalance then
        begin
          NodeA := CurrentNode;
          NodeB := NodeA.Right;
          NodeC := NodeB.Left;
          NodeC.Parent := NodeA.Parent;
 
          if Assigned(NodeC.Parent) then
            if NodeC.Parent.Right = NodeA then
              NodeC.Parent.Right := NodeC
            else
              NodeC.Parent.Left := NodeC;
 
          NodeA.Parent := NodeC;
          NodeB.Parent := NodeC;
          NodeA.Right := NodeC.Left;
          if Assigned(NodeA.Right) then
            NodeA.Right.Parent := NodeA;
 
          NodeC.Left := NodeA;
          NodeB.Left := NodeC.Right;
          if Assigned(NodeB.Left) then
            NodeB.Left.Parent := NodeB;
 
          NodeC.Right := NodeB;
 
          NodeA.RefreshBalance;
          NodeB.RefreshBalance;
          NodeC.RefreshBalance;
 
          if Root = NodeA then
            Root := NodeC;
 
          CurrentNode := NodeC.Parent;
        end
        else
        begin
          NodeA := CurrentNode;
          NodeB := NodeA.Right;
          NodeB.Parent := NodeA.Parent;
 
          if Assigned(NodeB.Parent) then
            if NodeB.Parent.Right = NodeA then
              NodeB.Parent.Right := NodeB
            else
              NodeB.Parent.Left := NodeB;
 
          NodeA.Parent := NodeB;
          NodeA.Right := NodeB.Left;
 
          if Assigned(NodeA.Right) then
            NodeA.Right.Parent := NodeA;
 
          NodeB.Left := NodeA;
 
          NodeA.RefreshBalance;
          NodeB.RefreshBalance;
 
          if Root = NodeA then
            Root := NodeB;
 
          CurrentNode := NodeB.Parent;
        end
      end
      else
      begin
        if CurrentNode.Left.RightBalance>CurrentNode.Left.LeftBalance then
        begin
          NodeA := CurrentNode;
          NodeB := NodeA.Left;
          NodeC := NodeB.Right;
          NodeC.Parent := NodeA.Parent;
          if Assigned(NodeC.Parent) then
            if NodeC.Parent.Right = NodeA then
              NodeC.Parent.Right := NodeC
            else
              NodeC.Parent.Left := NodeC;
 
          NodeA.Parent := NodeC;
          NodeB.Parent := NodeC;
          NodeA.Left := NodeC.Right;
          if Assigned(NodeA.Left) then
              NodeA.Left.Parent := NodeA;
 
          NodeC.Right := NodeA;
          NodeB.Right := NodeC.Left;
          if Assigned(NodeB.Right) then
            NodeB.Right.Parent := NodeB;
          NodeC.Left:=NodeB;
 
          NodeA.RefreshBalance;
          NodeB.RefreshBalance;
          NodeC.RefreshBalance;
 
          if Root = NodeA then
            Root := NodeC;
 
          CurrentNode := NodeC.Parent;
        end
        else
        begin
          NodeA := CurrentNode;
          NodeB := NodeA.Left;
          NodeB.Parent := NodeA.Parent;
          if Assigned(NodeB.Parent) then
            if NodeB.Parent.Right = NodeA then
            NodeB.Parent.Right := NodeB
          else
            NodeB.Parent.Left := NodeB;
 
          NodeA.Parent := NodeB;
          NodeA.Left := NodeB.Right;
 
          if Assigned(NodeA.Left) then
            NodeA.Left.Parent := NodeA;
 
          NodeB.Right := NodeA;
 
          NodeA.RefreshBalance;
          NodeB.RefreshBalance;
 
         if Root = NodeA then
           Root := NodeB;
          CurrentNode:=NodeB.Parent;
        end
      end;
  end;
end;
 
constructor TAVLTree.Create(AOwnedObjects: Boolean);
begin
  inherited Create;
 
  FOwnedObjects := AOwnedObjects;
end;
 
destructor TAVLTree.Destroy;
begin
  Clear;
 
  inherited;
end;
 
function TAVLTree.IsEmpty: Boolean;
begin
  Result := not Assigned(Root);
end;
 
function TAVLTree.FindData(AKey: Cardinal): Pointer;
var
  Node: TAVLTreeNode;
begin
  Node := FindNode(AKey);
 
  if Assigned(Node) then
    Result := Node.Data
  else
    Result := nil;
end;
 
function TAVLTree.FindNode(AKey: Cardinal): TAVLTreeNode;
begin
  Result := Root;
 
  while Assigned(Result) and (Result.Key <> AKey) do
    Result := Result.GetNext(AKey);
end;
 
function TAVLTree.FindOrInsert(AKey: Cardinal; AData: TObject): TAVLTreeNode;
var
  ParentNode,
  NewNode: TAVLTreeNode;
begin
  Result := Root;
 
  if Assigned(Result) then
  begin
    ParentNode := nil;
    Result := Root;
 
    while Assigned(Result) and (Result.Key <> Akey) do
    begin
      ParentNode := Result;
      Result := Result.GetNext(AKey);
    end;
 
    if Assigned(Result) then Exit;
 
    NewNode := TAVLTreeNode.Create(Self, AKey, AData, ParentNode);
 
    if ParentNode.Key > NewNode.Key then
      ParentNode.Left := NewNode
    else
      ParentNode.Right := NewNode;
 
    Balance(ParentNode);
  end
  else
  begin
    Root := TAVLTreeNode.Create(Self, AKey, AData, nil);
  end;
end;
 
function TAVLTree.Delete(AKey: Cardinal): Boolean;
var
  CurrentNode,
  NodeA,
  NodeB: TAVLTreeNode;
begin
  CurrentNode := FindNode(AKey);
 
  Result := Assigned(CurrentNode);
 
  if Result then
  begin
    if CurrentNode.LeftBalance > CurrentNode.RightBalance then
    begin
      NodeA := CurrentNode.Left;
 
      while Assigned(NodeA.Right) do
        NodeA := NodeA.Right;
 
      NodeB := NodeA.Parent;
 
      if NodeB = CurrentNode then
      begin
        CurrentNode.Left := NodeA.Left;
        if Assigned(CurrentNode.Left) then
          CurrentNode.Left.Parent := CurrentNode;
      end
      else
      begin
        NodeB.Right := NodeA.Left;
        if Assigned(NodeB.Right) then
          NodeB.Right.Parent := NodeB;
      end;
 
      CurrentNode.Key := NodeA.Key;
      CurrentNode.Data := NodeA.Data;
      FreeAndNil(NodeA);
 
      Balance(NodeB);
    end
    else if CurrentNode.RightBalance > 0 then
    begin
      NodeA := CurrentNode.Right;
 
      while Assigned(NodeA.Left) do
        NodeA := NodeA.Left;
 
      NodeB := NodeA.Parent;
 
      if NodeB = CurrentNode then
      begin
        CurrentNode.Right := NodeA.Right;
        if Assigned(CurrentNode.Right) then
          CurrentNode.Right.Parent := CurrentNode;
      end
      else
      begin
        NodeB.Left:=NodeA.Right;
        if Assigned(NodeB.Left) then
          NodeB.Left.Parent := NodeB;
      end;
 
      CurrentNode.Key := NodeA.Key;
      CurrentNode.Data := NodeA.Data;
 
      FreeAndNil(NodeA);
 
      Balance(NodeB);
    end
    else
    begin
      if not Assigned(CurrentNode.Parent) then
        Root := nil
      else
        if (CurrentNode.Parent.Left = CurrentNode) then
          CurrentNode.Parent.Left := nil
        else
          CurrentNode.Parent.Right := nil ;
 
      {Parent of Current Node is Not Balanced ,so}
      Balance(CurrentNode.Parent);
 
      FreeAndNil(CurrentNode);
    end;
  end;
end;
 
procedure TAVLTree.Clear;
 
  procedure _Clear_R(ANode: TAVLTreeNode);
  begin
    if not Assigned(ANode) then Exit;
 
    if Assigned(ANode.Left) then begin
      _Clear_R(ANode.Left);
    end;
 
    if Assigned(ANode.Right) then begin
      _Clear_R(ANode.Right);
    end;
 
    FreeAndNil(ANode);
  end;
 
begin
  _Clear_R(FRoot);
end;
 
 
end.


Код класса на C++.

using std::swap;
using std::max;
 
template <typename KEY_T, typename DATA_T>
class TreeMap{
	struct Node{
		KEY_T Key;
		DATA_T Data;
		Node* LeftChild;
		Node* RightChild;
		int Balance;
		Node(const KEY_T InKey, DATA_T InData);
		~Node();
		Node* GetNodeByKey(const KEY_T& InKey);
		void DeleteBranch();
		int Add(const KEY_T& InKey, const DATA_T& InData);
		int Delete(const KEY_T& InKey, Node* Parent=NULL);
		void DeleteLeaf(Node* Parent);
		size_t Count();
		Node* Leftest();
		Node* Rightest();
		void Swap(Node* Another);
		void Rebalance();
		void RotateLeft();
		void RotateRight();
		void DoubleRotateLeft();
		void DoubleRotateRight();
		int Height();
		void Check();
	};
	Node* Root;
public:
	class Iterator{
		Node* CurrentNode;
		TreeMap* CurrentTree;
		List<Node*> Stack;
		void SetBad();
		void GoLeft();
		void GoRight();
	public:
		friend class TreeMap<KEY_T, DATA_T>;
		Iterator(const Iterator& InIterator);
		Iterator(TreeMap& InTreeMap, bool IsBegin=true);
		operator bool();
		Iterator& operator++();
		Iterator& operator--();
		Iterator operator++(int);
		Iterator operator--(int);
		Iterator& operator+=(size_t n);
		Iterator& operator-=(size_t n);
		Iterator& operator=(const Iterator& InIterator);
		Iterator& operator=(const KEY_T& InKey);
		DATA_T& operator*();
		void Delete();
		void Add(const KEY_T& InKey, const DATA_T& InData);
	};
	TreeMap();
	~TreeMap();
	Iterator GetBegin();
	Iterator GetEnd();
	void Add(const KEY_T& InKey, const DATA_T& InData);
	void Delete(const KEY_T& InKey);
	DATA_T& operator[](const KEY_T& InKey);
	size_t Count();
	void Clear();
	Iterator Find(const DATA_T& Unknown);
	void CheckIntegrity();
};
 
template <typename KEY_T, typename DATA_T>
TreeMap<KEY_T, DATA_T>::Node::Node(const KEY_T InKey, DATA_T InData):Key(InKey), Data(InData), LeftChild(NULL), RightChild(NULL), Balance(0){
}
 
template <typename KEY_T, typename DATA_T>
TreeMap<KEY_T, DATA_T>::Node::~Node(){
}
 
template <typename KEY_T, typename DATA_T>
void TreeMap<KEY_T, DATA_T>::Node::DeleteLeaf(TreeMap<KEY_T, DATA_T>::Node* Parent){
	if(Parent->LeftChild==this)
		Parent->LeftChild=NULL;
	else
		Parent->RightChild=NULL;
	delete this;
}
 
 
template <typename KEY_T, typename DATA_T>
typename TreeMap<KEY_T, DATA_T>::Node* TreeMap<KEY_T, DATA_T>::Node::GetNodeByKey(const KEY_T& InKey){
	if(InKey==Key)
		return this;
	else if(InKey>Key && RightChild)
		return RightChild->GetNodeByKey(InKey);
	else if(LeftChild)
		return LeftChild->GetNodeByKey(InKey);
	throw String("No node for this key!");
}
 
template <typename KEY_T, typename DATA_T>
size_t TreeMap<KEY_T, DATA_T>::Node::Count(){
	size_t Counter=1;
	if(RightChild)
		Counter+=RightChild->Count();
	if(LeftChild)
		Counter+=LeftChild->Count();
	return Counter;
}
 
template <typename KEY_T, typename DATA_T>
int TreeMap<KEY_T, DATA_T>::Node::Add(const KEY_T& InKey, const DATA_T& InData){
	if(InKey==Key)
		throw String("Not unique key!");
	int OldBalance=Balance;
	if(InKey>Key)
		if(RightChild){
			Balance+=RightChild->Add(InKey, InData);
			Rebalance();
		}else{
			RightChild=new Node(InKey, InData);
			Balance++;
		}
	else
		if(LeftChild){
			Balance-=LeftChild->Add(InKey, InData);
			Rebalance();
		}else{
			LeftChild=new Node(InKey, InData);
			Balance--;
		}
	if(Balance!=OldBalance)
		return (Balance!=0);
	return 0;
}
 
template <typename KEY_T, typename DATA_T>
void TreeMap<KEY_T, DATA_T>::Node::Swap(TreeMap<KEY_T, DATA_T>::Node* Another){
	swap(Key, Another->Key);
	swap(Data, Another->Data);
}
 
template <typename KEY_T, typename DATA_T>
typename TreeMap<KEY_T, DATA_T>::Node* TreeMap<KEY_T, DATA_T>::Node::Leftest(){
	Node* CurrentNode=this;
	while(CurrentNode->LeftChild)
		CurrentNode=CurrentNode->LeftChild;
	return CurrentNode;
}
 
template <typename KEY_T, typename DATA_T>
typename TreeMap<KEY_T, DATA_T>::Node* TreeMap<KEY_T, DATA_T>::Node::Rightest(){
	Node* CurrentNode=this;
	while(CurrentNode->RightChild)
		CurrentNode=CurrentNode->RightChild;
	return CurrentNode;
}
 
template <typename KEY_T, typename DATA_T>
int TreeMap<KEY_T, DATA_T>::Node::Delete(const KEY_T& InKey, TreeMap<KEY_T, DATA_T>::Node* Parent){
	int OldBalance=Balance;
	if(InKey==Key){
		if(!RightChild && !LeftChild){
			DeleteLeaf(Parent);
			return 1;
		}else 
			if(Balance>=0){
				Swap(RightChild->Leftest());
				Balance-=RightChild->Delete(InKey, this);
			}else{
				Swap(LeftChild->Rightest());
				Balance+=LeftChild->Delete(InKey, this);
			}
	}else if(InKey>Key)
		if(RightChild){
			Balance-=RightChild->Delete(InKey, this);
			Rebalance();
		}else
			throw String("There is no node for this key!");
	else
		if(LeftChild){
			Balance+=LeftChild->Delete(InKey, this);
			Rebalance();
		}else
			throw String("There is no node for this key!");
	if(Balance!=OldBalance)
		return (Balance==0);
	return 0;
}
 
template <typename KEY_T, typename DATA_T>
void TreeMap<KEY_T, DATA_T>::Node::Rebalance(){
	if(Balance==2)
		if(RightChild->Balance>=0)
			RotateRight();
		else
			DoubleRotateRight();
	else if(Balance==-2)
		if(LeftChild->Balance<=0)
			RotateLeft();
		else
			DoubleRotateLeft();
}
 
template <typename KEY_T, typename DATA_T>
void TreeMap<KEY_T, DATA_T>::Node::RotateRight(){
	Swap(RightChild);
	Node* R=RightChild->RightChild;
	RightChild->RightChild=RightChild->LeftChild;
	RightChild->LeftChild=LeftChild;
	LeftChild=RightChild;
	RightChild=R;
	Balance=LeftChild->Balance-1;
	LeftChild->Balance=1-LeftChild->Balance;
}
 
template <typename KEY_T, typename DATA_T>
void TreeMap<KEY_T, DATA_T>::Node::DoubleRotateRight(){
	Swap(RightChild->LeftChild);
	Node* N=RightChild->LeftChild->RightChild;
	RightChild->LeftChild->RightChild=RightChild->LeftChild->LeftChild;
	RightChild->LeftChild->LeftChild=LeftChild;
	LeftChild=RightChild->LeftChild;
	RightChild->LeftChild=N;
	Balance=0;
	RightChild->Balance=(LeftChild->Balance==-1);
	LeftChild->Balance=-(LeftChild->Balance==1);
}
 
template <typename KEY_T, typename DATA_T>
void TreeMap<KEY_T, DATA_T>::Node::RotateLeft(){
	Swap(LeftChild);
	Node* L=LeftChild->LeftChild;
	LeftChild->LeftChild=LeftChild->RightChild;
	LeftChild->RightChild=RightChild;
	RightChild=LeftChild;
	LeftChild=L;
	Balance=1+RightChild->Balance;
	RightChild->Balance=-1-RightChild->Balance;
}
 
template <typename KEY_T, typename DATA_T>
void TreeMap<KEY_T, DATA_T>::Node::DoubleRotateLeft(){
	Swap(LeftChild->RightChild);
	Node* M=LeftChild->RightChild->LeftChild;
	LeftChild->RightChild->LeftChild=LeftChild->RightChild->RightChild;
	LeftChild->RightChild->RightChild=RightChild;
	RightChild=LeftChild->RightChild;
	LeftChild->RightChild=M;
	Balance=0;
	LeftChild->Balance=-(RightChild->Balance==1);
	RightChild->Balance=(RightChild->Balance==-1);
}
 
template <typename KEY_T, typename DATA_T>
TreeMap<KEY_T, DATA_T>::TreeMap(): Root(NULL){}
 
template <typename KEY_T, typename DATA_T>
TreeMap<KEY_T, DATA_T>::~TreeMap(){
	Clear();
}
 
template <typename KEY_T, typename DATA_T>
typename TreeMap<KEY_T, DATA_T>::Iterator TreeMap<KEY_T, DATA_T>::GetBegin(){
	return Iterator(*this);
}
 
template <typename KEY_T, typename DATA_T>
typename TreeMap<KEY_T, DATA_T>::Iterator TreeMap<KEY_T, DATA_T>::GetEnd(){
	return Iterator(*this, false);
}
 
template <typename KEY_T, typename DATA_T>
size_t TreeMap<KEY_T, DATA_T>::Count(){
	if(!Root)
		return 0;
	return Root->Count();
}
 
template <typename KEY_T, typename DATA_T>
void TreeMap<KEY_T, DATA_T>::Clear(){
	if(!Root)
		return;
	Root->DeleteBranch();
	Root=NULL;
}
 
template <typename KEY_T, typename DATA_T>
void TreeMap<KEY_T, DATA_T>::Node::DeleteBranch(){
	if(LeftChild)
		LeftChild->DeleteBranch();
	if(RightChild)
		RightChild->DeleteBranch();
	delete this;
}
 
template <typename KEY_T, typename DATA_T>
void TreeMap<KEY_T, DATA_T>::Iterator::SetBad(){
	CurrentNode=NULL;
	Stack.Clear();
}
 
template <typename KEY_T, typename DATA_T>
void TreeMap<KEY_T, DATA_T>::Iterator::GoLeft(){
	while(CurrentNode && CurrentNode->LeftChild){
		Stack.AddLast(CurrentNode);
		CurrentNode=CurrentNode->LeftChild;
	}
}
 
template <typename KEY_T, typename DATA_T>
void TreeMap<KEY_T, DATA_T>::Iterator::GoRight(){
	while(CurrentNode && CurrentNode->RightChild){
		Stack.AddLast(CurrentNode);
		CurrentNode=CurrentNode->RightChild;
	}
}
 
template <typename KEY_T, typename DATA_T>
typename TreeMap<KEY_T, DATA_T>::Iterator TreeMap<KEY_T, DATA_T>::Find(const DATA_T& Unknown){
	Iterator r(*this);
	for(; r; ++r)
		if(*r==Unknown)
			return r;
	r.SetBad();
	return r;
}
 
template <typename KEY_T, typename DATA_T>
TreeMap<KEY_T, DATA_T>::Iterator::Iterator(const TreeMap<KEY_T, DATA_T>::Iterator& InIterator){
	operator=(InIterator);
}
 
template <typename KEY_T, typename DATA_T>
TreeMap<KEY_T, DATA_T>::Iterator::Iterator(TreeMap<KEY_T, DATA_T>& InTreeMap, bool IsBegin):CurrentNode(InTreeMap.Root), CurrentTree(&InTreeMap){
	if(IsBegin)
		GoLeft();
	else
		GoRight();
}
 
template <typename KEY_T, typename DATA_T>
TreeMap<KEY_T, DATA_T>::Iterator::operator bool(){
	return CurrentNode!=NULL;
}
 
template <typename KEY_T, typename DATA_T>
typename TreeMap<KEY_T, DATA_T>::Iterator& TreeMap<KEY_T, DATA_T>::Iterator::operator++(){
	if(!CurrentNode)
		return *this;
	if(CurrentNode->RightChild){
		Stack.AddLast(CurrentNode);
		CurrentNode=CurrentNode->RightChild;
		GoLeft();
		return *this;
	}
	if(Stack.Count()==0){
		SetBad();
		return *this;
	}
	typename List<Node*>::Iterator i=Stack.GetEnd();
	if((*i)->LeftChild==CurrentNode){
		CurrentNode=*i;
		Stack.DeleteLast();
		return *this;
	}
	while(CurrentNode==(*i)->RightChild){
		CurrentNode=*i--;
		Stack.DeleteLast();
		if(Stack.Count()==0){
			SetBad();
			return *this;
		}
	}
	CurrentNode=*i;
	Stack.DeleteLast();
	return *this;
}
 
template <typename KEY_T, typename DATA_T>
typename TreeMap<KEY_T, DATA_T>::Iterator& TreeMap<KEY_T, DATA_T>::Iterator::operator--(){
	if(!CurrentNode)
		return *this;
	if(CurrentNode->LeftChild){
		Stack.AddLast(CurrentNode);
		CurrentNode=CurrentNode->LeftChild;
		GoRight();
		return *this;
	}
	if(Stack.Count()==0){
		SetBad();
		return *this;
	}
	typename List<Node*>::Iterator i=Stack.GetEnd();
	if((*i)->RightChild==CurrentNode){
		CurrentNode=*i;
		Stack.DeleteLast();
		return *this;
	}
	while(CurrentNode==(*i)->LeftChild){
		CurrentNode=*i--;
		Stack.DeleteLast();
		if(Stack.Count()==0){
			SetBad();
			return *this;
		}
	}
	CurrentNode=*i;
	Stack.DeleteLast();
	return *this;
}
 
template <typename KEY_T, typename DATA_T>
typename TreeMap<KEY_T, DATA_T>::Iterator TreeMap<KEY_T, DATA_T>::Iterator::operator++(int){
	Iterator Old(*this);
	++*this;
	return Old;
}
 
template <typename KEY_T, typename DATA_T>
typename TreeMap<KEY_T, DATA_T>::Iterator TreeMap<KEY_T, DATA_T>::Iterator::operator--(int){
	Iterator Old(*this);
	--*this;
	return Old;
}
 
template <typename KEY_T, typename DATA_T>
typename TreeMap<KEY_T, DATA_T>::Iterator& TreeMap<KEY_T, DATA_T>::Iterator::operator+=(size_t n){
	for(; n; n--)
		(*this)++;
	return *this;
}
 
template <typename KEY_T, typename DATA_T>
typename TreeMap<KEY_T, DATA_T>::Iterator& TreeMap<KEY_T, DATA_T>::Iterator::operator-=(size_t n){
	for(; n; n--)
		(*this)--;
	return *this;
}
 
template <typename KEY_T, typename DATA_T>
typename TreeMap<KEY_T, DATA_T>::Iterator& TreeMap<KEY_T, DATA_T>::Iterator::operator=(const TreeMap<KEY_T, DATA_T>::Iterator& InIterator){
	CurrentNode=InIterator.CurrentNode;
	CurrentTree=InIterator.CurrentTree;
	for(typename List<Node*>::Iterator i((List<Node*>&)InIterator.Stack); i; ++i)
		Stack.AddLast(*i);
	return *this;
}
 
template <typename KEY_T, typename DATA_T>
typename TreeMap<KEY_T, DATA_T>::Iterator& TreeMap<KEY_T, DATA_T>::Iterator::operator=(const KEY_T& InKey){
	CurrentNode=CurrentTree->Root->GetNodeByKey(InKey);
	return *this;
}
 
template <typename KEY_T, typename DATA_T>
DATA_T& TreeMap<KEY_T, DATA_T>::Iterator::operator*(){
	if(!(*this))
		throw String("Reading from bad iterator!");
	return CurrentNode->Data;
}
 
template <typename KEY_T, typename DATA_T>
void TreeMap<KEY_T, DATA_T>::Iterator::Delete(){
	if(!(*this))
		throw String("Delete from bad iterator. Nothing to delete!");
	CurrentTree->Delete(CurrentNode->Key);
}
 
template <typename KEY_T, typename DATA_T>
void TreeMap<KEY_T, DATA_T>::Add(const KEY_T& InKey, const DATA_T& InData){
	if(!Root)
		Root=new Node(InKey, InData);
	else
		Root->Add(InKey, InData);
}
 
template <typename KEY_T, typename DATA_T>
void TreeMap<KEY_T, DATA_T>::Delete(const KEY_T& InKey){
	if(Root->Key==InKey && !Root->LeftChild && !Root->RightChild){
		delete Root;
		Root=NULL;
	}else
		Root->Delete(InKey);
}
 
template <typename KEY_T, typename DATA_T>
DATA_T& TreeMap<KEY_T, DATA_T>::operator[](const KEY_T& InKey){
	if(!Root)
		throw String("Tree is empty!");
	Node* ReturnValue=Root->GetNodeByKey(InKey);
	return ReturnValue->Data;
}
 
// необязательный код для тестирования целостности дерева
template <typename KEY_T, typename DATA_T>
void TreeMap<KEY_T, DATA_T>::CheckIntegrity(){
	Root->Check();
}
 
template <typename KEY_T, typename DATA_T>
void TreeMap<KEY_T, DATA_T>::Node::Check(){
	if(!this)
		return; 
	if(Balance!=RightChild->Height()-LeftChild->Height())
		throw String("Mistake in balance integrity!");
	if(Balance<-1 || Balance>1)
		throw String("Tree is unbalanced!");
}
 
template <typename KEY_T, typename DATA_T>
int TreeMap<KEY_T, DATA_T>::Node::Height(){
	if (this==NULL)
		return 0;
	return max(RightChild->Height(), LeftChild->Height())+1;
}

Wikimedia Foundation. 2010.

Игры ⚽ Поможем написать реферат

Полезное


Смотреть что такое "Реализация АВЛ-дерева" в других словарях:

  • АВЛ-дерево — Эта статья или раздел нуждается в переработке. Пожалуйста, улучшите статью в соответствии с правилами написания статей. АВЛ дерево сбалансированное по в …   Википедия

  • Сбалансированное дерево поиска — АВЛ дерево сбалансированное по высоте двоичное дерево поиска: для каждой его вершины высота её двух поддеревьев различается не более чем на 1. АВЛ деревья названы по первым буквам фамилий их изобретателей, Г. М. Адельсона Вельского и Е. М.… …   Википедия

  • Красно-чёрное дерево — Тип дерево поиска Изобретено в 1972 году Изобретено Рудольф Байер Временная сложность в О символике В среднем В худшем случае Расход памяти O(n) O(n) Поиск O(log n) O(log n) Вставка O(log n) O(log n) Удаление O(log n) O(log n) Красно чёрное… …   Википедия

  • Декартово дерево — Декартово дерево  это двоичное дерево, в узлах которого хранятся: ссылки на правое и левое поддерево; ссылка на родительский узел (необязательно); ключи и , которые являются двоичным деревом поиска по ключу и двоичной кучей по ключу ; а… …   Википедия

  • Префиксное дерево — Префиксное дерево  абстрактный тип данных (АТД), структура данных, позволяющая хранить ассоциативный массив, ключами которого являются строки. В отличие от б …   Википедия

  • Дерево Фенвика — (двоичное индексированное дерево, англ. Fenwick tree, binary indexed tree, BIT) структура данных, позволяющая быстро изменять значения в массиве и находить некоторые функции от элементов массива. Впервые описано Питером Фенвиком в 1994 году …   Википедия

  • Красно-черное дерево — Красно чёрное дерево Красно чёрное дерево (Red Black Tree, RB Tree) это одно из самобалансирующихся двоичных деревьев поиска, гарантирующих логарифмический рост высоты дерева от числа узлов и быстро выполняющее основные операции дерева поиска:… …   Википедия

  • Суффиксное дерево — Суффиксное дерево  бор, содержащий все суффиксы некоторой строки (и только их). Позволяет выяснять, входит ли строка w в исходную строку t, за время O(|w|), где |w|  длина строки w. Содержание 1 Основные определения и описание структуры …   Википедия

  • Дерево отрезков — структура данных, позволяющая быстро изменять значения в массиве и находить некоторые функции от элементов массива. Содержание 1 Дерево отрезков в памяти …   Википедия

  • B-дерево — Тип Дерево Изобретено в 1972 году Изобретено Rudolf Bayer, Edward M. McCreight Временная сложность в О символике В среднем В худшем случае Расход памяти O(n) O(n) Поиск O(log n) O(log n) Вставка O(log n) O(log n) Удаление O(log n) O(log n) …   Википедия


Поделиться ссылкой на выделенное

Прямая ссылка:
Нажмите правой клавишей мыши и выберите «Копировать ссылку»