任务概述:
(1)采用孩子双亲表示法,创建一棵一般的树,初始化树后添加孩子及其双亲结点,要求从键盘输入树中结点,并且结点数不少于五个;
(2)将树转成对应的二叉树,将结点的第一个孩子作为其左孩子,其余孩子作为其左孩子的右孩子;
(3)实现转换后二叉树的前序、中序、后序的递归遍历算法的实现;
(4)利用栈实现转换后二叉树的前序、中序、后序的非递归遍历算法的实现。
存储结构:

#include <stdio.h>
#include <stdlib.h>
#define OVERFLOW -2
#define OK 0
#define ERROR 0
#define STACK_INIT_SIZE 100//存储空间初始分配量
#define STACKINCREMENT 10//存储空间分配增量
#define MAX_TREE_SIZE 21//树的结点数目最大值
//>>>>>>>>>>>>>>>>>>>>>>>>>>>自定义数据类型<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
typedef int Status;//函数返回值状态码类型
typedef char  ElemType;//树中结点元素类型
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>结构体定义<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//孩子结构
typedef struct CTNode
{int child;//孩子结点的下标struct CTNode *next;//指向下一个结点的指针
}*ChildPtr;
//表头结构
typedef struct
{ElemType data;//存放在树中的结点的数据int parent;//存放双亲的下标ChildPtr firstchild;//指向第一个孩子的指针
}CTBox;
//树结构
typedef struct
{CTBox tree[MAX_TREE_SIZE];//结点数组int n;//结点数目
}CTree;
//二叉树结点,左孩子,右孩子
typedef struct BTNode
{ElemType data;struct BTNode *lchild,*rchild;
}BTNode,*BTree;
typedef BTree SElemType;
//栈的结构体
typedef struct{SElemType *base;//在栈构造和销毁之后,base的值为NULL SElemType *top;//栈顶指针 int stacksize;//当前已分配的存储空间
}Stack;
//--------------------------------1.采用孩子双亲表示法创建一棵一般的树-------------------------------
void InitCtree(CTree &T)
{//初始化树 int i;printf("请输入树的结点个数:");scanf("\n%d",&T.n);printf("依次输入各个结点:\n"); for(i=0; i<T.n; i++){fflush(stdin);//清理标准输入流,把多余的未被保存的数据丢掉 T.tree[i].data = getchar();T.tree[i].parent = 0;T.tree[i].firstchild = NULL; }
}
void AddChild(CTree &T)
{//添加孩子int i,j,k;printf("-----------------------添加孩子及其双亲结点------------------------------------------\n");           for(k=0; k<T.n; k++){fflush(stdin); //清理标准输入流,把多余的未被保存的数据丢掉printf("请输入孩子结点及其双亲结点的序号:(用空格隔开)\n");scanf("%d %d",&i,&j); fflush(stdin);CTNode *p = (CTNode *)malloc(sizeof(CTNode));p->child = i;p->next = NULL;T.tree[i].parent = j;//找到双亲 if(!T.tree[j].firstchild)T.tree[j].firstchild = p;else{CTNode *temp = T.tree[j].firstchild;while(temp->next )temp = temp->next ;temp->next  = p;}}
}
//---------------------------------------2.将树转换成对应的二叉树------------------------------------------
Status ExchangeTree(BTree &BT,CTree &T)
{BTNode *p,*q,*t,*pre;//pre指向p的双亲结点 CTNode *temp;int m=T.n ;if(!(p=(BTNode*)malloc(sizeof(BTNode))))exit (OVERFLOW);int i=0;p->data =T.tree [i].data;p->lchild =NULL;p->rchild =NULL;BT=p;for(i=0;i<m;i++){if(p->data !=T.tree [i].data){if(!p->lchild &&!p->rchild )p=pre;//p没有孩子时,p指向双亲结点 if(p->lchild ){if(T.tree [i].data==p->lchild->data  )pre=p;p=p->lchild ;}if(p->rchild )if(T.tree [i].data==p->rchild ->data)pre=p;p=p->rchild ;}//寻找要转化的根结点 ,让p指向此时要转换的根节点 if(T.tree [i].firstchild){int k=T.tree [i].firstchild->child;q=(BTNode*)malloc(sizeof(BTNode));//为第一个孩子即左孩子分配空间 q->data =T.tree [k].data;q->lchild =NULL;q->rchild =NULL;p->lchild =q;//p指向其左孩子 temp=T.tree [i].firstchild;while(temp->next )//判断是否有兄弟结点 {t=(BTNode*)malloc(sizeof(BTNode));int s=temp->next ->child;t->data =T.tree [s].data;t->lchild =NULL;t->rchild =NULL;q->rchild =t;//右孩子为其兄弟结点 q=q->rchild ; temp=temp->next ; //后移判断是否还有兄弟结点 }}}
}
//-------------------------------------3.遍历二叉树的递归算法-----------------------------------------------
/*先序遍历的递归算法*/void PreOrderTraverse(BTree BT){if(BT){printf("%c ",BT->data );PreOrderTraverse(BT->lchild );PreOrderTraverse(BT->rchild );}}
/*中序遍历的递归算法*/
void InOrderTraverse(BTree BT)
{if(BT){InOrderTraverse(BT->lchild );printf("%c ",BT->data );InOrderTraverse(BT->rchild );}}
/*后序遍历的递归算法*/
void PostOrderTraverse(BTree BT)
{if(BT){PostOrderTraverse(BT->lchild );PostOrderTraverse(BT->rchild );printf("%c ",BT->data );}}
//----------------------------------------4.遍历的非递归算法--------------------------------------------------
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>栈的相关算法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<Status InitStack(Stack &S){//构造一个空栈S.base =(SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));if(!S.base ) exit(OVERFLOW);S.top =S.base ;S.stacksize = STACK_INIT_SIZE;return OK;}  Status Push(Stack &S,SElemType e){//入栈if(S.top -S.base >=S.stacksize ){//栈满S.base =(SElemType*)realloc(S.base ,(S.stacksize+STACKINCREMENT)*sizeof(SElemType));if(!S.base ) exit (OVERFLOW);S.top =S.base +S.stacksize ;S.stacksize += STACKINCREMENT;} *S.top++=e;return OK;} Status Pop(Stack &S,SElemType &e){//出栈if(S.top ==S.base ) return ERROR; e=*--S.top ;return OK;}Status GetTop(Stack S,SElemType &e){//若栈不空,则用e返回S的栈顶元素,并返回OK,否则返回ERRORif(S.top ==S.base ) return ERROR; e=*(S.top -1);return OK;}Status StackEmpty(Stack S){return (S.base ==S.top )?true:false;}
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>栈的相关算法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>遍历的非递归算法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
/*先序遍历的非递归算法*/ void PreOrder(BTree BT){Stack S;BTree p=BT;InitStack(S);while(p||!StackEmpty(S)){if(p){Push(S,p);printf("%c ",p->data );p=p->lchild ;}else{Pop(S,p );p=p->rchild ;}}  }
/*中序遍历的非递归算法*/
void InOrder(BTree BT){Stack S;BTree p=BT;InitStack(S);while(p||!StackEmpty(S)){if(p){Push(S,p );p=p->lchild ;}else{Pop(S,p );printf("%c ",p->data );p=p->rchild ;}}  }
/*后序遍历的非递归算法*/
/*步骤:
对于树中任意一个访问的节点p可以分情况讨论
1. p如果是叶子节点,直接输出
2. p如果有孩子,且孩子没有被访问过,则按照右孩子,左孩子的顺序依次入栈
3. p如果有孩子,而且孩子都已经访问过,则访问p节点*/
void PostOrder(BTree BT){Stack S;SElemType e;BTree p=BT;BTree mark;mark=p;InitStack(S);Push(S,p);while(!StackEmpty(S)){GetTop(S,p);//p等于栈顶指针 if( (p->lchild  == NULL && p->rchild  == NULL) || (p->rchild  == NULL && mark == p->lchild ) || (mark == p->rchild ) )//入栈时按照右孩子,左孩子顺序入栈,则右孩子被标记,左孩子没有或被标记 {printf("%c ",p->data );mark=p;Pop(S,p);} else{if(p->rchild )Push(S,p->rchild );if(p->lchild )Push(S,p->lchild );}} }
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>遍历的非递归算法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//----------------------------------------------主函数--------------------------------------------------------------
main()
{BTree BT;CTree T;SElemType e;printf("--------------------------孩子双亲表示法表示一棵一般的树---------------------------\n");InitCtree(T);AddChild(T);printf("---------------------------------树的创建已完成-------------------------------------\n");ExchangeTree(BT,T);printf("-------------------------------二叉树的转换已完成-----------------------------------\n");printf("------------------------------二叉树的递归遍历算法----------------------------------\n");printf("前序遍历:"); PreOrderTraverse(BT);printf("\n");printf("中序遍历:");InOrderTraverse(BT);printf("\n");printf("后序遍历:");PostOrderTraverse(BT);printf("\n");printf("------------------------------二叉树的非递归遍历算法---------------------------------\n");printf("前序遍历:"); PreOrder(BT);printf("\n");printf("中序遍历:");InOrder(BT);printf("\n");printf("后序遍历:");PostOrder(BT);printf("\n");return 0;}

运行结果:

课程设计 树的应用与实现相关推荐

  1. 设树采用孩子兄弟表示法存放.用类c语言设计算法计算树的高度.,(数据结构课程设计分类题目.doc...

    (数据结构课程设计分类题目 线性表 顺序表: 1.设有一元素为整数的线性表L=(a1,a2,a3,-,an),存放在一维数组A[N]中,设计一个算法,以表中an作为参考元素,将该表分为左.右两部分,其 ...

  2. 十字交叉链表c语言,C语言课程设计报告—十字交叉链表的应用.doc

    C语言课程设计报告-十字交叉链表的应用 PAGE \* MERGEFORMAT 13 华中科技大学计算机科学与技术学院 C语言程序设计课程设计实验报告 题目:水产品养殖信息管理系统 专业: 计算机科学 ...

  3. 《数据结构与算法》课程设计报告——赫夫曼编码/译码器

    题目 赫夫曼编码/译码器 实验目的 本课程设计是为了让同学们了解学习数据结构的作用和意义.数据结构是计算机科学与技术专业的专业基础课,是十分重要的课程.所有的计算机系统软件和应用软件都要用到各种类型的 ...

  4. 大二第一学期期末课程设计 2015.12.28

    <数据结构与算法>课程设计教学任务书 --2015-2016(一)   课程设计周数:2周                                                  ...

  5. 操作系统实验以及课程设计

    趁没人,当个小白来偷偷摸摸补一下操作系统的课程,羞 反正操作系统断断续续的看了一点了,主要是偏linux的.FreeBSD的实现,操作系统概念,30天自制操作系统等.Linux的话命令用的还行,没有很 ...

  6. 拓扑排序和关键路径课程设计

    目录 1.    设计任务书... 3 1.1设计任务... 3 1.2程序功能... 3 1.3运行环境... 3 2.    本组课题... 3 2.1课题... 3 2.2本人任务... 3 3 ...

  7. c语言数据结构五子棋实验报告,数据结构课程设计-五子棋

    数据结构课程设计-五子棋 姓 名: 学 院: 计算机与通信学院 班 级: 通信工程 101 班 指导老师: 目录一.需求分析 31.1 开发背景 .32.2 功能简介 .3二.系统设计 42.1 函数 ...

  8. 数据结构员工通讯录管理系统 C语言,数据结构课程设计报告单位员工通讯录管理系统.doc...

    班级:计科112 学号: 201100814203 姓名:冯贵阳 PAGE PAGE 42 数 据 结 构 课 程 设 计 实 验 报 告 目录 1.单位员工通讯录管理系统(线性表的应用)---- - ...

  9. 数据结构迷宫代码_数据结构课程设计——迷宫求解(二)

    前言 接上文的介绍,本文将主要介绍如何生成随机迷宫,在网上找到的资源也比较多,这里我选取了随机 Prim 算法生成迷宫,选择这个算法的理由如下: 算法思想简单,易于实现 生成的迷宫比较自然,不会出现明 ...

最新文章

  1. Centos7.4安装Nginx
  2. 全球的weex资源都在这里
  3. Silverlight OOB Setup
  4. 如何使用MySQL和JPA使用Spring Boot构建Rest API
  5. JUnit 4和JUnit 5区别
  6. ZebraDesigner-设计label
  7. web逻辑思维题目_学编程必看:10道逻辑思维测试题(附答案)
  8. cvpr 注意力机制_计算机视觉中的注意力机制
  9. coffeescript java 执行_javascript – CoffeeScript中的方法调用语法
  10. What Makes a Good Teacher
  11. Discord教程:Discord账号注册、Discord多账号登录和管理
  12. GlassFish 任意文件读取
  13. 计算机系统盘突然爆满,电脑c盘突然爆满是怎么个情况_电脑c盘和d盘的区别
  14. 从零开始写JavaScript框架
  15. 声明变量和定义变量的区别是什么?
  16. linux服务器odbc在哪看,在Linux上寻找odbc.ini和odbcinst.ini文件的良好文档
  17. 联发科全网通MT6755核心板资料,MT6755芯片模块物联网方案
  18. 深度学习论文笔记(知识蒸馏)—— FitNets: Hints for Thin Deep Nets
  19. 云适配联合IT巨头拟成立“中国企业级HTML5产业联盟”
  20. 用C++求解二元一次方程组

热门文章

  1. 新博系列-3(较好的博文链接)
  2. python元组和列表的联系_Python元组和列表的区别
  3. 交大C语言程设课的题目,让我意识到了自己为什么只读了大专
  4. 关于soapUI模拟返回不同response
  5. SpringBoot 如何配置 Https 以及 443端口被占用问题
  6. C语言静态链接库和动态链接库讲解及制作使用
  7. 春风十里,不如一起看数据的你!
  8. Thin Plate Spline TPS薄板样条变换基础理解
  9. 腾讯云原生数据库 TDSQL-C-产品概述
  10. c语言常用符号优先级问题,【C语言】符号优先级