二叉树递归非递归完整实现

 

http://hi.baidu.com/xiaoxi2008/blog/item/d14a71f45fbf9ed8f2d385d7.html


#include <malloc.h>
#include <iostream.h>
#include <assert.h>
#include <stdio.h>

#define DataType int


struct BiTree
{
DataType data;
BiTree *lchild;
BiTree *rchild;
};

#define ElemType *BiTree

class Stack
{
public :
BiTree   **list;
int top;
int maxSize;

public:
Stack();
~Stack();
void ClearStack(){top = 0;}
void Push(BiTree* item);
BiTree* Pop();
BiTree* GetTop();
void EmptyStack();
bool IsEmpty();
bool IsFull();
};


class QueueT
{
public:
BiTree **list;
int front;
int rear;
int maxSize;
int currentLen;
public:
QueueT();
~QueueT();
void EnQueue(BiTree* item);
BiTree* DeQueue();
BiTree* GetFirst();
void EmptyQueue();
bool IsEmpty();
bool IsFull();
};

BiTree * RecursiveCreate();
BiTree * NonRecursiveCreate();

void RePreOrderVisit(BiTree * t);
void ReInOrderVisit(BiTree *t);
void PostOrderVisit(BiTree *t);

void NonPreOrderVisit(BiTree *t);
void NonInOrderVisit(BiTree *t);
void NonPostOrderVisit(BiTree *T);

void LevelVisit(BiTree *t);

//implementation of the Stack.
//to predesign the max size of the stack is 12.
Stack::Stack()
{
maxSize = 12;
list = new BiTree*[maxSize];
assert(list != NULL);
top = -1;
}

void Stack::Push(BiTree* item)
{
//to find whether the stack is full or not.
assert(!IsFull());
top ++;
list[top] = item;
}

BiTree* Stack::Pop()
{
assert(!IsEmpty());
return list[top--];
}

BiTree* Stack::GetTop()
{
assert(!IsEmpty());
return list[top];
}

void Stack::EmptyStack()
{
top = -1;
}

bool Stack::IsEmpty()
{
return (top == -1);
}

bool Stack::IsFull()
{
return (top == maxSize -1);
}

Stack::~Stack()
{
delete []list;
}

//implementation of the QueueT class.
QueueT::QueueT()
{
maxSize = 12;
list = new BiTree*[maxSize];
assert(list != NULL);
front = rear = currentLen = 0;
}

void QueueT::EnQueue(BiTree* item)
{
assert(! IsFull());
currentLen ++;
list[rear] = item;
rear = (rear +1)%maxSize;
}

BiTree* QueueT::DeQueue()
{
BiTree* temp;
assert(!IsEmpty());
temp = list[front];
currentLen --;
front = (front+1)%maxSize;
return temp;
}

BiTree* QueueT::GetFirst()
{
BiTree* temp;
assert(!IsEmpty());
temp = list[front];
return temp;
}

bool QueueT::IsEmpty()
{
return currentLen == 0;
}

bool QueueT::IsFull()
{
return currentLen == maxSize;
}

QueueT::~QueueT()
{
delete []list;
}

/*Recursively create in pre-order*/

BiTree * RecursiveCreate()
{
BiTree *t = NULL;
DataType data;
cin >>data;
if(data != 0)
{
   t = new BiTree;
   t->data = data;
   t->lchild = RecursiveCreate();
   t->rchild = RecursiveCreate();
   return t;
}
else
   return NULL;
}

/*NonRecursively create a biTree pre-order*/

BiTree * NonRecursiveCreate()
{
BiTree *root,*p,*q;
Stack s;
DataType data;
int i = 0;
cout<<"Input the first data:"<<endl;
cin>>data;
root = NULL;
p = NULL;
q = NULL;
if(data == 0 || data == -1)
{
   root = NULL;
   return root;
}
else
{
   root = new BiTree;
   root->data = data;
   root->lchild = NULL;
   root->rchild = NULL;
   s.Push(root);
}
i++;
cin>>data;
while(data != -1)
{
   while(data != 0 && data != -1)
   {
    q = new BiTree;
    q->data = data;
    q->lchild = NULL;
    q->rchild = NULL;
    p = s.GetTop();
    p->lchild = q;
    s.Push(q);
    i ++;
    cin>>data;
   }
   cin>>data;
   if(data != -1 && !s.IsEmpty())
   {
    p = s.GetTop();
    i ++;
    if(data == -1)
     break;
    if( data != 0)
    {
     q = new BiTree;
     q->data = data;
     q->lchild = NULL;
     q->rchild = NULL;
     p->rchild = q;
     s.Pop();
     s.Push(q);
    }
    else
    {
     s.Pop();
    }
    i ++;
   }  
   cin>>data;
}

return root;
}

void RePreOrderVisit(BiTree * t)
{
if(t != NULL)
{
   cout<<t->data<<" ";
   RePreOrderVisit(t->lchild);
   RePreOrderVisit(t->rchild);
}
}
void ReInOrderVisit(BiTree *t)
{

if(t != NULL)
{
   ReInOrderVisit(t->lchild);
   cout<<t->data<<" ";
   ReInOrderVisit(t->rchild);
}
}
void PostOrderVisit(BiTree *t)
{

if(t != NULL)
{
   PostOrderVisit(t->lchild);
   PostOrderVisit(t->rchild);
   cout<<t->data<<" ";
}
}

void NonPreOrderVisit(BiTree *t)
{
BiTree *p = NULL;
BiTree *q = NULL;
p = t;
Stack s;

s.Push(p);
while(!s.IsEmpty())
{
   p = s.GetTop();
   while( p != NULL)
   {
    cout<<p->data<<" ";
    p = p->lchild;
    if(p != NULL)
     s.Push(p);
   }
   s.Pop();//Pop the last leaf node.

   if(!s.IsEmpty())
   {
    q = s.Pop();
    if(q->rchild != NULL)
    {
     s.Push(q->rchild);
    }
   }
}
}

void NonInOrderVisit(BiTree *t)
{
BiTree *p = NULL;
Stack s;
p = t;

while(!s.IsEmpty() || (p != NULL))

   if( p != NULL)
   {
    s.Push(p);
    p = p->lchild;
   }
   else
   {   
    p = s.Pop();
    cout<<p->data<<" ";
    p = p->rchild;
   }
}
}
void NonPostOrderVisit(BiTree *t)
{
BiTree *p = NULL;
BiTree *q = NULL;
Stack s;
p = t;
q = p;

while(1)
{
   while(p != NULL && p->lchild != q && p->rchild != q)
   {
    s.Push(p);
    p = p->lchild;
   }
   if(s.IsEmpty())
    break;
   p = s.GetTop();
   if(p->rchild != NULL && p->rchild != q)
   {
    p = p->rchild;
   }
   else
   {
    q = s.Pop();
    cout<<q->data<<" ";
    p = NULL;
   }


}

void LevelVisit(BiTree *t)
{
QueueT Q;
BiTree *p = NULL;
BiTree *q = NULL;
p = t;
if(p != NULL)
   Q.EnQueue(p);
while(!Q.IsEmpty())
{
   q = Q.DeQueue();
   cout<<q->data<<" "; 
   if(q->lchild != NULL)
    Q.EnQueue(q->lchild);
   if(q->rchild != NULL)
    Q.EnQueue(q->rchild);
}
}


void main()
{

BiTree *t = NonRecursiveCreate();
cout<<"Recursively visit PreOrder: ";
RePreOrderVisit(t);
cout<<endl;
cout<<"Recursively visit InOrder: ";
ReInOrderVisit(t);
cout<<endl;
cout<<"Recursively visit PostOrder: ";
PostOrderVisit(t);
cout<<endl;
cout<<"NonRecursively visit PreOrder: ";
NonPreOrderVisit(t);
cout<<endl;
cout<<"NonRecursively visit InOrder: ";
NonInOrderVisit(t);
cout<<endl;
cout<<"NonRecursively visit PostOrder: ";
NonPostOrderVisit(t);
cout<<endl;
cout<<"Levelly visit The BiTree : ";
LevelVisit(t);

BiTree *h=RecursiveCreate();
cout<<"Recursively visit PreOrder: ";
RePreOrderVisit(t);
cout<<endl;
}


给出了程序设计中两种递归问题的非递归算法实现过程,并与递归算法进行比较,结果表明,非递归算法在时间复杂度与空间复杂度两项指标上均优于递归算法,且不使用系统栈,执行过程不依赖于函数或过程的重复调用,有更大的灵活性,可以应用在程序与软件设计中.

在程序 设计中,递归算法可以有效简化某些特殊问题的编程,但它只能简化程序 编码,不能降低程序的时间与空间复杂度.相 反,由于执行过程依赖函数 或过程的重复调用,会带来附加的时间消耗.而且由 于保存函数调用的返回地 址需要占用系统栈,从而 增加了执行的空间复杂度..... 

你可能感兴趣的:(二叉树)