data);preorder(bt->lchild);preorder(bt->rchild);}}中序遍历:voidinorder(JD*bt){if(bt!=NULL){inorder(bt->lchild);printf("%d\t",bt->data);inorder(bt->rchild" />
文档库 最新最全的文档下载
当前位置:文档库 › 三种遍历算法

三种遍历算法

三种遍历算法
三种遍历算法

三种遍历算法:

线序遍历:

void preorder(JD *bt)

{ if(bt!=NULL)

{ printf("%d\t",bt->data);

preorder(bt->lchild);

preorder(bt->rchild);}}

中序遍历:

void inorder(JD *bt)

{ if(bt!=NULL)

{ inorder(bt->lchild);

printf("%d\t",bt->data);

inorder(bt->rchild);}}

后序遍历:

void postorder(JD *bt)

{ if(bt!=NULL)

{ postorder(bt->lchild);

postorder(bt->rchild);

printf("%d\t",bt->data);}}

构造2叉排序树:typedef struct node { datatype data;

struct node *lchild, *rchild;

}JD;

折半插入排序:

void binsort(JD r[],int n)

{ int i,j,x,s,m,k;

for(i=2;i<=n;i++)

{ r[0]=r[i];

x=r[i].key;

s=1; j=i-1;

while(s<=j)

{ m=(s+j)/2;

if(x

else s=m+1;

}

for(k=i-1;k>=s;k--)

r[k+1]=r[k];

r[s]=r[0];

}

}

时间复杂度:T(n)=O(n2)

空间复杂度:S(n)=O(1)

希尔排序(缩小增量法)

void shellsort(JD r[],int n,int d[T])

{ int i,j,k;

JD x;

k=0;

while(k

{ for(i=d[k]+1;i<=n;i++)

{ x=r[i];

j=i-d[k];

while((j>0)&&(x.key

{ r[j+d[k]]=r[j];

j=j-d[k];}

r[j+d[k]]=x;}

k++;}}

对于有头结点的单链表

单链表存储结构定义如下:

typedef struct LNode

{ int data;

struct LNode * next;

}LNode,* LinkList;

对于结点类型为LNode的单链表,编写出下列每个算法。

(1) 删除单链表中的第i个结点。

(2) 在有序单链表中插入一个元素x的结点。

(3) 从单链表中查找出所有元素的最大值,该值由函数返回,若单链表为空,则显示出错信息并停止运行。

(4)统计出单链表中结点的值等于给定值x的结点数。

void Delete_LinkList(LinkList &L,int i, ElemType &e)

{ LinkList p,q;

int j =0;

p = L;

while ( p->next && j < i-1)

{ p = p->next;

++j;

}

if(!(p->next) || j > i-1 )

{ exit(0);

cout<<"\n 删除位置不合理!\n";

}

q = p->next;

p->next = q->next;

e = q->data;

free(q);

}

void Insert_LinkList_x(LinkList &L, ElemType x)

{ LinkList p,q,s;

s = (LinkList)malloc(sizeof(LNode));

s->data = x;

s->next = NULL;

p = L ;

if(p->next ==NULL)

p->next = s;

else

{ while (p)

{ if(p->data <=x)

{ q = p;

p = p->next;}

else

break;}

s->next = q->next;

q->next = s; }}

int Find_Max(LinkList L)

{int max;

if(L->next == NULL)

{ cout<<"ERROR";

exit(0);}

max = L->next ->data ;

LinkList p = L->next ;

while(p)

{if(p->data > max)

max = p->data ;

p = p->next ;}

return max;}

int Count_LinkList(LinkList L, int x )

{ int count = 0;

if(L==NULL) exit(0);

LinkList p = L->next;

while(p)

{ if(p->data ==x)

count ++;

p = p->next;}

return count;}

创建一个二叉树并输出三种遍历结果

实验报告 课程名称数据结构 实验项目实验三--创建一个二叉树并输出三种遍历结果 系别■计算机学院 _________________ 专业_______________ 班级/学号_____________ 学生姓名___________ 实验日期— 成绩______________________________ 指导 教师

实验题目:实验三创建一个二叉树并输出三种遍历结果 实验目的 1)掌握二叉树存储结构; 2)掌握并实现二叉树遍历的递归算法和非递归算法; 3)理解树及森林对二叉树的转换; 4)理解二叉树的应用一哈夫曼编码及WPL计算。 实验内容 1)以广义表或遍历序列形式创建一个二叉树,存储结构自选; 2)输出先序、中序、后序遍历序列; 3)二选一应用题:1)树和森林向二叉树转换;2)哈夫曼编码的应用问题。 题目可替换上述前两项实验内容) 设计与编码 1)程序结构基本设计框架 (提示:请根据所选定题目,描述程序的基本框架,可以用流程图、界面描述图、 框图等来表示) 2)本实验用到的理论知识遍历二叉树,递归和非递归的方法 (应用型

(提示:总结本实验用到的理论知识,实现理论与实践相结合。总结尽量简明扼要,并与本次实验密切相关,要求结合自己的题目并阐述自己的理解和想法) 3) 具体算法设计 1) 首先,定义二叉树的存储结构为二叉链表存储,每个元素的数 据类型Elemtype,定义一棵二叉树,只需定义其根指针。 2) 然后以递归的先序遍历方法创建二叉树,函数为CreateTree(),在输 入字符时要注意,当节点的左孩子或者右孩子为空的时候,应当输入一 个特殊的字符(本算法为“ #”),表示左孩子或者右孩子为空。 3) 下一步,创建利用递归方法先序遍历二叉树的函数,函数为 PreOrderTreeQ,创建非递归方法中序遍历二叉树的函数,函数为 InOrderTree(),中序遍历过程是:从二叉树的根节点开始,沿左子树 向下搜索,在搜索过程将所遇到的节点进栈;左子树遍历完毕后,从 栈顶退出栈中的节点并访问;然后再用上述过程遍历右子树,依次类 推,指导整棵二叉树全部访问完毕。创建递归方法后序遍历二叉树的 函数,函数为LaOrderTree()。 (提示:该部分主要是利用C、C++ 等完成数据结构定义、设计算法实现各种操作,可以用列表分步形式的自然语言描述,也可以利用流程图等描述) 4) 编码 #include #include #include typedef char DataType; #define MaxSize 100 typedef struct Node { DataType data; struct Node *lchild; struct Node *rchild; } *BiTree,BitNode;

图的优先遍历算法(C语言版)

#include #define MAX_VERTEX_NUM 20 #define ERROR -1 #define TRUE 1 #define FALSE 0 typedef struct ArcNode{ int adjvex; struct ArcNode *nextarc; }ArcNode; typedef struct VNode{ char data; ArcNode *firstarc; }VNode,AdjList[MAX_VERTEX_NUM]; typedef struct { AdjList vertices; int vexnum,arcnum; }ALGraph; void CreateAL(ALGraph *G); int LocateVex(ALGraph G,char u); void DFSTraverse(ALGraph G,void (*Visit)(ALGraph G,int v)); void PrintElem(ALGraph G,int v); void DFS(ALGraph G,int v); int FirstAdjVex(ALGraph G,int v); int NextAdjVex(ALGraph G,int v,int w); int visited[MAX_VERTEX_NUM]; void (*VisitFunc)(ALGraph G,int v); int main(){ ALGraph G; CreateAL(&G); printf("The Graph is:\n"); DFSTraverse(G,PrintElem); getch(); } void CreateAL(ALGraph *T){ int i,j,m; ArcNode *p,*s; char ch[100]; printf("Please input the vexnum and arcnumm:\n"); scanf("%d%d",&(T->vexnum),&(T->arcnum)); printf("Please input the vertexs:\n"); for(i=0;i<(T->vexnum);++i){ scanf(" %c",&(T->vertices[i].data)); T->vertices[i].firstarc=NULL; }

二叉树的各种算法

二叉树的各种算法.txt男人的承诺就像80岁老太太的牙齿,很少有真的。你嗜烟成性的时候,只有三种人会高兴,医生你的仇人和卖香烟的。 /*用函数实现如下二叉排序树算法: (1)插入新结点 (2)前序、中序、后序遍历二叉树 (3)中序遍历的非递归算法 (4)层次遍历二叉树 (5)在二叉树中查找给定关键字(函数返回值为成功1,失败0) (6)交换各结点的左右子树 (7)求二叉树的深度 (8)叶子结点数 Input 第一行:准备建树的结点个数n 第二行:输入n个整数,用空格分隔 第三行:输入待查找的关键字 第四行:输入待查找的关键字 第五行:输入待插入的关键字 Output 第一行:二叉树的先序遍历序列 第二行:二叉树的中序遍历序列 第三行:二叉树的后序遍历序列 第四行:查找结果 第五行:查找结果 第六行~第八行:插入新结点后的二叉树的先、中、序遍历序列 第九行:插入新结点后的二叉树的中序遍历序列(非递归算法) 第十行:插入新结点后的二叉树的层次遍历序列 第十一行~第十三行:第一次交换各结点的左右子树后的先、中、后序遍历序列 第十四行~第十六行:第二次交换各结点的左右子树后的先、中、后序遍历序列 第十七行:二叉树的深度 第十八行:叶子结点数 */ #include "stdio.h" #include "malloc.h" #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0

#define INFEASIBLE -1 #define OVERFLOW -2 typedef int Status; typedef int KeyType; #define STACK_INIT_SIZE 100 // 存储空间初始分配量 #define STACKINCREMENT 10 // 存储空间分配增量 #define MAXQSIZE 100 typedef int ElemType; typedef struct BiTNode{ ElemType data; struct BiTNode *lchild,*rchild;//左右孩子指针 } BiTNode,*BiTree; Status SearchBST(BiTree T,KeyType key,BiTree f,BiTree &p) { if(!T){p=f;return FALSE;} else if(key==T->data){p=T;return TRUE;} else if(keydata)return SearchBST(T->lchild,key,T,p); else return(SearchBST(T->rchild,key,T,p)); } Status InsertBST(BiTree &T,ElemType e) { BiTree s,p; if(!SearchBST(T,e,NULL,p)) { s=(BiTree)malloc(sizeof(BiTNode)); s->data=e;s->lchild=s->rchild=NULL; if(!p)T=s; else if(edata)p->lchild=s; else p->rchild=s; return TRUE; } else return FALSE; } Status PrintElement( ElemType e ) { // 输出元素e的值 printf("%d ", e ); return OK; }// PrintElement

树与图的简单遍历算法

树与图的简单遍历算法 发表时间:2019-01-14T09:56:22.797Z 来源:《科技新时代》2018年11期作者:闵俊齐 [导读] 树与图是两种重要的数据结构,而树可以说是一种特殊的图,它的两两结点之间存在唯一简单路径。 重庆第二外国语学校重庆 400065 摘要:树与图是两种重要的数据结构,而树可以说是一种特殊的图,它的两两结点之间存在唯一简单路径。利用其特殊性质,人们创造了许多算法来处理数据结构问题和程序调用问题。而树与图的遍历算法也是数据结构中重要的算法之一。本文从树与图的概念出发,简单的介绍了树与图的主要存储方式,并重点对二叉树的简单遍历算法、哈夫曼树的生成和图的深度优先遍历及广度优先遍历做出了介绍。 关键词:数据结构;二叉树;图;遍历算法 1.树与图的概念 树是一种数据结构,是由n(n≥0)个结点构成的具有明显层次关系的有限集合。一棵树一般由一个根节点和若干个子结点构成。结点与结点之间具有明显的并列或层次关系,这种层次关系称为父子关系。在一棵树中,没有父结点的结点被称为根结点。树有几个重要的概念,以下做出简单的介绍——树的度:某个结点拥有的子树的数量称为这个结点的度,度为零的结点也叫做叶结点,而度不为零的结点叫做分支结点。树的深度:一棵树的根结点的层次为1,其他结点的层次是其父结点的层次加1。一棵树里最大的层次的值被称为这棵树的深度。树有无序树,有序树,二叉树等。其中二叉树是每个结点最多有两个子结点的树,每个结点的子树通常被称为“左子树”和“右子树”,故二叉树中每个结点的度的最大值为2,而又有左右之分,二叉树中结点的次序不能任意颠倒。除最后一层的叶结点没有子结点外,其余每一层的每个结点都具有两个子结点的二叉树称为满二叉树。如果存在一个深度为h的二叉树,它的除h层外其余各层(1~h-1)的结点数都达到了最大值,并且它的第h层的结点全部集中在树的左边,这种二叉树就被称为完全二叉树。完全二叉树是由满二叉树引申出来的,它是一种效率很高的数据结构。本文后部分将会介绍二叉树的简单遍历算法。 图由若干个顶点组成的有限非空集合和各个顶点的边构成,通常表示为G(V,E),其中G表示一个图,V是图G中顶点的集合,E是图G中边的集合。图数据结构主要研究形状和图形数据元素之间的关系。它必须反映数据所对应的元素之间的几何关系和拓扑关系。图依照边的方向可分为有向图和无向图。有向图由顶点和弧构成。弧有弧尾和弧头,带箭头的一边称为弧头。图结构与树结构相比较,图中的任意两个元素都有可能相关。而对某个结点而言,树下层可能有多个元素,上层只有能一个元素,复杂度比树大[1]。 2二叉树与图的储存方式 2.1二叉树的储存方式 二叉树有两种储存方式:顺序存储和链式存储。 顺序储存就是按照完全二叉树的结点层次顺序存储的一种只适用于完全二叉树的储存方式,且在最坏的情况下,k个结点的单支数却只需要长度的 -1的一维数据。这种储存需要一个完全连续地址,所以会占用许多的储存空间。 在二叉树中,每个结点信息一般都由一下几个部分构成:该结点的数据元素(Data)、指向左子树的指针(L child)和指向右子树的指针(R child)。利用指针,我们可以很好的存储二叉树。若使用二叉链表,每个结点的结构如图1(a)所示。一般可以(L,D,R)来表示。在三叉链表中,可表示每个结点的父结点,结构如图1(b)所示。一般可以(L,D,P,R)来表示[5]。链式储存不需要完全连续地址,节约储存空间[2]。 图2 3.二叉树的遍历算法及哈夫曼树的生成 3.1二叉树的遍历算法 遍历,是指用某种方法沿着某条路对每一个元素做一且仅一次访问,它是二叉树的重要运算之一。二叉树的主要有三种访问方式:先序遍历、中序遍历、后序遍历。具体实现过程如下:

二分搜索算法和快速排序算法及分治策略

实验课程:算法分析与设计 实验名称:实验二C/C++环境及递归算法(综合性/设计性) 实验目标: 1、熟悉二分搜索算法和快速排序算法; 2、初步掌握分治算法; 实验任务: 掌握分治策略的概念和基本思想。 实验题: 1、设a[0:n-1]是一个已排好序的数组。请改写二分搜索算法,使得当搜索元素x不在数组中时,返回小于x的最大元素的位置i和大于x的最小元素位置j。当搜索元素在数组中时,I 和j相同,均为x在数组中的位置。设有n个不同的整数排好序后存放于t[0:n-1]中,若存在一个下标i,0≤i<n,使得t[i]=i,设计一个有效的算法找到这个下标。要求算法在最坏的情况下的计算时间为O(logn)。 2、在快速排序中,记录的比较和交换是从两端向中间进行的,关键字较大的记录一次就能交换到后面单元,关键字较小的记录一次就能交换到前面单元,记录每次移动的距离较大,因而总的比较和移动次数较少。 实验设备及环境: PC;C/C++的编程环境Visual C++。 实验主要步骤: (1)明确实验目标和具体任务; (2)理解实验所涉及的分治算法; (3)编写程序并实现分治算法; (4)设计实验数据并运行程序、记录运行的结果; 实验数据及运行结果、实验结果分析及结论: 1、#include using namespace std; int main() { int const length=100; int n,x; int a[length]; cout<<"依次输入数组的长度,数组内容,要查找的数"<>n; //输入数组的长度 for(int i=0;i>a[i]; cin>>x;

数据结构C语言实现二叉树三种遍历

实验课题一:将下图中得二叉树用二叉链表表示: 1用三种遍历算法遍历该二叉树,给出对应得输出结果; 2写一个函数对二叉树搜索,若给出一个结点,根据其就是否属于该树,输出true或者f alse。 3写函数完成习题4、31(C++版)或4、28(C版教科书)。 #include "stdio、h" #include”malloc、h" typedefstruct BiTNode { char data; structBiTNode *lchild,*rchild; }BiTNode,*BiTree; BiTree Create(BiTreeT) { char ch; ch=getchar(); if(ch=='#’) T=NULL; else { T=(BiTNode *)malloc(sizeof(BiTNode)); T-〉data=ch; T->lchild=Create(T—〉lchild); T—〉rchild=Create(T-〉rchild); } return T; } int node(BiTree T) { int sum1=0,a,b; ?if(T) { if(T!=NULL) ??sum1++;

?a=node(T->lchild); sum1+=a; b=node(T—>rchild); sum1+=b; ?} return sum1; } int mnode(BiTree T) { ?int sum2=0,e,f; if(T) { ?if((T->lchild!=NULL)&&(T-〉rchild!=NULL))?sum2++; ?e=mnode(T-〉lchild); sum2+=e; f=mnode(T-〉rchild); sum2+=f; ?} return sum2; } void Preorder(BiTree T) { if(T) { printf("%c”,T->data); Preorder(T—>lchild); Preorder(T-〉rchild); } } int Sumleaf(BiTree T) { int sum=0,m,n; if(T) { if((!T-〉lchild)&&(!T-〉rchild)) sum++; m=Sumleaf(T->lchild); sum+=m; n=Sumleaf(T—>rchild); sum+=n; } return sum; }

图的深度优先遍历算法课程设计报告

合肥学院 计算机科学与技术系 课程设计报告 2013~2014学年第二学期 课程数据结构与算法 课程设计名称图的深度优先遍历算法的实现 学生姓名陈琳 学号1204091022 专业班级软件工程 指导教师何立新 2014 年9 月 一:问题分析和任务定义 涉及到数据结构遍会涉及到对应存储方法的遍历问题。本次程序采用邻接表的存储方法,并且以深度优先实现遍历的过程得到其遍历序列。

深度优先遍历图的方法是,从图中某顶点v 出发: (1)访问顶点v ; (2)依次从v 的未被访问的邻接点出发,对图进行深度优先遍历;直至图中和v 有路径相通的顶点都被访问; (3)若此时图中尚有顶点未被访问,则从一个未被访问的顶点出发,重新进行深度优先遍历,直到图中所有顶点均被访问过为止。 二:数据结构的选择和概要设计 设计流程如图: 图1 设计流程 利用一维数组创建邻接表,同时还需要一个一维数组来存储顶点信息。之后利用创建的邻接表来创建图,最后用深度优先的方法来实现遍历。 图 2 原始图 1.从0开始,首先找到0的关联顶点3 2.由3出发,找到1;由1出发,没有关联的顶点。 3.回到3,从3出发,找到2;由2出发,没有关联的顶点。 4.回到4,出4出发,找到1,因为1已经被访问过了,所以不访问。

所以最后顺序是0,3,1,2,4 三:详细设计和编码 1.创建邻接表和图 void CreateALGraph (ALGraph* G) //建立邻接表函数. { int i,j,k,s; char y; EdgeNode* p; //工作指针. printf("请输入图的顶点数n与边数e(以逗号做分隔符):\n"); scanf("%d,%d",&(G->n),&(G->e)); scanf("%c",&y); //用y来接收回车符. for(s=0;sn;s++) { printf("请输入下标为%d的顶点的元素:\n",s); scanf("%c",&(G->adjlist[s].vertex)); scanf("%c",&y); //用y来接收回车符.当后面要输入的是和单个字符有关的数据时候要存贮回车符,以免回车符被误接收。 G->adjlist[s].firstedge=NULL; } printf("请分别输入该图的%d条弧\n",G->e); for(k=0;ke;k++) { printf("请输入第%d条弧的起点和终点(起点下标,终点下标):\n",(k+1)); scanf("%d,%d",&i,&j); p=(EdgeNode*)malloc(sizeof(EdgeNode)); p->adjvex=j; p->next=G->adjlist[i].firstedge; G->adjlist[i].firstedge=p; } } 2.深度优先遍历 void DFS(ALGraph* G,int v) //深度优先遍历 { EdgeNode* p;

两点间所有路径的遍历算法

两点间所有路径的遍历算法 中国海洋大学信息科学与工程学院熊建设梁磊 摘要:本文首先简单介绍图的深度优先遍历算法,接着根据图的深度优先遍历算法求出连通图中两点间所有路径。 一、深度优先遍历(Depth-First Traversal) 1.图的深度优先遍历的递归定义 假设给定图G的初态是所有顶点均未曾访问过。在G中任选一顶点v为初始出发点(源点),则深度优先遍历可定义如下:首先访问出发点v,并将其标记为已访问过;然后依次从v出发搜索v的每个邻接点w。若w未曾访问过,则以w为新的出发点继续进行深度优先遍历,直至图中所有和源点v有路径相通的顶点(亦称为从源点可达的顶点)均已被访问为止。若此时图中仍有未访问的顶点,则另选一个尚未访问的顶点作为新的源点重复上述过程,直至图中所有顶点均已被访问为止。 图的深度优先遍历类似于树的前序遍历。采用的搜索方法的特点是尽可能先对纵深方向进行搜索。这种搜索方法称为深度优先搜索(Depth-First Search)。相应地,用此方法遍历图就很自然地称之为图的深度优先遍历。 2、深度优先搜索的过程 设x是当前被访问顶点,在对x做过访问标记后,选择一条从x出发的未检测过的边(x,y)。若发现顶点y已访问过,则重新选择另一条从x出发的未检测过的边,否则沿边(x,y)到达未曾访问过的y,对y访问并将其标记为已访问过;然后从y开始搜索,直到搜索完从y出发的所有路径,即访问完所有从y出发可达的顶点之后,才回溯到顶点x,并且再选择一条从x出发的未检测过的边。上述过程直至从x出发的所有边都已检测过为止。此时,若x 不是源点,则回溯到在x之前被访问过的顶点;否则图中所有和源点有路径相通的顶点(即从源点可达的所有顶点)都已被访问过,若图G是连通图,则遍历过程结束,否则继续选择一个尚未被访问的顶点作为新源点,进行新的搜索过程。 二、求两点间所有路径的算法 假设简单连通图如图1所示,那么它的邻接表存储结构如图2所示。假设我们要找出结点3到结点6的所有路径,那么,我们就设结点3为起点,结点6为终点。我们需要的存储结构有:一个保存路径的栈、一个保存已标记结点的数组,那么找到结点3到结点6的所有路径步骤如下:

树的遍历(递归和非递归)

二叉树的遍历 一、设计思想 二叉树的遍历分为三种方式,分别是先序遍历,中序遍历和后序遍历。先序遍历实现的顺序是:根左右,中序遍历实现的是:左根右,后续遍历实现的是:左右根。根据不同的算法分,又分为递归遍历和非递归遍历。 递归算法: 1.先序遍历:先序遍历就是首先判断根结点是否为空,为空则停止遍历,不为空则将左子作为新的根结点重新进行上述判断,左子遍历结束后,再将右子作为根结点判断,直至结束。到达每一个结点时,打印该结点数据,即得先序遍历结果。 2.中序遍历:中序遍历是首先判断该结点是否为空,为空则结束,不为空则将左子作为根结点再进行判断,打印左子,然后打印二叉树的根结点,最后再将右子作为参数进行判断,打印右子,直至结束。 3.后续遍历:指针到达一个结点时,判断该结点是否为空,为空则停止遍历,不为空则将左子作为新的结点参数进行判断,打印左子。左子判断完成后,将右子作为结点参数传入判断,打印右子。左右子判断完成后打印根结点。 非递归算法: 1.先序遍历:首先建立一个栈,当指针到达根结点时,打印根结点,判断根结点是否有左子和右子。有左子和右子的话就打印左子同时将右子入栈,将左子作为新的根结点进行判断,方法同上。若当前结点没有左子,则直接将右子打印,同时将右子作为新的根结点判断。若当前结点没有右子,则打印左子,同时将左子作为新的根结点判断。若当前结点既没有左子也没有右子,则当前结点为叶子结点,此时将从栈中出栈一个元素,作为当前的根结点,打印结点元素,同时将当前结点同样按上述方法判断,依次进行。直至当前结点的左右子都为

空,且栈为空时,遍历结束。 2.中序遍历:首先建立一个栈,定义一个常量flag(flag为0或者1),用flag记录结点的左子是否去过,没有去过为0,去过为1,默认为0.首先将指针指向根结点,将根结点入栈,然后将指针指向左子,左子作为新的结点,将新结点入栈,然后再将指针指向当前结点的左子,直至左子为空,则指针返回,flag置1,出栈一个元素,作为当前结点,打印该结点,然后判断flag,flag为1则将指针指向当前结点右子,将右子作为新的结点,结点入栈,再次进行上面的判断,直至当前结点右子也为空,则再出栈一个元素作为当前结点,一直到结束,使得当前结点右子为空,且栈空,遍历结束。 3.后续遍历:首先建立两个栈,然后定义两个常量。第一个为status,取值为0,1,2.0代表左右子都没有去过,1代表去过左子,2,代表左右子都去过,默认为0。第二个常量为flag,取值为0或者1,0代表进左栈,1代表进右栈。初始时指针指向根结点,判断根结点是否有左子,有左子则,将根结点入左栈,status置0,flag置0,若没有左子则判断结点有没有右子,有右子就把结点入右栈,status置0,flag置1,若左右子都没有,则打印该结点,并将指针指向空,此时判断flag,若flag为0,则从左栈出栈一个元素作为当前结点,重新判断;若flag为1则从右栈出栈一个元素作为当前结点,重新判断左右子是否去过,若status为1,则判断该结点有没有右子,若有右子,则将该结点入右栈,status置1,flag置1,若没有右子,则打印当前结点,并将指针置空,然后再次判断flag。若当前结点status为2,且栈为空,则遍历结束。若指针指向了左子,则将左子作为当前结点,判断其左右子情况,按上述方法处理,直至遍历结束。 二、算法流程图

二叉树遍历C语言(递归,非递归)六种算法

数据结构(双语) ——项目文档报告用两种方式实现表达式自动计算 专业: 班级: 指导教师: 姓名: 学号:

目录 一、设计思想 (01) 二、算法流程图 (02) 三、源代码 (04) 四、运行结果 (11) 五、遇到的问题及解决 (11) 六、心得体会 (12)

一、设计思想 二叉树的遍历分为三种方式,分别是先序遍历,中序遍历和后序遍历。先序遍历实现的顺序是:根左右,中序遍历实现的是:左根右,后续遍历实现的是:左右根。根据不同的算法分,又分为递归遍历和非递归遍历。 递归算法: 1.先序遍历:先序遍历就是首先判断根结点是否为空,为空则停止遍历,不为空则将左子作为新的根结点重新进行上述判断,左子遍历结束后,再将右子作为根结点判断,直至结束。到达每一个结点时,打印该结点数据,即得先序遍历结果。 2.中序遍历:中序遍历是首先判断该结点是否为空,为空则结束,不为空则将左子作为根结点再进行判断,打印左子,然后打印二叉树的根结点,最后再将右子作为参数进行判断,打印右子,直至结束。 3.后续遍历:指针到达一个结点时,判断该结点是否为空,为空则停止遍历,不为空则将左子作为新的结点参数进行判断,打印左子。左子判断完成后,将右子作为结点参数传入判断,打印右子。左右子判断完成后打印根结点。 非递归算法: 1.先序遍历:首先建立一个栈,当指针到达根结点时,打印根结点,判断根结点是否有左子和右子。有左子和右子的话就打印左子同时将右子入栈,将左子作为新的根结点进行判断,方法同上。若当前结点没有左子,则直接将右子打印,同时将右子作为新的根结点判断。若当前结点没有右子,则打印左子,同时将左子作为新的根结点判断。若当前结点既没有左子也没有右子,则当前结点为叶子结点,此时将从栈中出栈一个元素,作为当前的根结点,打印结点元素,同时将当前结点同样按上述方法判断,依次进行。直至当前结点的左右子都为空,且栈为空时,遍历结束。 2.中序遍历:首先建立一个栈,定义一个常量flag(flag为0或者1),用flag记录结点的左子是否去过,没有去过为0,去过为1,默认为0.首先将指针指向根结点,将根结点入栈,然后将指针指向左子,左子作为新的结点,将新结点入栈,然后再将指针指向当前结点的左子,直至左子为空,则指针返回,flag置1,出栈一个元素,作为当前结点,打印该结点,然后判断flag,flag为1则将指针指向当前结点右子,将右子作为新的结点,结点入栈,再次进行上面的判断,直至当前结点右子也为空,则再出栈一个元素作为当前结点,一直到结束,使得当前结点右子为空,且栈空,遍历结束。 3.后续遍历:首先建立两个栈,然后定义两个常量。第一个为status,取值为0,1,2.0代表左右子都没有去过,1代表去过左子,2,代表左右子都去过,默认为0。第二个常量为flag,取值为0或者1,0代表进左栈,1代表进右栈。初始时指针指向根结点,判断根结点是否有左子,有左子则,将根结点入左栈,status置0,flag置0,若没有左子则判断结点有没有右子,有右子就把结点入右栈,status置0,flag置1,若左右子都没有,则打印该结点,并将指针指向空,此时判断flag,若flag为0,则从左栈出栈一个元素作为当前结点,重新判断;若flag为1则从右栈出栈一个元素作为当前结点,重新判断左右子是否去过,若status 为1,则判断该结点有没有右子,若有右子,则将该结点入右栈,status置1,flag置1,若没有右子,则打印当前结点,并将指针置空,然后再次判断flag。若当前结点status为2,且栈为空,则遍历结束。若指针指向了左子,则将左子作为当前结点,判断其左右子情况,按上述方法处理,直至遍历结束。

二叉树的建立及几种简单的遍历方法

#include "stdio.h" #include "stdlib.h" #define STACK_INIT_SIZE 100 //栈存储空间初始分配量 #define STACKINCREMENT 10 //存储空间分配增量 //------二叉树的存储结构表示------// typedef struct BiTNode{ int data; struct BiTNode *lchild,*rchild; }BiTNode,*BiTree; //-----顺序栈的存储结构表示------// typedef struct{ BiTree *top; BiTree *base; int stacksize; }SqStack; //*************************************************** //构造一个空栈s SqStack *InitStack(); //创建一颗二叉树 BiTree CreatBiTree(); //判断栈空 int StackEmpty(SqStack *S); //插入元素e为新的栈顶元素 void Push(SqStack *S,BiTree p); //若栈不为空,则删除s栈顶的元素e,将e插入到链表L中void Pop(SqStack *S,BiTree *q); //非递归先序遍历二叉树 void PreOrderTraverse(BiTree L); //非递归中序遍历二叉树 void InOrderTraverse(BiTree L); //非递归后序遍历二叉树 void PostOrderTraverse(BiTree L); //递归后序遍历二叉树 void PostOrder(BiTree bt); //递归中序遍历二叉树 void InOrder(BiTree bt); //递归先序遍历二叉树 void PreOrder(BiTree bt); //***************************************************

图的遍历实验报告

实验四:图的遍历 题目:图及其应用——图的遍历 班级:姓名:学号:完成日期: 一.需求分析 1.问题描述:很多涉及图上操作的算法都是以图的遍历操作为基础的。试写一个程序,演示在连通的无向图上访问全部结点的操作。 2.基本要求:以邻接表为存储结构,实现连通无向图的深度优先和广度优先遍历。以用户指定的结点为起点,分别输出每种遍历下的结点访问序列和相应生成树的边集。 3.测试数据:教科书图7.33。暂时忽略里程,起点为北京。 4.实现提示:设图的结点不超过30个,每个结点用一个编号表示(如果一个图有n个结点,则它们的编号分别为1,2,…,n)。通过输入图的全部边输入一个图,每个边为一个数对,可以对边的输入顺序作出某种限制,注意,生成树的边是有向边,端点顺序不能颠倒。 5.选作内容: (1).借助于栈类型(自己定义和实现),用非递归算法实现深度优先遍历。 (2).以邻接表为存储结构,建立深度优先生成树和广度优先生成树,再按凹入表或树形打印生成树。 二.概要设计 1.为实现上述功能,需要有一个图的抽象数据类型。该抽象数据类型的定义为: ADT Graph { 数据对象V:V是具有相同特性的数据元素的集合,称为顶点集。 数据关系R: R={VR} VR={ | v,w v且P(v,w),表示从v到w得弧,谓词P(v,w)定义了弧的意义或信息} } ADT Graph 2.此抽象数据类型中的一些常量如下: #define TRUE 1 #define FALSE 0 #define OK 1 #define max_n 20 //最大顶点数 typedef char VertexType[20]; typedef enum{DG, DN, AG, AN} GraphKind; enum BOOL{False,True}; 3.树的结构体类型如下所示:

遍历算法及应用

实验报告 课程名称算法与数据结构 姓名何劼 专业计算机科学与技术 部别 指导教员 日期年月日

实验项目列表

实验报告 姓名:何劼学号:专业:计算机科学与技术部别: 实验地点:实验时间: 2012、4、17 设备编号: 同组人员:指导教员签字:成绩:教员评语: 一、实验名称 遍历算法及应用 二、实验目的 1 .掌握二叉树的递归构造方法 2 .掌握二叉树的递归遍历方法 3 .掌握二叉树的递归遍历的简单应用

三、实验内容和要求 编写完成如下功能的程序。 1 .构造二叉树(中序加后序序列造树选做) 2 .删除树中原来所有1 度的结点 3 .求给定的任意结点的父亲 4 .从根到叶的一条最长路经 5 .计算树中叶结点数(选) 6 .判定一棵树是否是正则树(选) 7 .按层遍历树,并输出树宽(选) 要求: 1 .先构造出二叉树,然后输出原树的三种遍历序列。 2 .在删除原来所有1 度的结点后,再输出新二叉树的三种遍历序列。 3 .直接输出给定结点的父结点的值。 4 .输出这条最长的路径。 5 .输出树中叶结点的数目。 6 .输出一棵树是否是正则树的判定结论。 7 .按层遍历树,并输出树宽 四、实验环境 1.硬件环境:PC机

2.软件环境:Windows操作系统,VC++集成开发环境 五、算法设计思想 题目一—构造二叉树。 为了使得程序能够更加具有通用性,设计者在构造二叉树时编写了三种造树方式,分别是先序扩充序列造树,先序加中序序列造树以及中序加后序造树。其中前两个程序已经在课上得到了实现。中序加后序造树,主要问题就是左右子树上下标界的确定,运用图示法能够较为形象准确的解决此问题。三种序列的输出这里不加赘述。 题目二——删除树中1度结点。 采用先序遍历递归。首先判断下一结点是否为1度结点,若为1度结点并且有右儿子,返回1;若为1度结点并且有左儿子,返回2;不为1度结点返回0。再根据返回值的情况进行勾连和结点的删除。 题目三——求结点的父亲。 采用后续遍历递归。设计者配合使用了类似于“红绿灯”的found 标记值。若为0则还未发现结点;若为1则找到该结点返回上一层输出其父亲,并置found为2。 题目四——输出从根到叶的一条最长路径。 首先找到最长路径对应的叶子(先序),再求取叶子的祖先(后序)。运用order数组存储其祖先,最后从后到前输出。这样得到的路径是符

二叉树三种遍历算法代码_

二叉树三种遍历算法的源码 二叉树三种遍历算法的源码背诵版 本文给出二叉树先序、中序、后序三种遍历的非递归算法,此三个算法可视为标准算法,直接用于考研答题。 1.先序遍历非递归算法 #define maxsize 100 typedef struct { Bitree Elem[maxsize]; int top; }SqStack; void PreOrderUnrec(Bitree t) { SqStack s; StackInit(s); p=t; while (p!=null || !StackEmpty(s)) { while (p!=null) //遍历左子树 { visite(p->data); push(s,p); p=p->lchild; }//endwhile if (!StackEmpty(s)) //通过下一次循环中的内嵌while实现右子树遍历 { p=pop(s); p=p->rchild; }//endif }//endwhile }//PreOrderUnrec 2.中序遍历非递归算法 #define maxsize 100 typedef struct { Bitree Elem[maxsize];

int top; }SqStack; void InOrderUnrec(Bitree t) { SqStack s; StackInit(s); p=t; while (p!=null || !StackEmpty(s)) { while (p!=null) //遍历左子树 { push(s,p); p=p->lchild; }//endwhile if (!StackEmpty(s)) { p=pop(s); visite(p->data); //访问根结点 p=p->rchild; //通过下一次循环实现右子树遍历}//endif }//endwhile }//InOrderUnrec 3.后序遍历非递归算法 #define maxsize 100 typedef enum{L,R} tagtype; typedef struct { Bitree ptr; tagtype tag; }stacknode; typedef struct { stacknode Elem[maxsize]; int top; }SqStack; void PostOrderUnrec(Bitree t)

数据结构 树的三种遍历

学号:E30814013 姓名:张芸; 专业:网络工程 题目::实现二叉树的前序,中序,后序遍历 #include #include #include typedef struct Btnode{ char data; struct Btnode *lchild; struct Btnode *rchild; }Btnode; void main() { void xianxu(Btnode *BT); void zhongxu(Btnode *BT); void houxu(Btnode *BT); Btnode *CreatBiTree(Btnode *BT); Btnode *BT; Btnode *B; BT=(Btnode*)malloc(sizeof(Btnode)); printf("先序输入二叉树中节点的值(一个字符,先序输入),空格表示空树\n"); B=BT=CreatBiTree(BT); printf("输出二叉树(二叉树的遍历)\n"); printf("先序\n"); xianxu(BT); printf("\n"); printf("中序\n"); zhongxu(BT); printf("\n"); printf("后序\n"); houxu(BT); printf("\n"); } Btnode *CreatBiTree(Btnode *BT) {char ch; scanf("%c",&ch); if(ch==' ')BT=NULL; else{

BT=(Btnode*)malloc(sizeof(Btnode)); BT->data=ch; BT->lchild=CreatBiTree(BT->lchild); BT->rchild=CreatBiTree(BT->rchild); } return BT; } void xianxu(Btnode *BT) { if(BT){ printf("%c",BT->data); xianxu(BT->lchild); xianxu(BT->rchild); } } void zhongxu(Btnode *BT) { if(BT){ zhongxu(BT->lchild); printf("%c",BT->data); zhongxu(BT->rchild); } } void houxu(Btnode *BT) { if(BT){ houxu(BT->lchild); houxu(BT->rchild); printf("%c",BT->data); }

邻接矩阵表示图,深度,广度优先遍历

*问题描述: 建立图的存储结构(图的类型可以是有向图、无向图、有向网、无向网,学生可以任选两种类型),能够输入图的顶点和边的信息,并存储到相应存储结构中,而后输出图的邻接矩阵。 1、邻接矩阵表示法: 设G=(V,E)是一个图,其中V={V1,V2,V3…,Vn}。G的邻接矩阵是一个他有下述性质的n阶方阵: 1,若(Vi,Vj)∈E 或∈E; A[i,j]={ 0,反之 图5-2中有向图G1和无向图G2的邻接矩阵分别为M1和M2: M1=┌0 1 0 1 ┐ │ 1 0 1 0 │ │ 1 0 0 1 │ └0 0 0 0 ┘ M2=┌0 1 1 1 ┐ │ 1 0 1 0 │ │ 1 1 0 1 │ └ 1 0 1 0 ┘ 注意无向图的邻接是一个对称矩阵,例如M2。 用邻接矩阵表示法来表示一个具有n个顶点的图时,除了用邻接矩阵中的n*n个元素存储顶点间相邻关系外,往往还需要另设一个向量存储n个顶点的信息。因此其类型定义如下: VertexType vertex[MAX_VERTEX_NUM]; // 顶点向量 AdjMatrix arcs; // 邻接矩阵 int vexnum, arcnum; // 图的当前顶点数和弧(边)数 GraphKind kind; // 图的种类标志

若图中每个顶点只含一个编号i(1≤i≤vnum),则只需一个二维数组表示图的邻接矩阵。此时存储结构可简单说明如下: type adjmatrix=array[1..vnum,1..vnum]of adj; 利用邻接矩阵很容易判定任意两个顶点之间是否有边(或弧)相联,并容易求得各个顶点的度。 对于无向图,顶点Vi的度是邻接矩阵中第i行元素之和,即 n n D(Vi)=∑A[i,j](或∑A[i,j]) j=1 i=1 对于有向图,顶点Vi的出度OD(Vi)为邻接矩阵第i行元素之和,顶点Vi 的入度ID(Vi)为第i列元素之和。即 n n OD(Vi)=∑A[i,j],OD(Vi)=∑A[j,i]) j=1j=1 用邻接矩阵也可以表示带权图,只要令 Wij, 若或(Vi,Vj) A[i,j]={ ∞, 否则。 其中Wij为或(Vi,Vj)上的权值。相应地,网的邻接矩阵表示的类型定义应作如下的修改:adj:weightype ; {weightype为权类型} 图5-6列出一个网和它的邻接矩阵。 ┌∞31∞∞┐ │∞∞51∞│ │∞∞∞∞∞│ │∞∞6∞∞│ └∞322∞┘ (a)网(b)邻接矩阵 图5-6 网及其邻接矩阵 对无向图或无向网络,由于其邻接矩阵是对称的,故可采用压缩存贮的方法,

相关文档
相关文档 最新文档