Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1436501
  • 博文数量: 241
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 2253
  • 用 户 组: 普通用户
  • 注册时间: 2012-04-11 22:27
个人简介

--

文章分类

全部博文(241)

文章存档

2021年(3)

2019年(6)

2018年(1)

2017年(9)

2016年(21)

2015年(50)

2014年(125)

2013年(26)

我的朋友

分类: C/C++

2013-09-27 15:46:47

(百度笔试)简要说明树的深度优先、广度优先遍历算法,及非递归实现的特点

二叉树的遍历:

D:访问根结点,L:遍历根结点的左子树,R:遍历根结点的右子树。

给定一棵二叉树的前序遍历序列和中序遍历序列可以惟一确定一棵二叉树。

二叉树的深度优先遍历的非递归的通用做法是采用栈,广度优先遍历的非递归的通用做法是采用队列。

 

深度优先遍历二叉树。

1. 中序遍历(LDR)的递归算法:

若二叉树为空,则算法结束;否则:

    中序遍历根结点的左子树;

    访问根结点;

    中序遍历根结点的右子树。

2. 前序遍历(DLR)的递归算法:

若二叉树为空,则算法结束,否则:

    访问根结点;

    前序遍历根结点的左子树;

    前序遍历根结点的右子树。

3. 后序遍历(LRD)的递归算法:

若二叉树为空,则算法结束,否则:

    后序遍历根结点的左子树;

    后序遍历根结点的右子树;

    访问根结点。

 

广度优先遍历二叉树。

广度优先周游二叉树(层序遍历)是用队列来实现的,从二叉树的第一层(根结点)开始,自上至下逐层遍历;在同一层中,按照从左到右的顺序对结点逐一访问。

按照从根结点至叶结点、从左子树至右子树的次序访问二叉树的结点。算法:

    1初始化一个队列,并把根结点入列队;

    2当队列为非空时,循环执行步骤3到步骤5,否则执行6;

    3出队列取得一个结点,访问该结点;

    4若该结点的左子树为非空,则将该结点的左子树入队列;

    5若该结点的右子树为非空,则将该结点的右子树入队列;

    6结束。

 

非递归深度优先遍历二叉树。

栈是实现递归的最常用的结构,利用一个栈来记下尚待遍历的结点或子树,以备以后访问,可以将递归的深度优先遍历改为非递归的算法。

1. 非递归前序遍历:遇到一个结点,就访问该结点,并把此结点推入栈中,然后下降去遍历它的左子树。遍历完它的左子树后,从栈顶托出这个结点,并按照它的右链接指示的地址再去遍历该结点的右子树结构。

2. 非递归中序遍历:遇到一个结点,就把它推入栈中,并去遍历它的左子树。遍历完左子树后,从栈顶托出这个结点并访问之,然后按照它的右链接指示的地址再去遍历该结点的右子树。

3. 非递归后序遍历:遇到一个结点,把它推入栈中,遍历它的左子树。遍历结束后,还不能马上访问处于栈顶的该结点,而是要再按照它的右链接结构指示的地址去遍历该结点的右子树。遍历遍右子树后才能从栈顶托出该结点并访问之。另外,需要给栈中的每个元素加上一个特征位,以便当从栈顶托出一个结点时区别是从栈顶元素左边回来的(则要继续遍历右子树),还是从右边回来的(该结点的左、右子树均已周游)。特征为Left表示已进入该结点的左子树,将从左边回来;特征为Right表示已进入该结点的右子树,将从右边回来。

4. 简洁的非递归前序遍历:遇到一个结点,就访问该结点,并把此结点的非空右结点推入栈中,然后下降去遍历它的左子树。遍历完左子树后,从栈顶托出一个结点,并按照它的右链接指示的地址再去遍历该结点的右子树结构。

----------------------------------------------------------------------

    图的深度优先搜索法是树的先根遍历的推广,它的基本思想是:从图G的某个顶点v0出发,访问v0,然后选择一个与v0相邻且没被访问过的顶点vi访问,再从vi出发选择一个与vi相邻且未被访问的顶点vj进行访问,依次继续。如果当前被访问过的顶点的所有邻接顶点都已被访问,则退回到已被访问的顶点序列中最后一个拥有未被访问的相邻顶点的顶点w,从w出发按同样的方法向前遍历,直到图中所有顶点都被访问。
    图的广度优先搜索是树的按层次遍历的推广,它的基本思想是:首先访问初始点vi,并将其标记为已访问过,接着访问vi的所有未被访问过的邻接点vi1,vi2, …, vi t,并均标记已访问过,然后再按照vi1,vi2, …, vi t的次序,访问每一个顶点的所有未被访问过的邻接点,并均标记为已访问过,依次类推,直到图中所有和初始点vi有路径相通的顶点都被访问过为止。

本文来自:http://www.cnblogs.com/way_testlife/archive/2010/10/07/1845264.html,感谢oyzway的分享。

以下转自http://blog.csdn.net/ithomer/article/details/5686810
#include "stdafx.h"
#include
#include
#define DataType char
int d_tree=0;  /* tree's depth */
int l_tree=0;  /* tree's leaf */
int n_tree=0;  /* tree's node */
/**************************************/
/********     树的结构定义     ********/
/**************************************/
struct _tree
{
DataType data;
struct _tree *lchild;
struct _tree *rchild;
};
typedef struct _tree tree, *ptree;
/**************************************/
/********     栈的结构定义     ********/
/**************************************/
struct _node
{
ptree pt;
struct _node *next;
};
typedef struct _node node, *pnode;
struct _stack
{
int size;
pnode ptop;
};
typedef struct _stack stack, *pstack;
/**************************************/
/********     堆的结构定义     ********/
/**************************************/
struct _queue
{
pnode front;
pnode rear;
};
typedef struct _queue queue, *pqueue;
/**************************************/
/********     栈的数据操作     ********/
/**************************************/
pstack init_stack()
{
pnode pn=NULL;
pstack ps=NULL;
pn=(pnode)malloc(sizeof(node));
ps=(pstack)malloc(sizeof(stack));
pn->pt=NULL;
pn->next=NULL;
ps->ptop=pn;
return ps;
}
int empty_stack(pstack ps)
{
if(ps->ptop->next==NULL)
return 1;
else
return 0;
}
void push_stack(pstack ps, ptree pt) /* flag for post tree: 0 for lchild; 1 for rchild */
{
pnode pn=NULL;
pn=(pnode)malloc(sizeof(node));
pn->pt=pt;
pn->next=ps->ptop;
ps->ptop=pn;
}
ptree pop_stack(pstack ps)
{
ptree pt=NULL;
pnode pn=NULL;
if(!empty_stack(ps))
{
pn=ps->ptop;
ps->ptop=ps->ptop->next;
pt=pn->pt;
free(pn);
}
return pt;
}
ptree gettop_stack(pstack ps)
{
if(!empty_stack(ps))
return ps->ptop->pt;
}
/**************************************/
/********     堆的数据操作     ********/
/**************************************/
queue init_queue()
{
pnode pn=NULL;
queue qu;
pn=(pnode)malloc(sizeof(node));
pn->pt=NULL;
pn->next=NULL;
qu.front=qu.rear=pn; /* init: pn is header */
return qu;
}
int empty_queue(queue &qu)
{
if(qu.front==qu.rear)
return 1;
else
return 0;
}
void en_queue(queue &qu, ptree pt)
{
pnode pn=NULL;
pn=(pnode)malloc(sizeof(node));
pn->pt=pt;
pn->next=qu.rear->next;
qu.rear->next=pn;
qu.rear=qu.rear->next;
}
ptree de_queue(queue &qu)
{
ptree pt=NULL;
pnode pn=NULL;
if(!empty_queue(qu))
{
pn=qu.front->next;
if(pn==qu.rear) /* qu is null: qu.front==qu.rear */
qu.rear=qu.front;
else
qu.front->next=qu.front->next->next;
pt=pn->pt;
free(pn);
}
return pt;
}
/**************************************/
/********     树的数据操作     ********/
/**************************************/
ptree init_tree()
{
ptree pt=NULL;
pt=(ptree)malloc(sizeof(tree));
pt->data='0';
pt->lchild=NULL;
pt->rchild=NULL;
return pt;
}
ptree create_tree()
{
char ch;
ptree pt=NULL;

scanf("%c", &ch);
getchar();
if(ch==' ')
return NULL;
else
{
pt=(ptree)malloc(sizeof(tree));
pt->data=ch;
pt->lchild=create_tree();
pt->rchild=create_tree();
}
return pt;
}
int depth_tree(ptree pt)
{
int l_len, r_len;
ptree p=pt;
if(p==NULL)
return 0;
else
{
l_len=depth_tree(p->lchild);
r_len=depth_tree(p->rchild);
return l_len>r_len?(l_len+1):(r_len+1);
}
}
void leaf_tree(ptree pt)
{
ptree p=pt;
if(p->lchild==NULL && p->rchild==NULL)
l_tree++;
else
{
leaf_tree(p->lchild);
leaf_tree(p->rchild);
}
}
void node_tree(ptree pt)
{
ptree p=pt;
if(p!=NULL)
{
n_tree++;
node_tree(p->lchild);
node_tree(p->rchild);
}
}
void print_pretree(ptree pt)
{
if(pt!=NULL)
{
printf("%3c", pt->data);
print_pretree(pt->lchild);
print_pretree(pt->rchild);
}
}
void print_pretree2(ptree pt)
{
pstack ps=NULL;
ptree p=NULL;
ps=init_stack();
p=pt;
while(p!=NULL || !empty_stack(ps))
{
while(p!=NULL)
{
printf("%3c", p->data);
push_stack(ps, p);
p=p->lchild;
}
if(!empty_stack(ps))
{
p=pop_stack(ps);
p=p->rchild;
}
}
}
void print_midtree(ptree pt)
{
if(pt!=NULL)
{
print_midtree(pt->lchild);
printf("%3c", pt->data);
print_midtree(pt->rchild);
}
}
void print_midtree2(ptree pt)
{
pstack ps=NULL;
ptree p=NULL;
ps=init_stack();
p=pt;
while (p!=NULL || !empty_stack(ps))
{
while(p!=NULL)
{
push_stack(ps, p);
p=p->lchild;
}
if(!empty_stack(ps))
{
p=pop_stack(ps);
printf("%3c", p->data);
p=p->rchild;
}
}
}
void print_posttree(ptree pt)
{
if(pt!=NULL)
{
print_posttree(pt->lchild);
print_posttree(pt->rchild);
printf("%3c", pt->data);
}
}
void print_posttree2(ptree pt)
{
pstack ps=NULL;
ptree p=NULL;
ptree p2=NULL;
ptree lastvisit=NULL;
ps=init_stack();
p=pt;
while (p!=NULL || !empty_stack(ps))
{
while(p!=NULL)
{
push_stack(ps, p);
p=p->lchild;
}
p2=gettop_stack(ps); /* top: rchild==null or sub_root */
if(p2->rchild==NULL || p2->rchild==lastvisit)
{
printf("%3c", p2->data);
lastvisit=pop_stack(ps); /* pop */
}
else
p=p2->rchild;
}
}
void bfs_tree(ptree pt)
{
ptree p=NULL;
queue qu;
qu=init_queue();
p=pt;
if(p!=NULL)
{
en_queue(qu, p);
while (!empty_queue(qu))
{
p=de_queue(qu);
printf("%3c", p->data);
if(p->lchild!=NULL)
en_queue(qu, p->lchild);
if(p->rchild!=NULL)
en_queue(qu, p->rchild);
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
ptree pt=NULL;
/*pt=init_tree();*/

printf("Create tree:/n");
pt=create_tree();
/************  recursion ************/
printf("/n/nrecursion...");
printf("/npre tree.../n");
print_pretree(pt);
printf("/nmid tree.../n");
print_midtree(pt);
printf("/npost tree.../n");
print_posttree(pt);
/************  stack ************/
printf("/n/nstack, non recursion:");
printf("/npre tree.../n");
print_pretree2(pt);
printf("/nmid tree.../n");
print_midtree2(pt);
printf("/npost tree.../n");
print_posttree2(pt);
/**********  bfs tree **********/
printf("/n/nbfs_tree:/n");
bfs_tree(pt);
/********* tree operation ********/
printf("/n/ntree operation:");
d_tree=depth_tree(pt);
leaf_tree(pt);
node_tree(pt);
printf("/ntree's depth: %d", d_tree);
printf("/ntree's leaf: %d", l_tree);
printf("/ntree's node: %d", n_tree);
printf("/n");
return 0;
}

阅读(2814) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~