資料結構學習(c++)——二叉樹 (轉)

gugu99發表於2007-08-15
資料結構學習(c++)——二叉樹 (轉)[@more@]

注:本文只是對學習清華殷人昆《資料結構(用面向方法與c++描述)》的人有些微幫助,其他人就沒有必要浪費時間看了。因為老實說這本書裡的程式碼實現的確不怎麼樣。

我的目的,就是努力實現和書裡的程式碼相同的介面,盡最大可能和原始碼一摸一樣。因為這樣的話,一則自己以後看起來比較方便,只要對著課本翻翻就行了;二則這樣可能對別的學這本書的人有一定的好處。由於自己的習慣,我在原書的類名前加了_。

/*
  Name: _BinaryTree.h
  Copyright:
  Author: elmar
  Date: 19-07-03 23:43
  Description:
*/

#ifndef _BinaryTree_H
#define _BinaryTree_H

#include
#include   //用於Insert中的層次遍歷
using namespace std;

template class _BinaryTree;
template class _BinTreeNode
{
  friend class _BinaryTree;
 
  public:
  _BinTreeNode():data(Type()), leftChild(NULL), rightChild(NULL){}
  _BinTreeNode(Type item,
  _BinTreeNode* left = NULL,
  _BinTreeNode* right = NULL);
  _BinTreeNode(const _BinTreeNode& b){*this = b;}
  Type GetData() const {return data;}
  _BinTreeNode* GetLeft() const {return leftChild;}
  _BinTreeNode* GetRight() const {return rightChild;}
  void SetData(const Type& item) {data = item;}
  void SetLeft(_BinTreeNode* L) {leftChild = L;}
  void SetRight(_BinTreeNode* R) {rightChild = R;}
  _BinTreeNode& operator = (const _BinTreeNode& b);
 
  private:
  _BinTreeNode *leftChild, *rightChild;
  Type data;
};

template class _BinaryTree
{
  public:
  _BinaryTree(): (NULL){}
  _BinaryTree(Type value): RefValue(value), root(NULL){}
  _BinaryTree(const _BinaryTree& bt);
  virtual ~_BinaryTree(){destroy(root);}
  virtual bool IsEmpty() {return root == NULL ? true : false;}
  virtual _BinTreeNode* Parent(_BinTreeNode* current)
  {return root == NULL || root == current ? NULL : Parent(root, current);}
  virtual _BinTreeNode* LeftChild(_BinTreeNode* current)
  {return root != NULL ? current->leftChild : NULL;}
  virtual _BinTreeNode* RightChild(_BinTreeNode* current)
  {return root != NULL ? current->rightChild : NULL;}
  virtual int Insert(const Type& item){return Insert(root, item);}
//  virtual int Find(const Type& item) const;
  const _BinTreeNode* GetRoot() const {return root;}
  _BinaryTree& operator = (const _BinaryTree&);
  _BinaryTree& operator += (const _BinaryTree& bt){return Append(bt);}
  friend istream& operator >> (istream& in, _BinaryTree& Tree)
  {
  Type item;
  cout << "Construct binary tree: " << endl;
  cout << "Input data (end with " << Tree.RefValue <  in >> item;
  while (item != Tree.RefValue)
  {
  Tree.Insert(item);
  cout << "Input data (end with " << Tree.RefValue <  in >> item;
  }
  return in;
  } 
 
  friend ostream& operator << (ostream& out, _BinaryTree& Tree)
  {
  out << "Preorder traversal of binary tree." << endl;
  Tree.Traverse(Tree.root, out);
  out << endl;
  return out;
  } 
 
  private:
  _BinTreeNode* root;  //二叉數的根指標
  Type RefValue;  //資料輸入停止的標誌
 
  _BinTreeNode* Parent(_BinTreeNode* start, _BinTreeNode* current);
  int Insert(_BinTreeNode*& current, const Type& item); //操作成功返回0,否則-1
  void Traverse(_BinTreeNode* current, ostream& out) const; //輸出根為current的二叉樹
//  int Find(_BinTreeNode* current, const Type& item) const;
  void destroy(_BinTreeNode* current);
  _BinaryTree& Append(const _BinaryTree& bt);  //為elmar所加的。把二叉樹bt加到當前樹上
};

template _BinTreeNode::_BinTreeNode(Type item,
  _BinTreeNode* left,
  _BinTreeNode* right)
{
  data = item;
  leftChild = left;
  rightChild = right;
}

template _BinTreeNode& _BinTreeNode::operator = (const _BinTreeNode& b)
{
  leftChild = b.leftChild; rightChild = b.rightChild; data = b.data;
  return *this;
}

template _BinaryTree::_BinaryTree(const _BinaryTree& bt)
{
  root = NULL;
  RefValue = bt.RefValue;
  Append(bt);
}

template void _BinaryTree::destroy(_BinTreeNode* current)
{
  if (current !=NULL)
  {
  destroy(current->leftChild);
  destroy(current->rightChild);
  delete current;
  }
}

template _BinTreeNode*
_BinaryTree::Parent(_BinTreeNode* start, _BinTreeNode* current)
{
  if (start == NULL) return NULL;
  if (start->leftChild == current || start->rightChild == current) return start;
  _BinTreeNode* p;
  if ((p = Parent(start->leftChild, current)) != NULL) return p;
  else return Parent(start->rightChild, current);
}

template void
_BinaryTree::Traverse(_BinTreeNode* current, ostream& out) const
{
  if (current != NULL)
  {
  out << current->data << ;
  Traverse(current->leftChild, out);
  Traverse(current->rightChild, out);
  }
}

//層次遍歷以current為根的二叉樹,把item插入在第一個葉子的的左指標,
//或第一個缺右孩子的節點的右指標
template int
_BinaryTree::Insert(_BinTreeNode*& current, const Type& item)
{
  _BinTreeNode* p = new _BinTreeNode(item);
  if (p == NULL) return -1;
 
  if (current == NULL)
  {
  current = p;
  return 0;
  }
  else
  {
  deque<_bintreenode>*>* deck = new deque<_bintreenode>*>;//佇列
  deck->push_back(current);
 
  typename deque<_bintreenode>*>::const_iterator iter;
  while (true)
  {
  iter = deck->begin();
  deck->pop_front();
  if ((*iter)->leftChild == NULL)
  {
  (*iter)->leftChild = p;
  delete deck;
  return 0;
  }
  else if ((*iter)->rightChild == NULL)
  {
  (*iter)->rightChild = p;
  delete deck;
  return 0;
  }
  else
  {
  deck->push_back((*iter)->leftChild);
  deck->push_back((*iter)->rightChild);
  }
  }
 
  }
}

template _BinaryTree& _BinaryTree::Append(const _BinaryTree& bt)
{
  deque<_bintreenode>*>* deck = new deque<_bintreenode>*>;
  deck->push_back(bt.root);

  typename deque<_bintreenode>*>::const_iterator iter;
  while (!deck->empty())
  {
  iter = deck->begin();
  deck->pop_front();
  this->Insert((*iter)->GetData());
 
  if ((*iter)->leftChild != NULL)
  {
  deck->push_back((*iter)->leftChild);
  }
  if ((*iter)->rightChild != NULL)
  {
  deck->push_back((*iter)->rightChild);
  }

  }//while
 
  delete deck;
  return *this;
}

template _BinaryTree& _BinaryTree::operator = (const _BinaryTree& bt)
{
  RefValue = bt.RefValue;
  if (bt.root == NULL) return *this;
 
  if (!this->IsEmpty())this->destroy(root);
 
  return this->Append(bt);
}

#endif


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10748419/viewspace-959478/,如需轉載,請註明出處,否則將追究法律責任。

相關文章