数据结构试验报告用先序中序建立二叉树后序遍历非递归

合集下载

二叉树的建立与先序,中序,后序,层次遍历,图的深度优先搜索和广度优先搜索 实验报告

二叉树的建立与先序,中序,后序,层次遍历,图的深度优先搜索和广度优先搜索 实验报告

树和图的遍历实验报告2011-4-9实验题目:树和图的遍历实验目的:1.实现二叉树的建立与先序,中序,后序,层次遍历2.选择建立图的类型;根据所选择的类型用邻接矩阵的存储结构构建图;对图进行深度优先搜索和广度优先搜索;实验内容:一、算法描述:(1)二叉树的建立要建立一棵树就要有根节点和两棵子树。

两棵子树的建立同样需要这样的过程。

建立二叉树的过程也是遍历树的过程,实验要求以前序遍历的方式输入数据,因此我们也应按前序遍历的顺序,动态申请存储空间的方式建立这棵树并返回根节点的指针。

BiTNode *CreateBiTree(BiTNode *T){char ch;if((ch=getchar())==' ') T=NULL;else if(ch!='\n'){if(!(T=(BiTNode *)malloc(sizeof(BiTNode))))exit(1);T->data=ch;T->lchild=CreateBiTree(T->lchild);T->rchild=CreateBiTree(T->rchild);}return T;}(2)二叉树的遍历遍历作为二叉树所有操作的基础,因此我把它放在二叉树建立的前面。

前序遍历:即按照根节点,左子树,右子树的顺序访问。

具体操作:遇到节点,立即打印根节点的值,然后访问左子树,再访问右子树。

对左子树和右子树的访问也进行相同的操作。

void PreOrderTraverse(BiTree T){if(T){putchar(T->data);PreOrderTraverse(T->lchild);PreOrderTraverse(T->rchild);}}同理,易得中序遍历,后序遍历的操作。

//中序遍历二叉树void InOrderTraverse(BiTree T){if(T){InOrderTraverse(T->lchild);putchar(T->data);InOrderTraverse(T->rchild);}}//后序遍历二叉树void PostOrderTraverse(BiTree T){if(T){PostOrderTraverse(T->lchild);PostOrderTraverse(T->rchild);putchar(T->data);}}层次遍历:先访问的节点,其孩子节点也必然优先访问,这就用到了队列的思想。

C 二叉树创建、前序遍历、中序遍历、后序遍历 的 递归与非递归实现 以及 层次遍历

C 二叉树创建、前序遍历、中序遍历、后序遍历 的 递归与非递归实现 以及 层次遍历

二叉树创建、前序遍历、中序遍历、后序遍历的递归与非递归实现以及层次遍历二叉树的创建:#include"stdio.h"typedef char ElemType;#define MAXNUM 150/* 二叉树结点定义 */typedef struct BTNode{ElemType data;/* data field */struct BTNode *lchild;struct BTNode *rchild;} BTNode;/* 辅助的二叉树索引数组 */BTNode *p[MAXNUM+1];/* 根据用户输入创建二叉树 *//* 二叉树结点信息:数据域,以及在完全二叉树中的索引值 */BTNode *Create_BiTree(void){BTNode* t =NULL;int i;int j;char ch;printf("\n enter i, ch :");scanf("%d,%c",&i,&ch);while(i != 0 && ch !='#'){BTNode* s =(BTNode*)malloc(sizeof(BTNode)); s->data = ch;s->lchild = s->rchild =NULL;p[i]= s;if( i == 1 )t = s;else{j = i/2;if( i%2 == 0 )p[j]->lchild = s;elsep[j]->rchild = s;}printf("\n enter i, ch :");scanf("%d,%c",&i,&ch);}return t;}int main(void){BTNode* t;t = Create_BiTree();/*preorder(t);printf(" preorder\n");preorder_recursive(t);printf(" preorder_recursive\n");Inorder(t);printf(" Inorder\n");Inorder_recursive1(t);printf(" Inorder_recursive1\n"); Inorder_recursive2(t);printf(" Inorder_recursive2\n");Postorder(t);printf(" Postorder\n");Postorder_recursive(t);printf(" Postorder_recursive\n");LevelOrder(t);printf(" LevelOrder\n");*/getchar();getchar();return 0;}二叉树的前序遍历,递归、非递归的实现:/* 前序遍历的递归实现 */void preorder(BTNode *bt){if(bt){printf("%c ",bt->data);preorder(bt->lchild);preorder(bt->rchild);}}/* 前序遍历的非递归实现 */void preorder_recursive(BTNode *bt){BTNode* p;BTNode* s[MAXNUM+1];/* 辅助的模拟栈 */ int top;p=bt;top=-1;while(p||top !=-1){if(p){printf("%c ",p->data);++top;二叉树的中序遍历,递归、非递归的实现:BTNode* p,*s[MAXNUM+1];int top;p=bt;top=-1;while(p||top !=-1){if(p){++top;s[top]=p;p=p->lchild ;}/*p移向左孩子*/else/*栈非空*/{p=s[top];--top;printf("%c ",p->data); p=p->rchild;}}}/* 中序遍历的非递归实现 */void Inorder_recursive2(BTNode *bt){BTNode* p,*s[MAXNUM+1];int top;p=bt;top=-1;while(p||top !=-1){if(p && p->lchild){++top;s[top]= p;p = p->lchild;}else{if(p)printf("%c ", p->data);if(p && p->rchild ){p = p->rchild;}else if( top >= 0){p = s[top];top--;printf("%c ", p->data); p = p->rchild;}elsebreak;}}}二叉树的后序遍历,递归、非递归的实现:/* 后序遍历的递归实现 */void Postorder(BTNode *bt){if(bt){Postorder(bt->lchild);Postorder(bt->rchild);printf("%c ",bt->data);}}/* 后序遍历的非递归实现 */void Postorder_recursive(BTNode *pt) {BTNode *s[MAXNUM+1];int top =-1;BTNode *p = pt;BTNode *pre =NULL;while( p || top !=-1 ){if(p ){++top;s[top]= p;p = p->lchild;pre = p;}else{p = s[top];// --top;if( p->rchild ==NULL|| p->rchild == pre ){p = s[top];--top;printf("%c ", p->data);pre =p;p =NULL;}else{p = p->rchild;pre = p;}}}}层次遍历:{BTNode*queue[100];int front=0,rear=0;if(bt==NULL)return;queue[rear]=bt;rear++;do{printf("%c ",queue[front]->data);/*访问队首结点的数据域*/if(queue[front]->lchild!=NULL)/*将队首结点的左孩子结点入队列*/{queue[rear]=queue[front]->lchild; rear++;}if(queue[front]->rchild!=NULL)/*将队首结点的右孩子结点入队列*/{queue[rear]=queue[front]->rchild; rear++;}front++;。

二叉树的遍历(先序、中序、后序)

二叉树的遍历(先序、中序、后序)

实践三:树的应用1.实验目的要求通过本实验使学生深刻理解二叉树的性质和存储结构,熟练掌握二叉树的遍历算法。

认识哈夫曼树、哈夫曼编码的作用和意义。

实验要求:建一个二叉树并按照前序、中序、后序三种方法遍历此二叉树,正确调试本程序。

能够建立一个哈夫曼树,并输出哈夫曼编码,正确调程序。

写出实验报告。

2.实验主要内容2.1 对二叉树进行先序、中序、后序递归遍历,中序非递归遍历。

2.2 根据已知的字符及其权值,建立哈夫曼树,并输出哈夫曼编码。

3.实验步骤2.1实验步骤●输入p127二叉链表的定义●录入调试p131算法6.4,实现二叉树的构造函数●编写二叉树打印函数,可以通过递归算法将二叉树输出为广义表的形式,以方便观察树的结构。

●参考算法6.1,实现二叉树的前序、中序和后序的递归遍历算法。

为简化编程,可以将visit函数直接使用printf函数输出结点内容来代替。

#include<stdio.h>#include<stdlib.h>#include<malloc.h>#define OK 1#define ERROR 0#define STACK_INIT_SIZE 100#define STACKINCREMENT 10typedef char TElemType;typedef char Status;// 构造书的结构体typedef struct BiTNode{TElemType data;struct BiTNode *lchild, *rchild;}BiTNode, *BiTree;// 构造栈的结构体typedef BiTree SElemType;typedef struct{SElemType *base;SElemType *top;int stacksize;}SqStack;Status InitStack(SqStack &S){//构造一个空栈S.base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType)); if(!S.base)exit(-2);S.top = S.base;S.stacksize = STACK_INIT_SIZE;return OK;}Status StackEmpty(SqStack S){//若栈S为空栈,则返回TRUE,否则返回FALSEif(S.top==S.base)return 1;elsereturn 0;}Status Push(SqStack &S,SElemType e){//插入元素e为新的栈顶元素if(S.top - S.base >= S.stacksize){S.base = (SElemType *)realloc(S.base,(S.stacksize + STACKINCREMENT) * sizeof(SElemType));if(!S.base)exit(-2);S.top = S.base + S.stacksize;S.stacksize += STACKINCREMENT;}*S.top++ = e;return OK;}Status Pop(SqStack &S,SElemType &e){//若栈不空,则删除S的栈顶元素,用e返回其值并返回OK,否则返回ERRORif(S.top == S.base) return ERROR;e = * --S.top;return OK;}Status InOrderTraverse(BiTree T,Status(*Visit)(TElemType e)){//非递归中序遍历二叉树SqStack S;BiTNode * p;InitStack(S);p = T;while(p||!StackEmpty(S)){if(p){Push(S,p); p=p->lchild; }else {Pop(S,p); if(!Visit(p->data)) return 0;p=p->rchild;}}return 1;}//以下是递归遍历Status CreateBiTree(BiTree &T){//构造二叉树Tchar ch;scanf("%c",&ch);if(ch == ' ') T=NULL;else{if(!(T=(BiTNode*)malloc(sizeof(BiTNode)))) exit(-2);T->data=ch;CreateBiTree(T->lchild);CreateBiTree(T->rchild);}return 1;}Status PreOrderTraverse(BiTree T, Status(* Visit)(TElemType e)){ //递归先序遍历if(T){if(Visit(T->data))if(PreOrderTraverse(T->lchild,Visit))if(PreOrderTraverse(T->rchild,Visit)) return 1;return 0;}else return 1;}Status MinOrderTraverse(BiTree T, Status(* Visit)(TElemType e)){ //递归中序遍历if(T){if(MinOrderTraverse(T->lchild,Visit))if(Visit(T->data))if(MinOrderTraverse(T->rchild,Visit)) return 1;return 0;}else return 1;}Status PostOrderTraverse(BiTree T, Status(* Visit)(TElemType e)){ //递归后续遍历if(T){if(PostOrderTraverse(T->lchild,Visit))if(PostOrderTraverse(T->rchild,Visit))if(Visit(T->data)) return 1;return 0;}else return 1;}Status PrintElement(TElemType e){//Visit函数,输出元素printf("%c ",e);return 1;}//主函数void main(){BiTNode* p;printf("Enter Node:\n");CreateBiTree(p);printf("递归先序遍历:");PreOrderTraverse(p,PrintElement);printf("\n递归中序遍历:");MinOrderTraverse(p,PrintElement);printf("\n递归后序遍历:");PostOrderTraverse(p,PrintElement);printf("\n");printf("\n非递归中序遍历:");InOrderTraverse(p,PrintElement);printf("\n");}输入:ABCE000DF00G00HJ00K0L00 (“0”表示空格) 输出:。

二叉树的遍历:先序中序后序遍历的递归与非递归实现及层序遍历

二叉树的遍历:先序中序后序遍历的递归与非递归实现及层序遍历

⼆叉树的遍历:先序中序后序遍历的递归与⾮递归实现及层序遍历 对于⼀种数据结构⽽⾔,遍历是常见操作。

⼆叉树是⼀种基本的数据结构,是⼀种每个节点的⼉⼦数⽬都不多于2的树。

⼆叉树的节点声明如下:1 typedef struct TreeNode *PtrToNode;2 typedef struct TreeNode *BinTree;34struct TreeNode5{6int Data; //为简单起见,不妨假设树节点的元素为int型7 BinTree Left;8 BinTree Right;9 }; ⼆叉树的遍历主要有先序遍历,中序遍历,后序遍历,层序遍历四种⽅式,下⾯⼀⼀介绍。

1. 先序遍历 在先序遍历中,对节点的访问⼯作是在它的左右⼉⼦被访问之前进⾏的。

换⾔之,先序遍历访问节点的顺序是根节点-左⼉⼦-右⼉⼦。

由于树可以通过递归来定义,所以树的常见操作⽤递归实现常常是⽅便清晰的。

递归实现的代码如下:1void PreOrderTraversal(BinTree BT)2{3if( BT )4 {5 printf(“%d\n”, BT->Data); //对节点做些访问⽐如打印6 PreOrderTraversal(BT->Left); //访问左⼉⼦7 PreOrderTraversal(BT->Right); //访问右⼉⼦8 }9 } 由递归代码可以看出,该递归为尾递归(即递归形式在函数末尾或者说在函数即将返回前)。

尾递归的递归调⽤需要⽤栈存储调⽤的信息,当数据规模较⼤时容易越出栈空间。

虽然现在⼤部分的编译器能够⾃动去除尾递归,但是即使如此,我们不妨⾃⼰去除。

⾮递归先序遍历算法基本思路:使⽤堆栈 a. 遇到⼀个节点,访问它,然后把它压栈,并去遍历它的左⼦树; b. 当左⼦树遍历结束后,从栈顶弹出该节点并将其指向右⼉⼦,继续a步骤; c. 当所有节点访问完即最后访问的树节点为空且栈空时,停⽌。

数据结构实验报告二叉树

数据结构实验报告二叉树

数据结构实验报告二叉树《数据结构与算法》实验报告专业班级姓名学号实验项目实验三二叉树。

实验目的1、掌握用递归方法实现二叉树的遍历。

2、加深对二叉树的理解,逐步培养解决实际问题的编程能力。

题目:(1)编写二叉树的遍历操作函数。

①先序遍历,递归方法re_preOrder(TREE *tree)②中序遍历,递归方法re_midOrder(TREE *tree)③后序遍历,递归方法re_postOrder(TREE *tree)(2)调用上述函数实现先序、中序和后序遍历二叉树操作。

算法设计分析(一)数据结构的定义要求用c语言编写一个演示程序,首先建立一个二叉树,让用户输入一个二叉树,实现该二叉树的便利操作。

二叉树型存储结构定义为:typedef struct TNode{ char data;//字符型数据struct TNode *lchild,*rchild;//左右孩子指针}TNode,* Tree;(二)总体设计程序由主函数、二叉树建立函数、先序遍历函数、中序遍历函数、后序遍历函数五个函数组成。

其功能描述如下:(1)主函数:统筹调用各个函数以实现相应功能。

int main()(2)二叉树建立函数:根据用户意愿运用先序遍历建立一个二叉树。

int CreateBiTree(Tree &T)(3)先序遍历函数:将所建立的二叉树先序遍历输出。

void PreOrder(Tree T)(4)中序遍历函数:将所建立的二叉树中序遍历输出。

void InOrder(Tree T)(5)后序遍历函数:将所建立的二叉树后序遍历输出。

void PostOrder(Tree T)(三)各函数的详细设计:(1)建立一个二叉树,按先序次序输入二叉树中结点的值(一个字符),‘#’表示空树。

对T动态分配存储空间,生成根节点,构造左、右子树(2)编写先序遍历函数,依次访问根节点、左子结点、右子节点(3)编写中序遍历函数,依次访问左子结点、根节点、右子节点(4)编写后序遍历函数,依次访问左子结点、右子节点、根节点(5)编写主函数,调用各个函数,以实现二叉树遍历的基本操作。

二叉树的先序、中序、后序递归与非递归实现遍历

二叉树的先序、中序、后序递归与非递归实现遍历

⼆叉树的先序、中序、后序递归与⾮递归实现遍历//定义⼆叉树结点struct BiTreeNode{int data;BiTreeNode* left;BiTreeNode* right;};⼀、递归实现//先序void preOrder(BiTreeNode *root){cout<<root->data;preOrder(root->left);preOder(root->right);}//中序void inOrder(BiTreeNode *root){preOrder(root->left);cout<<root->data;preOder(root->right);}//后序void postOrder(BiTreeNode *root){preOrder(root->left);preOder(root->right);cout<<root->data;}以上的cout<<root->data;是对结点的⼀种操作,这⾥可以对结点做任意想做的操作。

⼆、⾮递归实现//先序void preOrderS(Node *root){stack<Node*> s;Node *p=root;while(p!=NULL||!s.empty()){//沿着左⽀⾛到底//⽤栈记录⾛过的路径while(p!=NULL){cout<<p->data<<"";s.push(p);p=p->left;}//当左⽀⾛到尽头时,若栈⾥边还有结点//则退栈,后退到跟结点,并且向右⽀前进//此时p!=NULL,会进⼊以上while循环if(!s.empty()){p=s.top();s.pop();p=p->right;}}}//注:在 if(!s.empty())中,获取根结点只是为了得到往右⽀的中转,//当获得右⽀指针后,将根结点从栈中弹出,以便返回的时候直接//回到爷爷结点//中序void inOrderS(Node *root){stack<Node*> s;Node *p=root;while(p!=NULL||!s.empty()){while(p!=NULL)){s.push(p);p=p->left;}if(!s.empty()){p=s.top();s.pop();cout<<p->data;p=p->right;}}}//中序遍历和先序遍历的代码⼏乎⼀致,除了访问点的位置不⼀样//中序遍历是在退栈的时候访问根结点//后序void PostOrderS(Node *root) {Node *p = root, *r = NULL;stack<Node*> s;while (p!=NULL || !s.empty()) {if (p!=NULL) {//⾛到最左边s.push(p);p = p->left;}else {p = s.top();if (p->right!=NULL && p->right != r)//右⼦树存在,未被访问p = p->right;else {s.pop();visit(p->val);r = p;//记录最近访问过的节点p = NULL;//节点访问完后,重置p指针}}//else}//while}//因为后序⾮递归遍历⼆叉树的顺序是先访问左⼦树,再访问右⼦树,最后访问根节点。

二叉排序树 先序遍历 中序遍历 后序遍历(非递归)

二叉排序树 先序遍历 中序遍历 后序遍历(非递归)
int rs[100];int ls[100];//rs[],ls[]数组存放的是“当前结点”的左、右结点是否访问.
int j;
for(j=0; j<100 ;j++)
{
rs[j] =0;ls[j] =0;
}
while( i != 0)
{
if(i==1 && k == 0)
{
q[i] = T;
printf("%d\n",q[i]->data);
}
while(T->left && ls[i] == 0)
{
T =T->left;
ls[i] = 1;
i++; q[i] = T;k++;
ls[i] =0; rs[i] = 0;
printf("%d,",q[i]->data);
}
if(( T->left ==NULL && T->right && rs[i] ==0 ) || (ls[i] ==1 && T->right&& rs[i] ==0 ) )
int k ; k = 0;
int rs[100];int ls[100]; int j;
for(j=0; j<100 ;j++)
{
rs[j] =0;ls[j] =0;
}
while( i != 0)
{
while(T->left && ls[i] == 0)
{
T =T->left;

数据结构二叉树前中后序非递归遍历

数据结构二叉树前中后序非递归遍历

数据结构《实验2》实验报告实验项目2:二叉树前序、中序非递归遍历学号姓名课程号实验地点指导教师时间评语:按时完成实验;实验内容和过程记录完整;回答问题完整、正确;实验报告的撰写认真、格式符合要求;无抄袭的行为。

成绩教师签字二叉树中序、后序非递归遍历1、预习要求:二叉树结构定义。

2、实验目的:(1)了解二叉树结构遍历概念;(2)理解二叉树二种不同遍历过程;(3)掌握二叉树遍历算法程序。

3、实验内容及要求:(1)建立包含10个结点的二叉树(树结构和数据元素的值由自己设定);(2)完成二叉树非递归遍历程序;(3)给出程序和每种遍历程序的结果。

4、实验设备(环境)及要求硬件:支持 Intel Pentium Ⅱ及其以上 CPU ,内存 128MB 以上、硬盘 1GB 以上容量的微机。

软件:配有 Windows98/2000/XP 操作系统,安装 Visual C++ 。

5、实验时间:10学时6、该文档的文件名不要修改,存入<学号> <姓名> 命名的文件夹中7、该表中的数据只需填空,已有内容不要修改实验结果(运行结果界面及源程序,运行结果界面放在前面):依次是前序,中序,后序遍历的截屏#define STUDENT EType#include<iostream.h>#include <stdlib.h>#include<string.h>#include<math.h>#include<iomanip.h>//二叉树链式结构定义struct STUDENT{char name[10];char number[12];char place[10];char sex[3];int age;};struct BinaryTreeNode{EType data;BinaryTreeNode *LChild;BinaryTreeNode *RChild;};typedef BinaryTreeNode BinaryTree; //堆栈结构定义struct SType{BinaryTreeNode *ptr;bool status;};struct Stack{SType *element;int top;int Maxsize;};struct Node_Ptr{BinaryTreeNode *ptr;} ;void DigitalToString(char str[],int n){char temp;char k=1;int i=0;while (n && i<80){k=n%10+48;n=n/10;str[i]=k;i++;}str[i]='\0';int len=strlen(str);for (i=0;i<len/2;i++){temp=str[i];str[i]=str[len-i-1];str[len-i-1]=temp;}}void CreatStack(Stack &S,int MaxStackSize) {//构造一个最大容量为MaxStackSize的堆栈S.Maxsize=MaxStackSize;S.element=new SType[S.Maxsize];S.top=-1;}bool IsEmpty(Stack &S){//判断堆栈是否为空if(S.top==-1)return true;return false;}bool IsFull(Stack &S){//判断堆栈是否为满if(S.top>= S.Maxsize-1)return true;elsereturn false;}bool GetTop(Stack &S,SType &result){//返回堆栈S中栈顶元素if(IsEmpty(S))return false;result=S.element[S.top];return true;}bool Pop(Stack &S,SType &result){//将S栈顶的值取至result中,返回出栈后的状态if(IsEmpty(S))return false;result.ptr=S.element[S.top].ptr;result.status=S.element[S.top].status;S.top--;return true;}bool Push(Stack &S,SType &result){//result进s栈,返回进栈后的状态值if(IsFull(S))return false;S.top++;S.element[S.top]=result;//S.element[S.top].status=result.status;return true;}//构造一棵二叉树BinaryTree * MakeNode(EType &x){//构造节点BinaryTree *ptr;ptr=new BinaryTreeNode;if(!ptr) return NULL;ptr->data=x;ptr->LChild=NULL;ptr->RChild=NULL;return ptr;}void MakeBinaryTree(BinaryTree *root,BinaryTree *left,BinaryTree *right){//链接root,left,right所指的节点指针为二叉树root->LChild=left;root->RChild=right;}void BinaryDelete(BinaryTree *BT){//二叉树的删除if(BT){BinaryDelete(BT->LChild);BinaryDelete(BT->RChild);delete BT;}}char *GetOuputInformationString(int WidthOfData, char *OutputInformation, char*outputstring){//将一个元素的字符串OutputInformation转换为宽度为WidthOfData的等长字符串outputstring//例如,姓名是由四个字符组成,而WidthOfData为8,则在姓名字符串的两边分别连接两个字符,形成8个长度的字符串int left_space,right_space;int i;char left_space_string[16]={""};char right_space_string[16]={""};int add_space;int len_OutputInformation=strlen(OutputInformation); //计算OutputInformation的字符个数add_space=WidthOfData - len_OutputInformation; //计算需要补充的字符个数left_space=add_space/2; //计算OutputInformation左边需要补充的字符个数right_space=add_space-left_space; //计算OutputInformation右边需要补充的字符个数for(i=1;i<=left_space;i++) //形成OutputInformation左边需要补充的空格字符串strcat(left_space_string," ");for(i=1;i<=right_space;i++) //形成OutputInformation右边需要补充的空格字符串strcat(right_space_string," ");//在OutputInformation左边和右边连接需要补充的空格字符串strcpy(outputstring,left_space_string);strcat(outputstring,OutputInformation);strcat(outputstring,right_space_string);return outputstring; //返回WidthOfData宽度的outputstring}char *GetOuputInformation(int item, int k, char *outputInformation, Node_Ptr*element){switch(item){/*case 1: //线索树特有的处理与一般二叉树不同之处,在姓名的两边连接线索标志{if(element[k].ptr->Lflag)strcpy(outputInformation,"1");elsestrcpy(outputInformation,"0");strcat(outputInformation,element[k].ptr->);if(element[k].ptr->Rflag)strcat(outputInformation,"1");elsestrcat(outputInformation,"0");break;}*/case 1:{strcat(outputInformation,element[k].ptr->data.number);break;}case 2:{strcat(outputInformation,element[k].ptr->);break;}case 3:{strcat(outputInformation,element[k].ptr->data.sex);break;}case 4:{DigitalToString(outputInformation,element[k].ptr->data.age);break;}case 5:{strcat(outputInformation,element[k].ptr->data.place);break;}default: break;}return outputInformation;}void OutputBinaryTree(BinaryTreeNode *BT){Node_Ptr temp,*element;BinaryTreeNode *p;int MaxSize;int BinaryTreeHigh;int i,j,k;BinaryTreeHigh=5; //BinaryHeight(BT);MaxSize=(int) pow(2,BinaryTreeHigh);element = new Node_Ptr [MaxSize+1]; //定义一个用于存放二叉树结点指针的数组for (i=1;i<=MaxSize;i++) //对指针数组初始化,初值设为NULL element[i].ptr=NULL;p = BT;temp.ptr = p;if (p) element[1]=temp;for (i=1;i<=MaxSize;i++) //将二叉树中的每个结点指针以顺序存储结构存放到数组中{p=element[i].ptr;if (p){if (p->LChild){temp.ptr = p->LChild;element[2*i]=temp;}if (p->RChild){temp.ptr = p->RChild;element[2*i+1]=temp;}}}int WidthOfData=5;int IntervalOfData=3;// cout<<"WidthOfData="<<WidthOfData<<endl;// cout<<"IntervalOfData="<<IntervalOfData<<endl;// cout<<"BinaryTreeHigh="<<BinaryTreeHigh<<endl;int position_of_central[6][17]; //存放每一元素输出位置中心(距离屏幕左边界的字符数)int row,col; //二维数组的行列下标变量for(i=0;i<=BinaryTreeHigh;i++) //存放每一元素输出位置中心(距离屏幕左边界的字符数),初值为0for(j=0;j<=pow(2,BinaryTreeHigh-1);j++)position_of_central[i][j]=0;for(i=1;i<=pow(2,BinaryTreeHigh)-1;i++) //对深度为BinaryTreeHigh的满二叉树的所有结点计算每个结点输出的中心点位置{k=i*2; //k指向i的左子树根结点while (k<=pow(2,BinaryTreeHigh)-1) //k不断推进到i编号的结点左子树中最右子孙结点k=2*k+1;k=k/2; //k的值就是i编号的结点左子树中最右子孙结点的编号j=(int)(k-(pow(2,(BinaryTreeHigh-1))-1)); //由k编号的结点换算出该结点是底层中从左至右第j个结点右上方//即编号为k的结点中心点垂直线左边最底层上有j个结点row=(int)(log10(i)/log10(2)+1); //计算中心点值存放在position_of_central[row][col]中的rowcol=(int)(i-(pow(2,(row-1))-1)); //计算中心点值存放在position_of_central[row][col]中的colif(row==BinaryTreeHigh)//计算底层i结点距离左边界的字符数,左边无间隙position_of_central[row][col]= (j-1)*WidthOfData + (j-1)*IntervalOfData + (WidthOfData/2 +1);else//计算非底层i结点距离左边界的字符数,position_of_central[row][col]=j*WidthOfData + (j-1)*IntervalOfData + (IntervalOfData/2 +1);}char prespace[100];int m;int kk;int kkk;int item_max=5;cout<<endl;for(i=1;i<=BinaryTreeHigh;i++){kkk=(int)pow(2,i-1); //kkk是满二叉树中每一层第1个结点的编号for(int item=1;item<=item_max;item++) //输出每个数据元素多个item成员的值{int half_len_pre_value=0; //同一行前一个输出的元素值长度的一半,同一行第一个输出的元素值前没有值输出,初值为0int half_len_now_value=WidthOfData/2;//同一行当前输出的元素值长度的一半,其值始终为WidthOfData的一半kk=kkk; //kk是满二叉树中每一层结点的编号变化,从某层的最左边第一个结点编号kkk开始for(j=1;j<=pow(2,i-1);j++) //输出满二叉树中同一层次上的每个数据元素的同一个成员的值{char outputInformation[20]={""};char *OutputInformation;if (element[kk].ptr) //获取每个数据元素的一个成员的值OutputInformation,如姓名、年龄等OutputInformation=GetOuputInformation(item,kk,outputInformation,element);if (position_of_central[i][j]) //输出数据中点值存在时,position_of_central[i][j]非0{char outputstring[80]={""};char *OutputString;//下面语句将每个数据元素的一个成员的值OutputInformation,如姓名、年龄等,转换为等长WidthOfData的字符串OutputStringOutputString=GetOuputInformationString(WidthOfData,OutputInformation,outputstring);//生成两个孩子之前的空格串prespace//构成:<前导空格串>=<两个输出数据中心点之差> - <前一个输出元素值长度一半> - <当前输出元素值长度的一半>strcpy(prespace,"");m=(position_of_central[i][j]-position_of_central[i][j-1]-1-half_len_pre_value-half_len_now_ value);for(k=1;k<=m;k++)strcat(prespace," ");cout<<prespace;cout<<OutputString;half_len_pre_value=WidthOfData/2; //调整同一行前一个输出的元素值长度为WidthOfData的一半kk++;}// if (position_of_central[i][j])}//for(j=1;j<=pow(2,i-1);j++)cout<<endl;}//for(int item=1;item<=5;item++)char line[3]="─";char OutputLine[80];char midspace[80];int nodenumber;if(i==1) //对深度为BinaryTreeHigh的满二叉树从上至下,从左至右的编号,计算第i层上起始结点的编号nodenumbernodenumber=1;elsenodenumber=(int)((pow(2,i)-1)-(pow(2,i-1)-1)); //第i(i!=1)层上的第1个结点编号nodenumberfor(j=1;j<=pow(2,i-1);j++) //输出同一层次上的线条{if(i==BinaryTreeHigh) break; //最底层下面没有线条,所以break//生成两个数据元素之前的前导空格串prespacestrcpy(prespace,"");m=(position_of_central[i+1][j]-position_of_central[i+1][j-1]-1);for(k=1;k<=m;k++)strcat(prespace," ");//计算左右两个孩子之间一半的连线OutLine,由若干个line"─"构成//注意line是汉字字符,一个占两个字符位,m是左右两个孩子之间的line"─"数,所以m要除4strcpy(OutputLine,"");m=(position_of_central[i+1][j+1]-position_of_central[i+1][j]-1)/4;for(k=1;k<=m;k++)strcat(OutputLine,line);//计算左右两个孩子之间一半的空格字符的个数m,,所以要除2。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

《数据结构》实验报告
◎实验题目: 创建并遍历二叉树
◎实验目的:熟悉二叉树存储结构,熟悉二叉树的三种遍历方法,并能用非递归的方法建立并且遍历二叉树。

◎实验内容:用先序和中序建立二叉树,用后序遍历并输出二叉树,要求算法非递归。

一、需求分析
该程序用非递归的方法,利用先序和中序建立二叉树,然后用后序遍历的方法输出二叉树的元素。

1、输入的形式和输入值的范围;
程序运行时输入二叉树的先序和中序序列,为字符型元素。

2、输出的形式;
运行结果为输出二叉树的后序序列,亦为字符型元素。

3、程序所能达到的功能;
本程序可以建立一个二叉树存储结构,并且访问其结点元素。

4、测试数据:
输入:先序:abcde
中序:edcba
输出:后序:edcba
二概要设计
1. 本程序中首先需定义二叉树的节点类型,节点为一个含有数据与和指针域的结构体。

2. 其次,本程序中需要用两个栈,一个用来存放指针,一个用来存放数组元素的下标。

3. 主程序中,分别输入两个字符串,作为二叉树的先序和中序序列;两个子函数分别实现创建二叉树和后序遍历输出二叉树的功能。

而在子函数中还调用了例如出栈入栈等子函数。

三详细设计
1. 定义二叉树节点类型
struct node
{
char data;
struct node *lchild;
struct node *rchild;
}BTree;
2.定义两个栈的类型
struct snode
{
int top;
int a[MAX];
};
struct snode1
{
int top;
struct node *c[MAX];
};
3.主函数
void main()
{
char a[MAX]={0};
char b[MAX]={0};
char c=0,d=0;
int i=0,j=0;
struct node *g;
snode s;
snode1 s4,s1;
Initstack(&s);
Initstack1(&s4);
Initstack1(&s1);
printf("请输入先序序列:\n");
while(c!='\n')
{
c=getchar();
a[i]=c;
i++;
}
printf("请输入中序序列:\n");
while(d!='\n')
{
d=getchar();
b[j]=d;
j++;
}
g=create(&s,&s1,a,b);
printf("遍历输出后序序列:\n");
visit(&s4,g);
printf("\n");
}
4. 子函数一,创建二叉树
struct node * create(snode *s,snode1 *s1,char a[MAX],char b[MAX]) {
int i=1,num,x;
struct node *p,*q,*r,*root;
p=(struct node *)malloc(sizeof(BTree));
p->lchild=NULL;
p->rchild=NULL;
p->data=a[0];
root=p;
x=seek(a[0],b);
push(s,x);
push1(s1,p);
while(a[i]!='\n')
{
num=seek(a[i],b);
p=(struct node *)malloc(sizeof(BTree)); p->lchild=NULL;
p->rchild=NULL;
p->data=a[i];
if(num<gettop(s))
{
q=get(s1);
q->lchild=p;
push(s,num);
push1(s1,p);
}
else if(num>gettop(s))
{
while(s->top!=-1&&num>gettop(s))
{
r=pop1(s1);
pop(s);
}
r->rchild=p;
push(s,num);
push1(s1,p);
}
i++;
}
return root;
}
5. 子函数二,后序遍历输出二叉树
void visit(snode1 *s,struct node *root)
{
struct node *p;
p=root;
do
{
while(p!=NULL)
{
push1(s,p);
p=p->lchild;
}
while(s->top!=-1&&give(s)->rchild==p)
{
p=pop1(s);
printf("%c",p->data);
}
if(s->top!=-1)
p=give(s)->rchild;
}while(s->top!=-1);
}
四使用说明、测试分析及结果
1、说明如何使用你编写的程序;
程序名为4.exe,运行环境为visual C++。

程序执行后显示:请输入先序序列:
输入元素后显示
请输入中序序列:
然后程序自动运行,输出
遍历输出后序序列:以及结果
2、测试结果与分析;
请输入先序序列: abcde
请输入中序序列: edcba
遍历输出后序序列:edcba
3、运行界面。

五、实验总结
你在编程过程中花时多少?
五个小时
多少时间在纸上设计?
半个小时
多少时间上机输入和调试?
四个小时,主要是用来调试,程序编写完成后有很多错误,需要一个个的找,有些错误看起来没什么问题,所以用了很长时间。

你的收获有哪些?
用非递归法建立二叉树,让我们对于二叉树的建立过程掌握得更加清楚明了。

用先序中序建立,用后序遍历,让我们对于二叉树的三种遍历方法都能掌握。

教师评语:
实验成绩:
指导教师签名:
批阅日期:(注:可编辑下载,若有不当之处,请指正,谢谢!)。

相关文档
最新文档