数据结构-二叉树的基本操作
2017-11-05 10:04
465 查看
目标效果:
dsp0603.cpp页面;
bintree.h页面:
说几个小问题:
1.项目里有层次遍历,需要使用队列存储,我偷懒直接复制的前边博客里循环队列操作的代码,结果出现以下错误,return还不变成蓝色(code blocks中return等关键字是蓝色),百度是因为中文空格和英文空格的原因,只要把空格都删掉然后重新在英文输入法中把空格重新敲一遍就行了的。
2.循环队列我定义了100个元素,这也就意味着层次遍历时,结点个数最多为99个,不知道循环队列插入时判满后能不能再进行动态分配,课本上是没讲的,如果不能的话存储用链式队列比较好,对个数没要求。
3.凹入打印那里,因为空格个数递减,所以我是用一个初始值10减去一个递增变量,正确初始值应该为树的深度,因为每一层的长度一样,最多有个数为深度的不同凹入情况,但是因为输入的都是简单树,加上循环队列那里就对结点个数有要求了,所以这里就不那样写了,自己明白就好。
我的项目一般都会在学校机房里做前半部分,环境为VC6.0,后半部分是在自己电脑上做的,环境为code blocks,最近几次在电脑上都是新建一个项目,删掉main函数后导入几个操作页面,但是修改后还是修改的原先那个vc项目,并且在原项目中是运行的之前的结果的,我上传的也是原项目,所以如果下载源码,不要直接运行debug中的那个exe文件,打开后编译运行一下就好。
源码链接:点击打开链接
dsp0603.cpp页面;
#include <stdio.h> #include <stdlib.h> #define ElemType char //二叉树中数据元素类型 #include "bintree.h" //二叉树的实现 //打印结点数据(作为Visit函数) Status print(char); //计算二叉树中叶子结点的个数 int LeafCount(BiTree bt); //计算二叉树的深度 int Deapth(BiTree bt); //按缩进方式打印二叉树 void PrintTreeIndent(BiTree bt, int indent); /////////////////////////////////////////////////////////// // 主程序 int main() { BiTree bt = 0; //建立二叉树 printf("建立二叉树(按先序输入二叉树中的结点,空格表示空树)\n"); if( CreateBiTree(bt)==ERROR ) { printf("ERROR: call CreateBiTree\n"); system("pause"); exit(1); } PrintTree(bt); //遍历二叉树 printf("\n先序遍历: "); if( PreOrderTraverse(bt)==ERROR ) printf("ERROR: call PreOrderTraverse\n"); printf("\n中序遍历: "); if( InOrderTraverse(bt)==ERROR ) printf("ERROR: call InOrderTraverse\n"); printf("\n后序遍历: "); if( PostOrderTraverse(bt)==ERROR ) printf("ERROR: call PostOrderTraverse\n"); printf("\n按层遍历: "); if( LevelOrderTraverse(bt)==ERROR ) printf("ERROR: call LevelOrderTraverse\n"); //二叉树的应用 printf("\n二叉树中叶子结点的个数: %d\n", LeafCount(bt)); printf("\n二叉树的深度: %d\n", Deapth(bt)); printf("\n按缩进形式打印:\n"); PrintTreeIndent(bt,1); //销毁二叉树 DestroyBiTree(bt); system("pause"); //暂停以便查看结果 return 0; } /////////////////////////////////////////////////////////// // 函数实现 //计算二叉树中叶子结点的个数 int LeafCount(BiTree bt) { if(!bt) //结点为空 return 0; if(!bt->lchild&&!bt->rchild) //没有子节点了 return 1; else return LeafCount(bt->lchild)+LeafCount(bt->rchild); } //计算二叉树的深度 int Deapth(BiTree bt) { int height,leftH,rightH; //左右子树的深度和最深的深度 if(!bt) height=0; else{ leftH=Deapth(bt->lchild); rightH=Deapth(bt->rchild); if(leftH>rightH) height=leftH+1; else height=rightH+1;; } return height; } //按缩进方式打印二叉树 void PrintTreeIndent(BiTree bt, int indent) { if(bt){ for(int i=0;i<10-indent;i++) //这里固定了以10减,正常最规范的应该用树的深度减 printf(" "); printf("%c",bt->data); printf("\n"); PrintTreeIndent(bt->lchild,indent+1); PrintTreeIndent(bt->rchild,indent+1); } }
bintree.h页面:
#ifndef BINTREE_H_INCLUDED #define BINTREE_H_INCLUDED #include <stdlib.h> #include "ds.h" //数据元素的缺省类型用char #ifndef ElemType #define ElemType char #define ELEMTYPE_TAG #endif /*下面使用TElemType如同ElemType*/ #define TElemType ElemType #define QElemType BiTree //队列元素为二叉树指针类型,所以这里不是普通的char类型 #define MAXQSIZE 100 /////////////////////////////////////////////////////////// // 二叉链表类型 typedef struct BiTNode { TElemType data; struct BiTNode *lchild, *rchild; //左右孩子指针 } BiTNode, *BiTree; //循环队列类型定义 typedef struct{ QElemType *base; int front; int rear; }SqQueue; //初始化队列 Status InitQueue(SqQueue &Q); //元素入队 Status EnQueue(SqQueue &Q,QElemType e); //元素出队 Status DeQueue(SqQueue &Q,QElemType &e); //销毁队列 Status DestroyQueue(SqQueue &Q); //队列判空 Status QueueEmpty(SqQueue Q); // 二叉链表的基本操作 //新建二叉链表结点 BiTree MakeNode(TElemType e, BiTree lch, BiTree rch) { BiTree p = (BiTree)malloc(sizeof(BiTNode)); p->data = e; p->lchild = lch; p->rchild = rch; return p; } //按先序次序输入二叉树中的结点值(字符)构造二叉树 Status CreateBiTree(BiTree &T) { char ch; read(ch); // NOTE: 这里用字符类型 if( ch==' ' ) //空格代表空指针 T = 0; else { T=(BiTree)malloc(sizeof(BiTNode)); if(!T) return ERROR; else{ T->data=ch; CreateBiTree(T->lchild); CreateBiTree(T->rchild); } } return OK; } //销毁二叉树 Status DestroyBiTree(BiTree &T) { T=NULL; return OK; } //先序遍历二叉树T,对每个结点数据调用Visit函数 Status PreOrderTraverse(BiTree T) { if(T){ printf("%c",T->data); PreOrderTraverse(T->lchild); PreOrderTraverse(T->rchild); } return OK; } //中序遍历二叉树T,对每个结点数据调用Visit函数 Status InOrderTraverse(BiTree T) { if(T){ InOrderTraverse(T->lchild); printf("%c",T->data); InOrderTraverse(T->rchild); } return OK; } //后序遍历二叉树T,对每个结点数据调用Visit函数 Status PostOrderTraverse(BiTree T) { if(T){ PostOrderTraverse(T->lchild); PostOrderTraverse(T->rchild); printf("%c",T->data); } return OK; } //按层次顺序遍历二叉树T,对每个结点数据调用Visit函数 Status LevelOrderTraverse(BiTree T) { //将每一层的节点分别入队列,然后分别读取,读取后继续将它们的子节点入队,所以保证是按照一层一层来遍历的 BiTree P=T; SqQueue Q; InitQueue(Q); //初始化队列 if(P) { EnQueue(Q,P); while(!QueueEmpty(Q)) { DeQueue(Q,P); //出队列 printf("%c",P->data); if(P->lchild) EnQueue(Q,P->lchild); if(P->rchild) EnQueue(Q,P->rchild); } } DestroyQueue(Q); return OK; } //以直观方式打印二叉树 void PrintTree(BiTree t, int level=0) { int i; if(t) { PrintTree(t->rchild, level+1); for(i=0; i<level; i++) printf(" "); write(t->data); write('\n'); PrintTree(t->lchild, level+1); } } //构造一个空队列 Status InitQueue(SqQueue &Q) { Q.base=(QElemType *)malloc(MAXQSIZE*sizeof(QElemType)); if(!Q.base) return ERROR; Q.front=Q.rear=0; return OK; } //元素入队 Status EnQueue(SqQueue &Q,QElemType e) { if((Q.rear+1)%MAXQSIZE==Q.front) return ERROR; Q.base[Q.rear]=e; Q.rear=(Q.rear+1)%MAXQSIZE; return OK; } //元素出队 Status DeQueue(SqQueue &Q,QElemType &e) { if(Q.front==Q.rear) return ERROR; e=Q.base[Q.front]; Q.front=(Q.front+1)%MAXQSIZE; return OK; } //判断队列是否为空 Status QueueEmpty(SqQueue Q) { if(Q.rear==Q.front) return OK; else return ERROR; } //销毁队列 Status DestroyQueue(SqQueue &Q) { if(!Q.base) return ERROR; Q.rear=Q.front; free(Q.base); return OK; } //取消缺省类型的定义以免影响其它部分 #ifdef ELEMTYPE_TAG #undef ElemType #undef ELEMTYPE_TAG #endif #endif //BINTREE_H_INCLUDED
说几个小问题:
1.项目里有层次遍历,需要使用队列存储,我偷懒直接复制的前边博客里循环队列操作的代码,结果出现以下错误,return还不变成蓝色(code blocks中return等关键字是蓝色),百度是因为中文空格和英文空格的原因,只要把空格都删掉然后重新在英文输入法中把空格重新敲一遍就行了的。
2.循环队列我定义了100个元素,这也就意味着层次遍历时,结点个数最多为99个,不知道循环队列插入时判满后能不能再进行动态分配,课本上是没讲的,如果不能的话存储用链式队列比较好,对个数没要求。
3.凹入打印那里,因为空格个数递减,所以我是用一个初始值10减去一个递增变量,正确初始值应该为树的深度,因为每一层的长度一样,最多有个数为深度的不同凹入情况,但是因为输入的都是简单树,加上循环队列那里就对结点个数有要求了,所以这里就不那样写了,自己明白就好。
我的项目一般都会在学校机房里做前半部分,环境为VC6.0,后半部分是在自己电脑上做的,环境为code blocks,最近几次在电脑上都是新建一个项目,删掉main函数后导入几个操作页面,但是修改后还是修改的原先那个vc项目,并且在原项目中是运行的之前的结果的,我上传的也是原项目,所以如果下载源码,不要直接运行debug中的那个exe文件,打开后编译运行一下就好。
源码链接:点击打开链接
相关文章推荐
- PHP数据结构之九 PHP储存二叉树,二叉树的创建与二叉树的基本操作 遍历二叉树算法
- 二叉树的基本操作(定义、遍历、高度、生成)【数据结构】
- 算法与数据结构-二叉树的基本操作C语言实现
- 数据结构->二叉树的基本操作
- 数据结构 【实验7 二叉树基本操作】
- 数据结构--二叉树(链表)基本操作
- 二叉树构建和基本操作【数据结构】
- 数据结构_二叉树的基本操作
- 一步一步复习数据结构和算法基础-二叉树基本操作
- 【数据结构】二叉树基本操作的程序实现
- 【数据结构】二叉树的简单遍历及基本操作
- 【数据结构】线索化二叉树的基本操作
- 数据结构:二叉树的基本操作(JAVA实现)
- [数据结构] 二叉树的建立及其基本操作
- 【数据结构】二叉树的基本操作
- 数据结构类型定义及基本操作汇总(二)-- 二叉树及其遍历
- 【 数据结构】实现二叉树以及其基本操作
- javascript实现数据结构: 树和二叉树,二叉树的遍历和基本操作
- 【数据结构】二叉树的基本操作
- 数据结构:树与二叉树_二叉树_二叉树的基本操作