任务概述:
(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. CUDA硬件架构知识
  2. Web.Config文件配置之限制上传文件大小和时间
  3. 【第二组】项目冲刺(Beta版本)第六次每日例会 2017/7/24
  4. 摩卡业务服务管理 全面彰显强大产业推动优势——神华集团神东煤炭分公司
  5. [转]MPlayer快捷键参数设置--系统开销最少的影音播放器
  6. mysql升级后乱码_Mysql转换或者升级以后出现乱码情况的说明
  7. [转]撞车之后,不要傻里傻气的!这里有绝招!
  8. 师妹问我:如何在7分钟内彻底搞懂word2vec?
  9. play商店 小米_小米应用商店和Google Play商店的简单对比
  10. 阿里云的认证多少分通过?没通过可以补考吗?
  11. 网站被降权了怎么办?被降权后的正确处理方法
  12. 百面机器学习 #2 模型评估:0102 精确率与召回率,假阳性与真阳性率,PR曲线和ROC曲线
  13. 快牛策略——嵌入式计算机
  14. 深度学习 噪声抑制_使用深度学习抑制噪声
  15. 灾难恢复_有效的灾难恢复计划的10个技巧
  16. WP篇 创新实践能力赛(华东南分区赛)线下AWD复现
  17. ubuntu之daemon
  18. 如何借助ImageAI轻松实现目标检测(只需十行代码)
  19. 烟雾传感器模块资料(MQ-2)
  20. 藏在80年代的儿时游戏里的”通证经济“

热门文章

  1. 8088单板机串口驱动代码测试
  2. 联想拯救者wif开不了_联想R720怎么开不了WiFi?
  3. printf 输出格式设置\033[47\033[5m 与-8.8s
  4. iphone6s计算机驱动,iPhone 6s驱动安装失败解决办法【详解】
  5. 6大行数字人民币推送子钱包扩大使用范围
  6. 2021年中国化学制品市场趋势报告、技术动态创新及2027年市场预测
  7. 【引语练习题】直接引语与间接引语
  8. Android开发 自定义ViewGroup 实现微信九格图功能(图片不同排布不同) 和 一种图片点击变暗效果
  9. 转载:算法工程师过去这一年:理想很丰满,现实很骨感
  10. 计算机视觉(三):基于Scipy图像处理技术,图像模糊(灰色、彩色图像高斯模糊)、图像导数(sobel算子滤波)