《二叉树的基本操作》
2015-11-28 20:09
357 查看
#include<stdio.h> #include<stdlib.h> #include<string.h> #define NUM 100 //二叉树的最大结点数 #define QueueSize 100 //队列初始容量 #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define OVERFLOW -1 typedef int Status; //函数结果状态代码 typedef char DataType; //二叉树结点元素类型为char类型 //二叉树的存储结构 typedef struct node { DataType data; //结点元素 struct node *lchild,*rchild; //左右孩子指针 }BinTNode,*BinTree; typedef BinTNode* ElemType; //循环队列存储结构 typedef struct { ElemType *base; int front,rear; }SeQueue; Status CreateBiTree(BinTree &bt) {//按照先序遍历次序递归建立二叉树。 //输入ABC##DE#G##F### char ch; scanf_s("%c",&ch); if(ch == '#') bt = NULL; else { bt = (BinTNode*)malloc(sizeof(BinTNode)); bt->data = ch; //生成根结点 CreateBiTree(bt->lchild); //构造左子树 CreateBiTree(bt->rchild); //构造右子树 } return OK; } Status InorderTraversal(BinTree bt) {//中序遍历二叉树的非递归方法 BinTNode *stack[NUM]; //定义栈数组 int top = 0; //初始化栈 stack[top] = bt; do { while(NULL!=stack[top]) {//扫描根结点及其所有的左结点并入栈 top = top + 1; stack[top] = stack[top-1]->lchild; } top = top -1; //退栈 if(top>=0) //判断栈是否为空 { printf("%3c",stack[top]->data); //访问结点 stack[top] = stack[top]->rchild; //扫描右子树 } }while(top>=0); return OK; } void PreOrderTraversal(BinTree bt) {//先序遍历二叉树 if(bt) { printf("%3c",bt->data); PreOrderTraversal(bt->lchild); PreOrderTraversal(bt->rchild); } } void InOrderTraversal(BinTree bt) {//中序遍历二叉树 if(bt) { InOrderTraversal(bt->lchild); printf("%3c",bt->data); InOrderTraversal(bt->rchild); } } void PostOrder(BinTree bt) {//后序遍历二叉树 if(bt) { PostOrder(bt->lchild); PostOrder(bt->rchild); printf("%3c",bt->data); } } int Size(BinTree bt) {//统计二叉树中所有结点的个数 int num1,num2; if(bt==NULL) return 0; else if(bt->lchild==NULL && bt->rchild==NULL) return 1; else { num1 = Size(bt->lchild); //统计左子树的结点个数 num2 = Size(bt->rchild); //统计右子树的结点个数 return (num1+num2+1); } } int LeafCount(BinTree bt) {//统计二叉树的叶子总数 int LeafNum; if(bt==NULL) LeafNum = 0; else if((bt->lchild==NULL) && (bt->rchild==NULL)) LeafNum = 1; else LeafNum = LeafCount(bt->lchild)+LeafCount(bt->rchild); //叶子总数为左右子树叶子之和 return LeafNum; } int Depth(BinTree bt) {//统计二叉树的深度 int hl,hr,max; if(bt!=NULL) { hl = Depth(bt->lchild); //求左子树的深度 hr = Depth(bt->rchild); //求右子树的深度 max = hl>hr?hl:hr; return (max+1); //返回树的深度 } else return 0; } void Exchange(BinTree bt) {//交换左右二叉树 if(bt == NULL) return; BinTNode *temp; temp = bt->lchild; bt->lchild = bt->rchild; bt->rchild = temp; Exchange(bt->lchild); Exchange(bt->rchild); } //构造一个循环队列 Status InitQueue(SeQueue &Q) { Q.base = (ElemType*)malloc(QueueSize*sizeof(ElemType)); if(!Q.base) exit(0); Q.front = Q.rear = 0; return OK; } //插入新的元素为队尾元素 Status EnQueue(SeQueue &Q,ElemType e) {//插入的元素为二叉树结点中的元素 if((Q.rear+1)%QueueSize == Q.front) { printf("Queue overflow"); return 0; } Q.base[Q.rear] = e; Q.rear = (Q.rear+1)%QueueSize; return 1; } //删除队头元素 Status DeleteQ(SeQueue &Q,ElemType &e) { if(Q.front == Q.rear) { printf("Queue empty"); return ERROR; } e = Q.base[Q.front]; Q.front = (Q.front+1)%QueueSize; return OK; } //判空循环队列 Status IsEmptyQ(SeQueue Q) { if(Q.front == Q.rear) return TRUE; else return FALSE; } //层次遍历二叉树 void LevelOrderTraversal(BinTree bt) { SeQueue Q; ElemType e; InitQueue(Q); //创建并初始化队列 if(bt) EnQueue(Q,bt); while(!IsEmptyQ(Q)) { DeleteQ(Q,e); printf("%3c",e->data); if(e->lchild) EnQueue(Q,e->lchild); if(e->rchild) EnQueue(Q,e->rchild); } } void main() { BinTree bt; int xz = 1; int yz,sd; while(xz) { printf("\t*************************************\n"); printf("\t\t二叉树的建立及其基本操作\n"); printf("\t*************************************\n"); printf("\t==============================\n"); printf("\t1,建立二叉树的存储结构\n"); printf("\t2,二叉树的基本操作\n"); printf("\t3,交换二叉树的左右子树\n"); printf("\t4,二叉树的层次遍历\n"); printf("\t0,退出系统\n"); printf("\t==============================\n"); printf("\t请选择:(0~4)\n"); scanf("%d",&xz); getchar(); switch(xz) {//输入:ABC##DE#G##F### case 1: printf("输入二叉树的先序序列结点值:\n"); CreateBiTree(bt); printf("二叉树的链式存储结构建立完成\n"); printf("\n"); break; case 2: printf("该二叉树的先序遍历序列是:"); PreOrderTraversal(bt); //输出ABCDEGF printf("\n"); printf("该二叉树的中序遍历序列是:"); InOrderTraversal(bt); //输出CBEGDFA printf("\n"); printf("该二叉树的后序遍历序列是:"); PostOrder(bt); //输出CGEFDBA printf("\n"); printf("该二叉树的中序遍历序列是(非递归算法):"); InorderTraversal(bt); //输出CBEGDFA printf("\n"); printf("该二叉树的结点个数是:%d\n",Size(bt)); yz = LeafCount(bt); printf("叶子结点个数是:%d",yz); printf("\n"); sd = Depth(bt); printf("该二叉树的深度是:%d\n",sd); printf("\n"); break; case 3: Exchange(bt); printf("该二叉树意已交换左右子树\n"); printf("\n"); printf("交换左右子树后,先序遍历序列是:"); PreOrderTraversal(bt); printf("\n"); printf("交换左右子树后,中序遍历序列是:"); InorderTraversal(bt); printf("\n"); printf("交换左右子树后,后序遍历序列是:"); PostOrder(bt); printf("\n"); break; case 4: printf("该二叉树的层次遍历序列是:"); LevelOrderTraversal(bt); printf("\n"); //输出ABCDEFG case 0: break; default:printf("输入的选项没有对应的操作,请重新选择:\n"); } } }
相关文章推荐
- 从printf("\40d\n")看转义字符
- 查找整数
- 关于单表代换密码分析程序设计{C++}
- Apache Stratos探究:Apache Stratos 4.1.x 的架构
- 文件上传时,seesion丢失
- 新浪免费天气Api简单使用说明
- 数组与指针定义字符串的区别(即char[]与char*)
- opencv的KeyPoint
- C#中使用split分割字符串的方法小结
- MapReduce 思想解析
- 用eclipse开发Android,用Genymotion测试时报错adb端口被占用时
- 沙盒 文件操作
- poj 2920 Mine Map【BFS】
- C#中struct与class的区别
- 计算机视觉、机器学习相关领域论文和源代码大集合
- 如何让iOS 保持界面流畅?这些技巧你知道吗
- Part Acquisition(spfa输出路径)
- (五) Nepxion-Thunder分布式RPC集成框架 - 通信协议框架
- Nginx安装--2015.11.27
- [转]用android LinearLayout和RelativeLayout实现精确布局