二叉树的递归与非递归实现

来源:互联网 发布:腾讯网络推广 编辑:程序博客网 时间:2024/05/16 05:29

二叉树的递归实现:

#include <iostream>using namespace std;#define LEN sizeof(struct Tree)struct Tree{int key;    struct Tree*lchild;    struct Tree*rchild;};//二叉树的创建void create(struct Tree **p){  *p=new struct Tree [LEN];  cout<<"请输入二叉树key值:(按0结束当前分支输入)"<<endl;  cin>>(*p)->key;  static i=0;  if ((*p)->key!=0)  {  create((&(*p)->lchild));  create((&(*p)->rchild));  }}//先序遍历递归过程。。。。(位置1)void PreOderTraverse(struct Tree *p){//递归实现先序遍历if (p->key){cout<<p->key<<" ";PreOderTraverse(p->lchild);PreOderTraverse(p->rchild);}}//中序遍历void InOderTraverse(struct Tree *p){    if (p->key){InOderTraverse(p->lchild);cout<<p->key<<" ";InOderTraverse(p->rchild);}}//后序遍历void BackOderTraverse(struct Tree *p){    if (p->key){BackOderTraverse(p->lchild);BackOderTraverse(p->rchild);cout<<p->key<<" ";}}void main(){    struct Tree *p=NULL;create(&p);cout<<"先序遍历:"<<endl;PreOderTraverse(p);cout<<endl;cout<<"中序遍历:"<<endl;InOderTraverse(p);cout<<endl;cout<<"后序遍历:"<<endl;BackOderTraverse(p);cout<<endl;}

二叉树的非递归实现:

这里我们主要谈一下先序遍历的非递归实现的三种方法。

1,可以直接用C++STL的栈实现:

头文件加上#include <stack>,将上面代码位置1的递归实现二叉树遍历过程替换以下代码即可实现。

//先序遍历非递归过程void PreOderTraverse(struct Tree *root)  {  //用C++STL实现很容易。   if (root == NULL) return;    stack<struct Tree *>s;    s.push(root);   while (!s.empty()) {       struct Tree *p=s.top();    cout<<p->key<<" ";    s.pop();    if (p->rchild->key != 0) {      s.push(p->rchild); }    if (p->lchild->key != 0) {      s.push(p->lchild);  }}  cout << endl;  } 

2.也可以用栈的数组实现,栈的实现,包括PUSH POP等栈操作全部自己实现。这个应该是符合《算法导论》10.4-3题目条件。

#include <iostream>using namespace std;#define LEN sizeof(struct Tree)#define m 10//栈的最大容纳空间可以调整struct Tree{int key;    struct Tree*lchild;    struct Tree*rchild;};struct Stack{    int top;    int Array[m];bool empty();void push(struct Tree*);int pop();}s;//判断栈是否为空bool Stack::empty(){    if (s.top==-1)    {        return true;    }    else    {        return false;    }}//入栈void Stack::push(struct Tree*p){    if (s.top==m)    {        cerr<<"overflow!"<<endl;    }     else    {        s.top++;        s.Array[s.top]=reinterpret_cast<int>(p);//将树形结构体的地址转化为整数储存到栈里面。    }}//出栈int Stack::pop(){    if (empty())    {        cerr<<"underflow"<<endl;        return NULL;    }    else    {        s.top--;        return s.Array[s.top+1];    }    }void create(struct Tree **p){  *p=new struct Tree [LEN];  cin>>(*p)->key;  static i=0;  if ((*p)->key!=0)  {  create((&(*p)->lchild));  create((&(*p)->rchild));  }} void PreOderTraverse(struct Tree *root)  {  //用栈的数组实现,POP PUSH等函数全部自己来写if (root == NULL) return; s.top=-1;s.push(root);struct Tree *p=root;while (!s.empty()) {   p=reinterpret_cast<struct Tree *>(s.Array[s.top]);//将数组中的数据恢复为编译器所能识别的指针cout<<p->key<<" ";s.pop();if (p->rchild->key != 0) {s.push(p->rchild); }if (p->lchild->key != 0) {s.push(p->lchild);  }}  cout << endl;  }void main(){    struct Tree *p=NULL;create(&p);PreOderTraverse(p);}

3.前2种都是用辅助栈的方法实现的,还有一种不用辅助栈,但需要父结点。
(1). 访问左孩子
(2). 访问右孩子
(3). 如果是从右孩子返回,表明整棵子树已访问完,需要沿树而上寻找父节点。直到是从左孩子返回,或者访问到根节点的父节点

#include <iostream>#include <stack>using namespace std;#define LEN sizeof(struct Tree)struct Tree{int key;    struct Tree*lchild;    struct Tree*rchild;struct Tree*parent;};void create(struct Tree **p){static struct Tree *p1=NULL;//p1保存当前结点的父亲结点*p=new struct Tree [LEN];cin>>(*p)->key;(*p)->parent=p1;p1=*p;if ((*p)->key!=0){create((&(*p)->lchild));p1=*p;create((&(*p)->rchild));}}void InOderTraverse(struct Tree *p){   if(!p->key) return;    struct Tree *x=NULL;    while(1)    {        //访问左孩子        if(x != p->lchild)        {            while(p->lchild->key) {                p=p->lchild;}        }        cout<<p->key<<" ";        //访问右孩子        if(p->rchild->key)        {            p=p->rchild;            continue;        }        //回溯        do        {x=p;p=p->parent;            //访问到根节点的父节点(NULL)            if(!p) return;        }while(x==p->rchild);    }}void main(){    struct Tree *p=NULL;create(&p);InOderTraverse(p);}
这段代码遍历是借鉴网友的,但是创建的过程是自己写的,尤其是如何把父结点和这颗树相联系起来。


1 0
原创粉丝点击