编程之美3.8 3.9 3.10二叉树问题实现

// 编程之美之求二叉树节点的最大距离.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include <queue>//for the use of the layer print
#include <vector>
using namespace std;
#define N 10
struct TNode{
	char chValue;
	TNode *leftChild;
	TNode *rightChild;
	int nMaxLeft;
	int nMaxRight;
};
TNode* rebuildTree(char *preOrder,int start1,char *midOrder,int start2,int n)//根据前序和中序建立二叉树 长度为N
{
	TNode *root;
	if(n==0) return NULL;
	root = new TNode;
	int pivet;
	char chroot;
	chroot=preOrder[start1];
	root->chValue = chroot;
	root->nMaxLeft=0;
	root->nMaxRight=0;
	for(int i=start2;i<start2+n;i++)//include start1 
	{
		if(midOrder[i]==chroot) { pivet = i;break;}
	}
	if(pivet-start2>0)
		root->leftChild=rebuildTree(preOrder,start1+1,midOrder,start2,pivet-start2);
	else root->leftChild = NULL;
	if(n-pivet+start2-1>0)//pivet-start2 is the half number,
		root->rightChild=rebuildTree(preOrder,start1+1+pivet-start2,midOrder,pivet+1,n-pivet+start2-1);
	else root->rightChild = NULL;
	return root;
}
void layerprint(TNode *root)
{
	queue<TNode*> que;// = new queue<TNode>();
	TNode *h;
	//int layer=0;
	//int cur1=0,cur2=0;//current layer in the queue
	h=root;
	que.push(h);//initialize the queue with the root of the tree
	while(que.empty()==0)
	{
		int sz = que.size();//size is the number of the current layer
		for(int i=0;i<sz;i++)
		{
			TNode *p=que.front();
			cout<<p->chValue<<" ";
			que.pop();
			if(p->leftChild!=NULL) que.push(p->leftChild);
			if(p->rightChild!=NULL) que.push(p->rightChild);
		}
		cout<<endl;
	}
}
void layerprintreverse(TNode *root)//use a array record the number of each layer
{
	vector<TNode*> vecnodes;//because there is no pop operation, and the need of get the values of serial elements,so the queue is inconvinient,vector is the better choice
	TNode *h,*p;
	vector<int> layer;//used for the recording the number of each layer
	h=root;
	//size_t i=1;
	int nodes=1;//present the current position in the vecnodes
	vecnodes.push_back(h);//initialize the queue with the root of the tree
	int num=1;//the ending condition is that all the array elements are puted into the queue,as for that, we must know the number of the tree, no matter how,at least we need to know the deepth of the tree,except we use the vector that is dynamicly increased
	//we can know that the current layer is null only if the the last layer is null, so when the number of the current layer is zero,the troop ends.
	layer.push_back(num);
	while(num>0)
	{
		int numi=0;
		int lastnum = layer.back();//[i-1];//i presents the current layer
		if(lastnum==0)break;
		nodes=vecnodes.size();
		for(int j=nodes-lastnum;j<nodes;j++)
		{
			p=vecnodes[j];
			if(p->leftChild!=NULL) {vecnodes.push_back(p->leftChild);numi++;}
			if(p->rightChild!=NULL) {vecnodes.push_back(p->rightChild);numi++;}
		}
		num=numi;//the number of the current layer
		if (num!=0)
		{
			layer.push_back(num);
			//i++;
		}
	}
	while(layer.empty()==0)
	{
		int laynum=layer.back();
		layer.pop_back();
		int siz=vecnodes.size();
		for(int i=siz-laynum;i<siz;i++)
			cout<<vecnodes[i]->chValue<<" ";
		cout<<endl;
		for(int i=siz-laynum;i<siz;i++)
			vecnodes.pop_back();
	}
}
void preprint(TNode *root)
{
	if(root!=NULL)
	{
		cout<<root->chValue<<" ";
		preprint(root->leftChild);
		preprint(root->rightChild);
	}
}
int findMax(TNode* root,int &curmax)//return the height of the tree, at the same time judge the current longest distance which through the current root so that we can get the longest distance within one loop
{
	TNode *p=root;
	//int curmax=0;
	if(p->leftChild==NULL&&p->rightChild==NULL)
		return 0;
	if(p->leftChild!=NULL)
		p->nMaxLeft = findMax(p->leftChild,curmax) + 1;//defaut value is zero
	if(p->rightChild!=NULL)
		p->nMaxRight = findMax(p->rightChild,curmax) + 1;

	if(curmax<p->nMaxLeft + p->nMaxRight)
		curmax = p->nMaxLeft + p->nMaxRight;
	return max(p->nMaxLeft,p->nMaxRight);
}
int _tmain(int argc, _TCHAR* argv[])
{
	char preOrder[N],midOrder[N];
	int m;
	cout<<"input preorder"<<endl;
	for(int i=0;i<N;i++)
		cin>>preOrder[i];
	cout<<"input midorder"<<endl;
	for(int i=0;i<N;i++)
		cin>>midOrder[i];
	TNode *root;
	root=rebuildTree(preOrder,0,midOrder,0,N);
	cout<<endl<<" root value is "<<root->chValue<<endl;
	preprint(root);
	cout<<endl<<" next is layprint"<<endl;
	layerprint(root);
	cout<<endl<<" next is layprintreverse"<<endl;
	layerprintreverse(root);
	cout<<endl<<" next is find the distance"<<endl;
	findMax(root,m);
	cout<<"the longest distance is "<<m<<endl;
	system("pause");
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第一篇 基础篇 第0章 JDK安装和最简单的环境变量配置方法 第1章 Java基础概念 一、 Java基础语法 1、Helloworld.java 2、标识符 3、关键字 4、常量 5、变量 6、语句 6.1 if语句和switch语句 6.1.2 if语句举例 6.1.3 switch语句 6.2 for循环语句 6.3 while语句和do-while语句 6.3.1 while语句形式 6.3.2 do-while语句 6.3.3 while语句和do-while语句举例 6.4 break语句和continue语句 6.4.1 break语句 6.4.2 continue语句 二、类和对象 1、面向对象基础 1.1 面向对象程序设计入门分析 1.2 抽象 1.3 封装 2、类 2.1 类头 2.2类体 2.3 创建对象 2.4 面向对象举例 2.5 构造函数 2.5.1 构造函数的一般概念 2.5.2 创建自己的构造函数 2.5.3 构造方法注意事项 2.5.4构造函数的作用 3、方法 3.1 方法介绍 3.2方法定义 3.3调用方法 3.4 方法举例 4、访问控制符 5、this关键字 5.1 this方法应用举例 6. Static关键字 6.1 static应用举例 7. super关键字 7.1 super应用举例 8. abstract关键字 9. final关键字 9.1 final介绍 9.2 final使用注意事项 三、继承 1、继承的概念 1.1 继承的定义 1.2 继承举例 1.3 父类和子类 类继承 2.1 方法继承 2.2 方法覆盖 2.3 方法重载 3、多态与动态绑定 3.1 多态分为两种 3.2 调用一个对象方法的机制 3.3 方法调用举例 4、构造函数的重载 4.1 默认字段初始化 4.2 默认构造函数 4.3 显式字段初始化 4.4 构造函数被调用后的详细执行过程 5、包 5.1 创建包 5.2 创建可复用类的步骤简要说明 5.3 包的导入 5.4 包的可见性 接口 6.1 接口的概念 6.2 接口的声明 6.3 接口的实现 四、IO流及异常处理 1、流和文件 1.1 流 1.2 文件 2、常用流类 2.1 字节流 2.1.1 InputStream(输入流) 2.1.2 OutputStream(输出流) 2.1.3 FileInputStream(文件输入流) 2.1.4 FileOutputStream(文件输出流) 2.1.5 BufferedInputStream(缓冲输入流) 2.1.6 BufferedOutputStream(缓冲输出流) 2.1.7 PrintStream(打印流) 2.2字符流 2.2.1 Reader类 2.2.2 Writer类 2.2.3 FileReader类 2.2.4 FileWriter类 2.2.5 CharArrayReader类 2.2.6 CharArrayWriter类 2.2.7 BufferedReader类 2.2.8 BufferedWriter类 2.2.9 PrintWriter类 2.2.10 System.in对象和System.out对象 文件处理 3.1 创建或打开、关闭文件对象 3.2 关闭文件 3.3 read()方法 3.4 write()方法 3.5 其他操作文件的方法 4、Java异常处理 4.1 Java异常概念 4.2 异常类型 4.3 Java的内置异常 4.4 Java异常举例 4.5 异常的捕获和处理 4.6 异常抛出 4.6.1 throw语句 4.6.2 throws语句 4.6.3 finally语句 4.7 自定义异常类 4.8 异常应用的其他问题 4.9 异常应用举例 五、线程 1、线程的概念 1.1 程序、进程与线程 1.2 线程调度与优先级 1.3 线程的状态与生命周期 1.4 控制一个线程生命周期最常用的方法 2、线程的创建和启动 3、线程的同步与死锁 3.1 同步的概念 3.2 线程同步举例 3.3 线程死锁 六、GUI 1、图形用户界面概述 1.1 组件 1.2容器 1.3 AWT组件 1.4 Swing组件 1.5 组件与容器的关系 1.6 swing常用组件 2、Swing常用组件 2.1文本组件 2.2 标签 2.3 按钮 2.4单选按钮组件 2.5 复选框组件 2.6列表框组件 2.7组合框组件 2.8滑块组件 事件处理 3.1 事件处理原理 3.2 事件架构 3.3 焦点事件 3.4 键盘事件 3.5 鼠标事件 4、布局设计 4.1 FlowLayout流布局 4.2 BorderLayout边界布局 4.3 CardLayout卡式布局 4.4 GridLayout卡式布局 4.5 GridBagLayout卡式布局 4.6 BoxLayout盒式布局 5、菜单步骤 6、对话框设计 6.1 JOptionPane对话框 6.2 JDialog对话框 文字与图形处理 7.1 文本和字体 7.2 简单图形绘制 7.3 颜色 7.4 图像处理 七、网络 1、Java网络编程简介 1.1 IP网间协议 1.2 TCP传输控制协议 1.3 UDP用户数据包协议 2、URL连接 2.1 URL 2.2 Java.net包中URL类定义 2.3 创建URL对象 2.4 Java.net包中URLConnection类 2.5 AppletContext接口类 2.6 获取网络属性信息 2.7 创建输入流(InputStream)对象 3、SOCKET连接 3.1 Socket通信的一般结构 3.2 TCP Socket编程 3.2.1 Socket类 3.2.2 ServerSocket类 3.3 UDP Socket编程 八、Java概念疑难解答 第2章 Java经典练习题 2.1 斐波那契数列 2.2 判断素数 2.3 水仙花数 2.4 分解质因数 2.5 杨辉三角 2.6 学习成绩查询 2.7 求最大公约数与最小公倍数 2.8 完全平方数 2.9 统计字母、空格、数字和其它字符个数 2.10 求主对角线之和 2.11 完数求解 2.12 求s=a+aa+aaa+aaaa+aa...a的值 2.13 高度计算 2.14 乘法口诀 2.15 无重复三位数 2.16 菱形打印 2.17 利润计算 2.18 第几天判断 2.19 从小到大输出数列 2.20 猴子吃桃问题 2.21 乒乓球比赛 2.22 求分数之和 2.23 求阶乘的和 2.24 递归求法 2.25 求不多于5的正整数 2.26 回文判断 2.27 星期判断 2.28 插数入数组 2.29 取整数的任意位 2.30 按顺序输出数列 2.31 位置替换 2.32 字符串排序 2.33 贷款器 2.34 通讯录排序 2.35 闰年判断 2.36 二元方程求解 2.37 密码解译 2.38 DVD查询 2.39 电子日历 2.40 万年历 第二篇 提高篇 第3章 Java常用算法 3.1递归算法 3.2冒泡排序算法 3.3 快速排序算法 3.4选择排序算法 3.5直接插入算法 3.6希尔排序算法 3.7 二分查找算法 3.8 二叉树 3.9 图的实现 3.10 生产者消费者的实现 3.11 银行家算法 3.12 KMP算法 3.13 RSA的实现 第4章 IO流实例开发 4.1流到底怎样输入和输出扯淡区 4.2 FileInputStream的应用 4.3 FileOutputStream的应用 4.4 FileReader的应用 4.5 FileWriter的应用 4.6 BufferedInputStream的应用 4.7 BufferedOutputStream的应用 4.8 BufferedReader的应用 4.9 BufferedWriter的应用 第5章 Java图形界面开发 5.1 开发自己的控件 5.2 控件的排布示例 5.3 开发自己的QQ聊天系统 5.4 颜色选择器 5.5 按钮测试 5.6 密码验证器 5.7 绘制自己的坐标 5.8 多种字体显示 5.9 窗口风格选择器 5.10 右键菜单 5.11 树形关系网 5.12 开发自己的文本编辑器 5.13 开发自己的剪切板 5.14 文本拖动效果演示 5.15 怎样拖动图片 5.16 开发自己的数字时钟 5.17 数字动画 5.18 滑杆调试器 5.19 启动程序开发 5.20 开发自己的调色板 5.21 文件选择器 5.22 丰富多彩的光标选择器 5.23 开发自己的浏览器 5.24 文字抖动效果演示 5.25 文字阴影效果演示 5.26 3D文字效果演示 5.27 波浪文字效果演示 5.28 飞行文字效果演示 5.29 伸展文字效果演示 5.30 开发自己的网页图片 5.31 火焰图片效果演示 5.32 图片百叶窗效果演示 5.33 图片倒影效果演示 5.34 怎样翻转图片 5.35 开发自己的闹钟 5.36 应用自己的万年历 5.37 开发自己的计算器 5.38 开发自己的电子相册 第6章 Java游戏 6.1 俄罗斯方块 6.2 连连看游戏 6.3 迷宫 6.4 模拟闪电 6.5 扫雷 6.6 贪食蛇 6.7 围棋 6.8 五子棋 6.9 人机猜拳游戏 第三篇 实战篇 第7章 项目开发 7.1 开发自己的浏览器 7.2 开发自己的象棋游戏 7.3 网络主机线程扫描与端口控制
C语言教程(原书第4版) 《c语言教程(原书第4版)》是一本优秀的c程序设计语言教材,完整描述了ansi c语言及其语法特性,并对c语言的高级特性和应用作了深入阐述,介绍了从c到c++和java过渡的相关知识。《c语言教程(原书第4版)》的一个鲜明特色就是结合大量示例描述c语言的重要特征,并对很多工作代码给出了逐步的分析,以这种独特的教学方法向读者解释新接触的编程元素及一些惯用法。   《c语言教程(原书第4版)》系统、完整,可作为c语言的参考手册,也非常适合作为学习c语言的入门和高级课程教材。 前言 第0章 从零开始 0.1 为什么要用c 0.2 ansi c标准 0.3 从c到c++ 0.4 从c和c++到java 第1章 c语言概述 1.1 编程和预备知识 1.2 程序输出 1.3 变量、表达式和赋值 1.4 使用#define和#include 1.5 使用printf()和scanf() 1.6 控制流 1.7 函数 1.8 数组、字符串和指针 1.8.1 数组 1.8.2 字符串 1.8.3 指针 1.9 文件 1.10 与操作系统有关的内容 1.10.1 编写和运行c程序 1.10.2 中断程序 1.10.3 输入文件尾标志 1.10.4 输入和输出的重定向 1.11 总结 1.12 练习 第2章 词法元素、操作符和c系统 2.1 字符和词法元素 2.2 语法规则 2.3 注释 2.4 关键字 2.5 标识符 2.6 常量 2.7 字符串常量 2.8 操作符和标点符号 2.9 操作符的优先级和结合性 2.10 增值操作符和减值操作符 2.11 赋值操作符 2.12 例子:计算2的乘方 2.13 c系统 2.13.1 预处理器 2.13.2 标准函数库 2.14 总结 2.15 练习 第3章 基本数据类型 3.1 声明、表达式和赋值 3.2 基本数据类型 3.3 字符和char数据类型 3.4 int数据类型 3.5 整数类型short、long和unsigned 3.6 浮点类型 3.7 typedef的用法 3.8 sizeof操作符 3.9 使用getchar()和putchar() 3.10 数学函数 3.10.1 使用abs()和fabs() 3.10.2 unix和数学函数库 3.11 隐式类型转换和强制类型转换 3.11.1 整型提升 3.11.2 寻常算术转换 3.11.3 强制类型转换 3.12 十六进制和八进制常量 3.13 总结 3.14 练习 第4章 控制流 4.1 关系操作符、相等操作符和逻辑操作符 4.2 关系操作符和表达式 4.3 相等操作符和表达式 4.4 逻辑操作符和表达式 4.5 复合语句 4.6 表达式和空语句 4.7 if和if-else语句 4.8 while语句 4.9 for语句 4.10 例子:布尔变量 4.11 逗号操作符 4.12 do语句 4.13 例子:斐波那契数 4.14 goto语句 4.15 break和continue语句 4.16 switch语句 4.17 条件操作符 4.18 总结 4.19 练习 第5章 函数 5.1 函数定义 5.2 return语句 5.3 函数原型 5.4 例子:创建乘方表 5.5 从编译器的角度观察函数原型 5.6 函数定义顺序的另一种风格 5.7 函数调用和传值调用 5.8 开发大型程序 5.9 使用断言 5.10 作用域规则 5.10.1 平行和嵌套代码块 5.10.2 以调试为目的使用代码块 5.11 存储类型 5.11.1 auto存储类型 5.11.2 extern存储类型 5.11.3 register存储类型 5.11.4 static存储类型 5.12 静态外部变量 5.13 默认初始化 5.14 递归 5.15 例子:汉诺塔 5.16 总结 5.17 练习 第6章 数组、指针和字符串 6.1 一维数组 6.1.1 初始化 6.1.2 下标 6.2 指针 6.3 传引用调用 6.4 数组和指针之间的关系 6.5 指针运算和元素的大小 6.6 数组作为函数的实参 6.7 例子:冒泡排序 6.8 用calloc()和malloc()进行动态内存分配 6.9 例子:归并和归并排序 6.10 字符串 6.11 标准函数库中的字符串处理函数 6.12 多维数组 6.12.1 二维数组 6.12.2 存储映射函数 6.12.3 形式参数声明 6.12.4 三维数组 6.12.5 初始化 6.12.6 使用typedef 6.13 指针数组 6.14 main()函数的参数 6.15 不规则数组 6.16 函数作为参数 6.17 例子:使用二分法寻找函数的根 6.18 函数指针数组 6.19 类型限定符const和volatile 6.20 总结 6.21 练习 第7章 位操作符和枚举类型 7.1 位操作符和表达式 7.1.1 按位求反 7.1.2 补码 7.1.3 位逻辑操作符 7.1.4 左移位和右移位操作符 7.2 掩码 7.3 软件工具:打印int值的二进制形式 7.4 包装和解包 7.5 枚举类型 7.6 例子:“石头、剪刀、布”游戏 7.7 总结 7.8 练习 第8章 预处理器 8.1 #include的使用 8.2 使用#define 8.3 带参数的宏 8.4 stddef.h中的类型定义和宏 8.5 例子:用qsort()进行排序 8.6 例子:带参数的宏 8.7 stdio.h和ctype.h中的宏 8.8 条件编译 8.9 预定义的宏 8.10 “#”和“##”操作符 8.11 assert()宏 8.12 使用#error和#pragma 8.13 行号 8.14 对应的函数 8.15 例子:快速排序 8.16 总结 8.17 练习 第9章 结构和联合 9.1 结构 9.2 访问结构成员 9.3 操作符的优先级和结合性的总结 9.4 在函数中使用结构 9.5 结构的初始化 9.6 例子:玩扑克牌 9.7 联合 9.8 位字段 9.9 例子:访问位和字节 9.10 adt堆栈 9.11 总结 9.12 练习 第10章 结构和列表处理 10.1 自引用的结构 10.2 线性链表 10.3 链表操作 10.4 一些链表处理函数 10.4.1 插入 10.4.2 删除 10.5 堆栈 10.6 例子:波兰记法和堆栈求值 10.7 队列 10.8 二叉树 10.8.1 二叉树的遍历 10.8.2 创建树 10.9 普通的树 10.9.1 遍历 10.9.2 calloc()的用法以及树的创建 10.10 总结 10.11 练习 第11章 输入/输出和操作系统 11.1 输出函数printf() 11.2 输入函数scanf() 11.3 fprintf()、fscanf()、sprintf() 和sscanf()函数 11.4 fopen()和fclose()函数 11.5 例子:对文件进行空间加倍 11.6 使用临时文件和优雅函数 11.7 随机访问文件 11.8 文件描述符输入/输出 11.9 文件访问权限 11.10 在c程序内部执行命令 11.11 在c程序内部使用管道 11.12 环境变量 11.13 c编译器 11.14 使用性能评估程序 11.15 函数库 11.16 对c代码进行计时 11.17 使用make 11.18 使用touch 11.19 其他有用的工具 11.20 总结 11.21 练习 第12章 高级应用 12.1 用fork()创建并发进程 12.2 进程的叠加:exec...()函数族系 12.3 使用pipe()实现进程间的通信 12.4 信号 12.5 例子:哲学家用餐问题 12.6 矩阵的动态分配 12.6.1 为什么二维数组无法满足要求 12.6.2 用指针数组创建矩阵 12.6.3 调整下标范围 12.6.4 一次分配所有内存 12.7 返回状态 12.8 总结 12.9 练习 第13章 从c到c++ 13.1 输出 13.2 输入 13.3 函数 13.4 类和抽象数据类型 13.5 重载 13.6 构造函数和析构函数 13.7 面向对象编程和继承 13.8 多态 13.9 模板 13.10 c++的异常 13.11 面向对象编程的优点 13.12 总结 13.13 练习 第14章 从c到java 14.1 输出 14.2 变量和类型 14.3 类和抽象数据类型 14.4 重载 14.5 类的创建和销毁 14.6 面向对象编程和继承 14.7 多态和重写方法 14.8 applet 14.9 java的异常 14.10 java和oop的优势 14.11 总结 14.12 练习 附录a 标准函数库 附录b c的语法 附录c ansi c与传统c的比较 附录d ascii字符码 附录e 操作符的优先级和结合性

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值