C++练习6-1:二叉树

一次贴代码太多,先贴二叉树的类定义头文件和实现文件:
//tree.h
#include <iostream>
#include <cstdlib>
#include <cassert>
#include <exception>
#include <stdexcept>
#include <vector>
#include <algorithm>

#define NODE_NUMBER 100
#define FOUR_SPACE 4
#define MIDDLE_SCREEN 60
#define LEFT_CHILD  10
#define RIGHT_CHILD 20
using namespace std;
typedef int  T;

typedef struct btree_node
{
  btree_node *left,*right;
  int level;
  int screen_x;
  T value;
}BTREE_NODE;

class CBinaryTree{
  public:
    CBinaryTree(T array[],int size);
    BTREE_NODE *GetTreeRoot(void);
    void TraversePreOrder(BTREE_NODE *r);
    void TraverseByMiddleOrder(BTREE_NODE *r);
    void TraverseByBehindOrder(BTREE_NODE *r);
    int TreeDepth(BTREE_NODE *r);
    int GetElementLayer(T element);  
    void PrintTree(void);    
    ~CBinaryTree(void);

  protected:
    BTREE_NODE * _InsertByLocation(BTREE_NODE *r,
               BTREE_NODE *new_node);
    void _OutPutValue(T value);
    void _MiddleOrderAdd(BTREE_NODE *r, vector<BTREE_NODE> *coll);
    int _GetElementLayer(T element);
    void _SetLayerForEachNode(BTREE_NODE *pTmp, 
                int layer);
    void _SetPositionForEachNode(BTREE_NODE *pTmp, 
          int layer ,int wide);
    int _CalculateDigitalBits(T value);
    void _PrintLeftChildValue(vector<BTREE_NODE>::iterator pos, 
                              int wide);
    void _PrintRightChildValue(vector<BTREE_NODE>::iterator pos, 
                              int wide);
    void _PrintStartSpace(vector<BTREE_NODE> *last, 
                           vector<BTREE_NODE> *now);
    int _DetectNextNodePosition(vector<BTREE_NODE>::iterator pos_now, 
                             vector<BTREE_NODE> *now);
    int _DetectNextNodeType(vector<BTREE_NODE>::iterator pos_last, 
                          vector<BTREE_NODE>*last);
    void _PrintCurrentLayerNode(vector<BTREE_NODE> *last, vector<BTREE_NODE> *now, int wide);
    int _CalculateTreeWide(vector<BTREE_NODE> *coll, int depth);
    inline void _PrintSpace(int number);  
    int _RemoveRepeat(T *array, int len);  
    
  private:
    BTREE_NODE *pMemStart;
    BTREE_NODE *TreeRoot; 
};
//tree.cpp
#include "tree.h"
#include <iostream>
#include <cstdlib>
#include <cassert>
#include <exception>
#include <stdexcept>
#include <algorithm>
#include <typeinfo>

CBinaryTree::CBinaryTree(T array[],int size)
{
  BTREE_NODE *pNew;
  BTREE_NODE *pTmp =NULL;
  assert(array);

  CBinaryTree::pMemStart = new BTREE_NODE[size];
  if(NULL!=CBinaryTree::pMemStart){
     pNew=CBinaryTree::pMemStart;
     for(int i=0;i<size;i++,pNew++){
        pNew->value=array[i];
        pNew->left=pNew->right=NULL;
        if(0==i){
           CBinaryTree::TreeRoot = pNew;
           continue;
        }
        pTmp = CBinaryTree::_InsertByLocation(CBinaryTree::TreeRoot, pNew);
        if(pTmp->value > pNew->value)
          pTmp->left = pNew;
        else
          pTmp->right = pNew;
     }
   }

   cout<<"construct OK!";
}

CBinaryTree::~ CBinaryTree(void)
{
  if(NULL!=CBinaryTree::pMemStart){
     delete CBinaryTree::pMemStart;
     CBinaryTree::pMemStart=NULL;
  }
  cout<<"destruct OK!";
}

BTREE_NODE * CBinaryTree::_InsertByLocation(BTREE_NODE *r,
                                     BTREE_NODE *new_node)
{
  assert(r and new_node);
  
  if(NULL==r->left and  NULL==r->right)
    return r;

  if(new_node->value < r->value){
    if(NULL!=r->left)
       return CBinaryTree::_InsertByLocation(r->left,new_node);
  }
  else{
    if(NULL!=r->right)
       return  CBinaryTree::_InsertByLocation(r->right,new_node);
  }

  return r;
}

void CBinaryTree::_OutPutValue(T value)
{
  if((typeid(value)) == typeid(int))
    cout<<" "<<value;
  else if(( typeid(value)) == typeid(char)){
    cout<<" " ;
    cout.put(value);
  }
  else
  cout<<"unsupport type";
  return;
}

void CBinaryTree::TraversePreOrder(BTREE_NODE *r)
{
  assert(r);
  if((NULL == r->left)and (NULL==r->right)){
   CBinaryTree::_OutPutValue(r->value);
   return;
  }
  
  CBinaryTree::_OutPutValue(r->value);
  if(r->left)
     CBinaryTree::TraversePreOrder(r->left);
  
  if(r->right)
     CBinaryTree::TraversePreOrder(r->right);
}

BTREE_NODE * CBinaryTree::GetTreeRoot(void)
{
  return TreeRoot;
}

void  CBinaryTree::TraverseByBehindOrder(BTREE_NODE *r)
{
  assert(r);

  if((NULL == r->left)and (NULL==r->right)){
    CBinaryTree::_OutPutValue(r->value);
    return;
  }

  if(r->left)
     CBinaryTree::TraverseByBehindOrder(r->left);
    
  if(r->right)
     CBinaryTree::TraverseByBehindOrder(r->right);
  CBinaryTree::_OutPutValue(r->value);  
}

void CBinaryTree::TraverseByMiddleOrder(BTREE_NODE *r)
{
  assert(r);

  if((NULL == r->left)and (NULL==r->right)){
    CBinaryTree::_OutPutValue(r->value);
   return;
  }

  if(r->left)
     CBinaryTree::TraverseByMiddleOrder(r->right);
    
  CBinaryTree::_OutPutValue(r->value);
  if(r->right)
     CBinaryTree::TraverseByMiddleOrder(r->right);
}

void CBinaryTree::_MiddleOrderAdd(BTREE_NODE *r, vector<BTREE_NODE> *coll)
{
  assert(r and coll);

  if((NULL == r->left)and (NULL==r->right)){
   coll->push_back(*r);
   return;
  }

  if(r->left)
    CBinaryTree::_MiddleOrderAdd(r->left, coll);
    
  coll->push_back(*r);
  if(r->right)
    CBinaryTree::_MiddleOrderAdd(r->right, coll);
}

int CBinaryTree::TreeDepth(BTREE_NODE *r)
{
    int r_high=0, l_high=0;

    if(r->right)
    r_high = CBinaryTree::TreeDepth(r->right);

    if(r->left)
    l_high = CBinaryTree::TreeDepth(r->left);

    return r_high>l_high ? r_high+1:l_high+1;
}

int CBinaryTree::_GetElementLayer(T element)
{
    BTREE_NODE *r=CBinaryTree::TreeRoot;
    int count=0;
    bool find = false;
    while(1){
       count ++;
       if(r->value == element){
          find = true;
          break;
       }
       else if(r->value > element)
          if(r->left) r = r->left;
          else break;
       else
          if(r->right) r = r->right;
          else break;
    }
    if (find)
      return count;
    else
      return -1;
}

int CBinaryTree::_RemoveRepeat(T *array, int len)
{
  int i,j, r=0;

  for(i=0; i<len; i++)
  {
     for(j=0; j<r; j++)
       if(array[j]==array[i]) break;
     if(j==r)
       array[r++] = array[i];
  }
  return r;
}

inline void CBinaryTree::_PrintSpace(int number)
{
  for(int i=0;i<number; i++) cout<<" ";
}

int CBinaryTree::_CalculateTreeWide(vector<BTREE_NODE> *coll, int depth)
{
  int wide=0;
  vector<BTREE_NODE>::iterator pos;
  vector<BTREE_NODE>coll_now;
  
  for(int i=2; i<depth; i++){
    for(pos=coll->begin(); pos!=coll->end(); ++pos){
      if(pos->level==i) coll_now.push_back(*pos);
    }
    if((int) coll_now.size()>wide) 
      wide=coll_now.size();
    coll_now.clear();
  }
  return wide;
}

void CBinaryTree::_SetLayerForEachNode(BTREE_NODE *pTmp, int layer)
{
  if(NULL == pTmp) return;

  if(CBinaryTree::_GetElementLayer(pTmp->value) == layer)
    pTmp->level = layer;
  
  if(NULL!=pTmp->left) 
    CBinaryTree::_SetLayerForEachNode(pTmp->left, layer+1); 
 
  if(NULL!=pTmp->right);
    CBinaryTree::_SetLayerForEachNode(pTmp->right, layer+1);

  return ;
}

void CBinaryTree::_SetPositionForEachNode(BTREE_NODE *pTmp,int layer ,int wide)
{
    if(NULL == pTmp) return;

  if(CBinaryTree::_GetElementLayer(pTmp->value) == layer)
    pTmp->level = layer;
  
  if(NULL!=pTmp->left){
    if(wide>0){
      if(pTmp->left)
      pTmp->left->screen_x = pTmp->screen_x-wide-FOUR_SPACE;
    }
    else{
      if(pTmp->left)
      pTmp->left->screen_x = pTmp->screen_x-FOUR_SPACE;
    }
    
    CBinaryTree::_SetPositionForEachNode(pTmp->left, layer+1, wide-2); 
  }
 
  if(NULL!=pTmp->right);{
    if(wide>0){
       if(pTmp->right)
       pTmp->right->screen_x = pTmp->screen_x+wide+FOUR_SPACE;
    }
    else{
       if(pTmp->right)
       pTmp->right->screen_x = pTmp->screen_x+FOUR_SPACE;
    }
    CBinaryTree::_SetPositionForEachNode(pTmp->right, layer+1,wide-2);
  }
  return ;
}

int CBinaryTree::_CalculateDigitalBits(T value)
{
   int cnt=1;

   if(typeid(value) != typeid(char)){
     for(int i=10; (int)(value/i)>0; i=i*10)
      cnt++;
   }
   return cnt;
}

void CBinaryTree::_PrintLeftChildValue(vector<BTREE_NODE>::iterator pos, 
                              int wide)
{
   CBinaryTree::_OutPutValue(pos->value);
   if(wide>1)
   for(int i=0; i<wide; i++) cout<<"_";
   switch(CBinaryTree::_CalculateDigitalBits(pos->value))
   {
     case 1:
       cout<<"__/";//x__/
       break;
     case 2:
       cout<<"_/";//xx_/
       break;
     case 3:
       cout<<"/";//xxx/
       break;
     default:
       break;
   } 
}

void CBinaryTree::_PrintRightChildValue(vector<BTREE_NODE>::iterator pos, 
                              int wide)
{
    switch(CBinaryTree::_CalculateDigitalBits(pos->value))
    {
      case 1:
        cout<<"\\__";
        break;
      case 2:
        cout<<"\\_";
        break;
      case 3:
        cout<<"\\";
        break;
      default:
        break;
    }
    if(wide>1)
    for(int i=0; i<wide; i++) cout<<"_";
    CBinaryTree::_OutPutValue(pos->value);
}

void  CBinaryTree::_PrintStartSpace(vector<BTREE_NODE> *last, 
                           vector<BTREE_NODE> *now)
{
   vector<BTREE_NODE>::iterator pos_last;
   pos_last= last->begin();
   while(!pos_last->left && !pos_last->right)
      ++pos_last;    
   if(pos_last->left)
     CBinaryTree::_PrintSpace(MIDDLE_SCREEN+now->begin()->screen_x);
   else
     CBinaryTree::_PrintSpace(MIDDLE_SCREEN+pos_last->screen_x);
}

int CBinaryTree::_DetectNextNodePosition(vector<BTREE_NODE>::iterator pos_now, 
                             vector<BTREE_NODE> *now)
{
  int position=pos_now->screen_x;
   if(pos_now!=--now->end()){
      ++pos_now;
      return pos_now->screen_x - position;
   }
   else
      return 0;
}

int CBinaryTree::_DetectNextNodeType(vector<BTREE_NODE>::iterator pos_last, 
                          vector<BTREE_NODE>*last)
{
  vector<BTREE_NODE>::iterator pos_tmp;

   if(pos_last!=last->end()){
     pos_tmp=++pos_last;
     if(!pos_last->left && !pos_last->right){
        while(pos_last!=last->end() && !pos_last->left && !pos_last->right)
        ++pos_last;
     }
   }
   
   if(pos_last==last->end())
   return 0;
   
   if(pos_last!=last->end() && pos_last->left){
    return LEFT_CHILD;
   }

   if(pos_last!=last->end() && pos_last->right){
    return RIGHT_CHILD;
   }
   
   return 0;
}

void CBinaryTree::_PrintCurrentLayerNode(vector<BTREE_NODE> *last, 
                              vector<BTREE_NODE> *now, int wide)
{
   vector<BTREE_NODE>::iterator pos_now,pos_last,pos_tmp;
   int interval=0;
   int next_node_type=0;  

   CBinaryTree::_PrintStartSpace(last,now);
   for(pos_last=last->begin(),pos_now=now->begin();
      pos_last!=last->end() and pos_now!=now->end();++pos_last)
   {
      if(pos_last!=last->end() && !pos_last->left && !pos_last->right)
      continue;
      
      if(pos_last->left){
         CBinaryTree::_PrintLeftChildValue(pos_now, wide);
         interval = CBinaryTree::_DetectNextNodePosition(pos_now,now);
         ++pos_now;
         if(pos_last->right){
            CBinaryTree::_PrintRightChildValue(pos_now,wide);
            interval = CBinaryTree::_DetectNextNodePosition(pos_now, now);
            next_node_type = CBinaryTree::_DetectNextNodeType(pos_last, last);
            if(next_node_type == LEFT_CHILD)
              CBinaryTree::_PrintSpace(interval);
            else if(next_node_type == RIGHT_CHILD)
              CBinaryTree::_PrintSpace(interval-FOUR_SPACE-
                         CBinaryTree::_CalculateDigitalBits(pos_now->value));
            ++pos_now;
         }
         else{  
            next_node_type = CBinaryTree::_DetectNextNodeType(pos_last, last);
            if(next_node_type == LEFT_CHILD){
              --pos_now;
              CBinaryTree::_PrintSpace(interval-FOUR_SPACE);
              ++pos_now;
            }
            else if(next_node_type == RIGHT_CHILD){
              CBinaryTree::_PrintSpace(interval-FOUR_SPACE-FOUR_SPACE);
            }
         }
      }
      else{
         if(pos_last->right){
            CBinaryTree::_PrintRightChildValue(pos_now,wide);
            interval = CBinaryTree::_DetectNextNodePosition(pos_now, now);
            
            next_node_type = CBinaryTree::_DetectNextNodeType(pos_last, last);
            if(next_node_type == LEFT_CHILD)
              CBinaryTree::_PrintSpace(interval);
            else if(next_node_type == RIGHT_CHILD)
              CBinaryTree::_PrintSpace(interval-FOUR_SPACE);
            ++pos_now;
         }
      }
   }

   cout<<endl;
}

void CBinaryTree::PrintTree(void)
{
  vector<BTREE_NODE> coll, coll_last, coll_now;
  vector<BTREE_NODE>::iterator pos;
  BTREE_NODE *pTmp = CBinaryTree::TreeRoot;
  int depth =CBinaryTree::TreeDepth(pTmp), wide;

  CBinaryTree::_SetLayerForEachNode(pTmp, 1);
  CBinaryTree::_MiddleOrderAdd(CBinaryTree::TreeRoot, &coll);

  wide = CBinaryTree::_CalculateTreeWide(&coll,depth);
  if(wide*6 >MIDDLE_SCREEN){
  cout<<"tree is too wide!"<<endl;
  return ;
  }

  coll.clear(); 
  CBinaryTree::_SetPositionForEachNode(pTmp, 1, wide);
  
  CBinaryTree::_MiddleOrderAdd(CBinaryTree::TreeRoot, &coll);
  cout<<endl<<""<<endl;
  CBinaryTree::_PrintSpace(MIDDLE_SCREEN-CBinaryTree::_CalculateDigitalBits(CBinaryTree::TreeRoot->value)/2);
  CBinaryTree::_OutPutValue(CBinaryTree::TreeRoot->value);
  cout<<endl;
  
  for(int i=2; i<=depth; i++)
  { 
     coll_now.clear();
     coll_last.clear();
     for(pos=coll.begin(); pos!=coll.end(); ++pos){
       if(pos->level==i-1) coll_last.push_back(*pos);
       if(pos->level==i) coll_now.push_back(*pos);
     }
     CBinaryTree::_PrintCurrentLayerNode(&coll_last, &coll_now, wide);
     wide -= 2;
     cout<<endl;
  }
  cout<<""<<endl;
}


转载于:https://my.oschina.net/mingfu/blog/527526

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值