问题
解析
(1)检索得到所有的叶子
(2)对每个叶子自底向上检索,每次只向上检索一层
(3)利用队列实现的
(4)对每个结点做标记,利用条件结点不能相邻,作出合理的标记(根据自己需要即可)
(5)根据结点的标记,删除重复的,还有就是在最后节点最大数目确定的情况下,有可能有好几种结点组合,答案不唯一,我只求了其中一种
时间复杂度(n*log n),n计算的是n个叶子,log n 是树的高度(不考虑单叉树),即每个叶子都要走到树的根。
实验
方便大家查看,我自己把树画出来吧
代码
#include<iostream>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
#define NATURE 0
#define HALF 1
#define OK 2
#define NO -1
#define RESULT 3
const int SIZE = 24 ;
class node
{
public:
int value ;
node * Parent ;
node * Lchild ;
node * Rchild ;
int flag ;
node( )
{
value = NATURE ;
Parent = NULL ;
Lchild = NULL ;
Rchild = NULL ;
flag = 0 ;
};
};
typedef vector<node*> NVector ;
typedef NVector::iterator NIterator;
typedef queue<node*> NQueue;
class tree
{
public:
node * Root ;
tree( void )
{
Root = new node( );
};
void Insert( node * R,int data )
{
if( data > R -> value )
{
if( R -> Rchild == NULL )
{
R -> Rchild = new node() ;
R->Rchild->value = data ;
R->Rchild->Parent =R;
}
else
this->Insert( R->Rchild,data ) ;
}
if( data < R->value )
{
if( R->Lchild == NULL )
{
R -> Lchild = new node( ) ;
R ->Lchild->value = data ;
R->Lchild->Parent = R ;
}
else
this->Insert( R->Lchild,data ) ;
}
};
void Create( node * R,int * data,int size )
{
R->value = *data;
for(int i=1;i<size;i++)
{
this->Insert(R,*(data+i));
}
};
void InorderShow( node * R )
{
if(R->Lchild)
this->InorderShow( R->Lchild );
cout<<R->value<<" ";
if(R->Rchild)
this->InorderShow( R->Rchild );
};
void PreorderShow( node * R )
{
cout<<R->value<<" ";
if(R->Lchild)
this->PreorderShow( R->Lchild );
if(R->Rchild)
this->PreorderShow( R->Rchild );
};
void Findleaf( node * R ,NVector * L )
{
if( this->IsLeaf(R) )
L->insert(L->begin(),R) ;
else
{
if( R->Lchild != NULL )
this->Findleaf(R->Lchild,L) ;
if( R->Rchild != NULL )
this->Findleaf(R->Rchild,L) ;
}
};
bool IsLeaf( node * R)
{
if( R->Lchild==NULL && R->Rchild==NULL )
return true;
else return false ;
};
bool CheckBelongResult(node * p)
{
if(p->Parent&&p->Parent->flag == OK)
return false ;
if(p->Lchild&&p->Lchild->flag == OK)
return false ;
if(p->Rchild&&p->Rchild->flag == OK)
return false ;
return true ;
};
void ShowResult(NVector * L)
{
cout<<"result "<<(L->end()-L->begin())<<endl;
for( NIterator i =L->begin(); i<L->end() ; i++ )
{
cout<<(*i)->value<<endl;
}
};
void VectorSwap( NVector * L ,int a,int b)
{
node * p;
p = *(L->begin()+a);
*(L->begin()+a) = *(L->begin()+b);
*(L->begin()+b)= p;
};
void Buttom_to_up( NVector * L )
{
NQueue * Q = new NQueue();
NVector * Halflist = new NVector();
cout<<" leaf "<<endl;
// put leaves into queue :running time O(n)
for( NIterator i =L->begin(); i<L->end( ) ; i++ )
{
(*i)->flag = OK ;
cout<<(*i)->value<<endl;
Q->push( *i );
}
cout<<"progress"<<endl;
L->clear();
node * p =NULL;
while( ! Q->empty() )
{
cout<<endl;
p =Q->front();
if( p->flag == OK )
{
L->insert(L->begin(),p);
//cout<<p->value<<endl;
}
if( p->flag == HALF )
{
Halflist->insert(Halflist->begin(),p);
//cout<<p->value<<endl;
}
cout<<p->value<<" out"<<endl;
Q->pop();
if( p->Parent != NULL )
{
if(p->Parent->flag== NATURE)
{
Q->push(p->Parent);
cout<<p->Parent->value<<" in"<<endl;
}
if( p->flag == OK )
{
p->Parent->flag = NO ;
}
else
{
switch( p->Parent->flag )
{
case NO:break;
case NATURE:p->Parent->flag = HALF ;break;
case HALF:p->Parent->flag =OK;break;
}
}//else
cout<<p->Parent->value<<" "<<p->Parent->flag<<endl;
}//if
}//while
for( NIterator i = Halflist->begin();i<Halflist->end();i++ )
{
if(this->CheckBelongResult(*i))
{
(*i)->flag = OK ;
L->insert(L->begin(),(*i));
}
else
{
(*i)->flag = NO ;
}
}
for( NIterator i = L->begin(); i<L->end() ; i++ )
{
// delete the duplicate point
if( (*i)->flag != OK )
{
this->VectorSwap( L,L->end()-L->begin()-1,i-L->begin() );
L->pop_back();
}
else
{
(*i)->flag = RESULT ;
}
}
};
void Main( int * data,int size )
{
NVector * L = new NVector ();
//L->resize(size);
// create the tree :running time O(n*log n )
this->Create(Root,data,size);
cout<<"IN ORDER"<<endl;
this->InorderShow(Root);
cout<<endl;
cout<<"PRE ORDER"<<endl;
this->PreorderShow(Root);
cout<<endl;
this->Findleaf(Root,L);
this->Buttom_to_up(L);
this->ShowResult(L);
};
~tree( void ) ;
};
int main()
{
int * data = new int[SIZE];
for( int i =0 ;i<SIZE ;i++ )
{
*(data+i) = rand()%100+4;
}
tree * T = new tree() ;
T->Main(data,SIZE) ;
system("pause") ;
return 0;
}