一次贴代码太多,先贴二叉树的类定义头文件和实现文件:
//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