技术标签: c语言 数据结构 visual studio
(1)n个结点的集合,如果n=0, S是空树;
(2)结点的度:一个节点含有的子树的个数;
(3)树的度:树中节点的度的最大值;
(4)树的高度(深度):树的层数。
(1)每个节点最多只能有两棵子树,也就是说二叉树不存在度大于2的节点;
(2)二叉树的子树有左右之分,左右子树的次序不能颠倒;
(3)二叉树有五种形态:①空树、②只有一个根节点、③一个根节点和一个左子树、④一个根节点和一个右子树、⑤一个根节点和左右子树。
(4)满二叉树:一个二叉树,如果每一层的节点数都达到了最大值2;
(5)完全二叉树:从上到下,从左到右,按照每个节点有两个分支进行编号,中间只要没有断开的,就是完全二叉树。
(1)先序遍历:根左右,创建二叉树,先遍历根节点,再遍历左子树,最后遍历右子树。
(2)中序遍历:左根右,创建二叉树,先遍历左子树,再遍历根节点,最后遍历右子树。
(3)后续遍历:左右根,创建二叉树,先遍历左子树,再遍历右子树,最后遍历根节点。
(4)层遍历——借助队列,从上到下,从左到右依次遍历。
算法思想:
1.将根节点入队;
2.判断队列是否为空,如果不空,则获取对头元素front,访问并出队;
3.判断front是否有左右孩子,如果有,按照先入左,再入右的顺序将孩子入队;
4.循环2.3,直到队列为空,则遍历完毕。
参考代码如下:
#include<iostream>
using namespace std;
#include<stack>
#include<queue>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//节点的结构
typedef struct node
{
char value;//当前节点本身的值
struct node* left;//当前节点指向左子树的指针
struct node* right;//当前节点指向右子树的指针
}Node;
//树的结构
typedef struct tree
{
Node* root;//指向树的根节点的指针
}Tree;
//递归
void InitTree(Tree* t);//初始化树,其实就是将树的root初始化为NULL
Node* Create(char*& str);//创建二叉树,创建成功后,将根节点返回
void PreOrder(Node* root);//先序遍历以根为root的二叉树 根左右
void InOrder(Node* root);//中序遍历以根为root的二叉树 左根右
void PostOrder(Node* root);//后序遍历以根为root的二叉树 左右根
void LevOrder(Node* root);//层遍历
//根据先序遍历创建二叉树,先创建根,在创建根的左子树,最后 创建根的右子树
Node* Create(char*& str)
{
if (*str == '*')
return NULL;
else
{
Node* newnode = (Node*)malloc(sizeof(Node));//先开辟一个节点空间
newnode->value = *str;//将当前不是*的字符赋给当前节点,创建根
newnode->left = Create(++str);//创建当前节点的左子树,调用创建函数
newnode->right = Create(++str);//创建当前结点的右子树
return newnode;
}
}
//初始化
void InitTree(Tree* t)
{
t->root = NULL;
}
//递归算法——先序遍历二叉树
void PreOrder(Node* root)
{
if (root != NULL)
{
//cout << root->value << " ";//先遍历root
printf("%c ", root->value);//先遍历root
PreOrder(root->left);//遍历当前根的左子树
PreOrder(root->right);//遍历当前根的右子树
}
}
//递归算法——中序遍历二叉树
void InOrder(Node* root)
{
if (root != NULL)
{
InOrder(root->left);//先遍历左子树
printf("%c ", root->value);//遍历根
InOrder(root->right);//遍历右子树
}
}
//递归算法——后序遍历二叉树
void PostOrder(Node* root)
{
if (root != NULL)
{
PostOrder(root->left);//递归遍历左子树
PostOrder(root->right);//递归遍历右子树
printf("%c ", root->value);//遍历根
}
}
//层次遍历二叉树
void LevOrder(Node* root)
{
queue<Node*>qq;//定义队列qq,存储指向每个节点的指针
if (root == NULL)
return;
Node* front = NULL;//指向队头的指针
qq.push(root);//将根入队
while (!qq.empty())
{
front = qq.front();//获取队头
qq.pop();
printf("%c ", front->value);
//将当前front的左右孩子(下一层)入队
if (front->left != NULL)
qq.push(front->left);
if (front->right != NULL)
qq.push(front->right);
}
printf("\n");
}
int main()
{
Tree t;
InitTree(&t);//空树
char* str =(char*) "ABDG**HI****CE*J**F**";//变量强转
t.root = Create(str);
printf("先序遍历二叉树\n");
PreOrder(t.root);
printf("\n");
printf("中序遍历二叉树:\n");
InOrder(t.root);
printf("\n");
printf("后序遍历二叉树:\n");
PostOrder(t.root);
printf("\n");
printf("层遍历二叉树:\n");
LevOrder(t.root);
printf("\n");
}
非递归算法——借助栈
(1)先序遍历
算法思想:根左右
(2)中序遍历
算法思想:左根右,要将当前左子树分支上的所有节点都入栈,要么找不到
(3)后序遍历
算法思想:左右根,需要一个指针记住已经遍历过的节点
#include<iostream>
using namespace std;
#include<stack>
#include<queue>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//节点的结构
typedef struct node
{
char value;//当前节点本身的值
struct node* left;//当前节点指向左子树的指针
struct node* right;//当前节点指向右子树的指针
}Node;
//树的结构
typedef struct tree
{
Node* root;//指向树的根节点的指针
}Tree;
//非递归
void InitTree(Tree* t);//初始化树,其实就是将树的root初始化为ULL
Node* Create(char*& str);//创建二叉树,创建成功后,将根节点返回
void PreOrder1(Node* root);//前序遍历
void InOrder1(Node* root);//中序遍历
void PostOrder1(Node* root);//后序遍历
//根据先序遍历创建二叉树,先创建根,在创建根的左子树,最后 创建根的右子树
Node* Create(char*& str)
{
if (*str == '*')
return NULL;
else
{
Node* newnode = (Node*)malloc(sizeof(Node));//先开辟一个节点空间
newnode->value = *str;//将当前不是*的字符赋给当前节点,创建根
newnode->left = Create(++str);//创建当前节点的左子树,调用创建函数
newnode->right = Create(++str);//创建当前结点的右子树
return newnode;
}
}
//初始化
void InitTree(Tree* t)
{
t->root = NULL;
}
void PreOrder1(Node* root)//非递归先序遍历
{
stack<Node*>ss;//定义栈,存储指向结点的指针
if (root == NULL)
return;
ss.push(root);
Node* top = NULL;//top指向栈顶元素
while (!ss.empty())
{
top = ss.top();
printf("%c ", top->value);
ss.pop();//出栈
//将当前节点的toop的孩子入栈,按照右左的顺序入栈
if (top->right != NULL)
ss.push(top->right);
if (top->left != NULL)
ss.push(top->left);
}
printf("\n");
}
void InOrder1(Node* root)//非递归中序遍历
{
if (root == NULL)
return;
Node* p = root, * top = NULL;
stack<Node*>ss;
while (p != NULL || !ss.empty())
{
//从p开始,将所有左分支入栈
while (p!=NULL)
{
ss.push(p);
p = p->left;
}
if (!ss.empty())
{
top = ss.top();
ss.pop();
printf("%c ", top->value);
//过程到当前节点的右分支
p = top->right;
}
}
printf("\n");
}
void PostOrder1(Node* root)//非递归后序遍历
{
if (root == NULL)
return;
stack<Node*>ss;
Node* top = NULL, * pre = NULL;
ss.push(root);
while (!ss.empty())
{
top = ss.top();//获得栈顶
//出栈,要么没孩子,要么孩子已经出栈
if (top->left == NULL && top->right == NULL ||pre!=NULL&& pre == top->left ||pre!=NULL&& pre == top->right)
{
printf("%c ", top->value);
ss.pop();
pre = top;//pre指针记住当前节点,为了下一次查看是否已经出栈
}
else//右孩子,则按照右左顺序入栈
{
if (top->right != NULL)
ss.push(top->right);
if (top->left != NULL)
ss.push(top->left);
}
}
printf("\n");
}
int main()
{
Tree t;
InitTree(&t);//空树
char* str =(char*) "ABDG**HI****CE*J**F**";//变量强转
t.root = Create(str);
printf("非递归先序遍历二叉树:\n");
PreOrder1(t.root);
printf("\n");
printf("非递归中序遍历二叉树:\n");
InOrder1(t.root);
printf("\n");
printf("非递归后序遍历二叉树:\n");
PostOrder1(t.root);
printf("\n");
}
如有错误,敬请指正!
您的点赞与收藏是对我最大的鼓励与支持。
文章浏览阅读2.9k次。有限元或者其他数值计算程序中经常会涉及到对求解空间的剖分(均匀剖分或者非均匀剖分),在数据可视化过程中,需要绘制剖分单元,反映分布结果。下面给出matlab程序。function [x,y,z] = plotcube( p1, cube_x, cube_y, cube_z )%% p1: 立方体左下角顶点坐标%% cube_x, cube_y, cube_z 是立方体三个方向边长v = z..._matlab画三维图剖面
文章浏览阅读171次。题目来源:https://leetcode-cn.com/problems/yuan-quan-zhong-zui-hou-sheng-xia-de-shu-zi-lcof/0,1,,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字。求出这个圆圈里剩下的最后一个数字。例如,0、1、2、3、4这5个数字组成一个圆圈,从数字0开始每次删除第3个数字,则删除的前4个数..._个人围成一圈,1-m报数,叫到m的出圈,剩下继续报数,剩最后一个人的时候 他的编
文章浏览阅读3.5k次。当使用BitLocker给磁盘上锁后,可以通过命令:manage-bde -lock d: -forcedismount 将已经解锁的磁盘重新上锁,如果觉得每次都通过命令行写命令很麻烦,那可以通过修改注册表的方式在右键菜单上增加一个上锁功能。步骤如下:1、打开注册表编辑器2、在键值【HKEY_CLASSES_ROOT\Drive\shell】下添加项【runas】,然后..._manage-bde -unlock d:
文章浏览阅读4k次。一、问题描述将sql server的数据导入hive,结果报错:Warning: /opt/cloudera/parcels/CDH-5.15.2-1.cdh5.15.2.p0.3/bin/../lib/sqoop/../accumulo does not exist! Accumulo imports will fail.Please set $ACCUMULO_HOME to th..._could not load db driver class
文章浏览阅读805次。基于OpenGauss系列主要包括vastbase G系列产品,GBase8c ,GBase8s, Shentong For OpenGauss。1. 建库的时候需要将DBCOMPATIBILITY='PG' 否则后续插入数据的时候会出现文本数据录入不进去的问题。原因:默认的是兼容oracle的模式,oracle定义字符的个数是按照字节数定义的,而PG是按照字符数量定义的。2. Shentong兼容oracle模式例子。具体可以在pg_database进行查询。3. shentong基于PG模式。_dbcompatibility vastdata
文章浏览阅读343次。该楼层疑似违规已被系统折叠隐藏此楼查看此楼/*将移位寄存器内的数据锁存到输出寄存器并显示 *//*..._c语言多位数码管显示变化数据
文章浏览阅读252次,点赞3次,收藏6次。同学们都在机房做实验或自由上机,请根据自己实际使用情况编写一份模拟校园卡消费记录查询系统,实现登录,计费,挂失,统计等相关功能。可以选择TC2.0、TC3.0、VC++6.0等开发环境,或者与老师讨论,选择自己熟悉的开发工具与平台。(5)如有可能,可使用MFC 等开发工具,实现彩色或图形操作界面。//状态 ,正常、挂失、冻结。char state;//状态 ,是否上机中。
文章浏览阅读69次。本系统带文档lw万字以上文末可领取本课题的JAVA源码参考。
文章浏览阅读3.3k次,点赞2次,收藏31次。温度传感器DS18B20简介特点实物图原理图内部结构(1) 64位(激)光刻只读存储器(2) DS18B20温度转换规则(3) DS18B20温度传感器的存储器(4) 配置寄存器ROM指令RAM指令编程原理DS18B20初始化DS18B20读时序DS18B20写时序大致过程代码实现DS18B20简介DS18B20数字温度传感器接线方便,封装后可应用于多种场合,如管道式,螺纹式,磁铁吸附式,不锈钢封装式。主要根据应用场合的不同而改变其外观。封装后的DS18B20可用于电缆沟测温,高炉水循环测温,锅炉测温_ds18b02在ad中怎么搜索
文章浏览阅读736次,点赞28次,收藏12次。WebView 与 JS 交互方式,shouldOverrideUrlLoading、onJsPrompt使用有啥区别 -Flutter、Kotlin接触使用过没有其他项目相关问题算法 - 二叉树输出第 k 层节点元素。
文章浏览阅读5.9k次,点赞11次,收藏15次。IT技术发展迅猛,新技术层出不穷,具有良好的学习能力,并及时获取新知识,成为程序员职业发展的核心竞争力。本文作者结合多年学习经验总结出提高程序员学习能力的三个要点,即要善于读书、要高效学习、要有好心态。IT技术的发展日新月异,新技术层出不穷,具有良好的学习能力,能及时获取新知识、随时补充和丰富自己,已成为程序员职业发展的核心竞争力。本文中,作者结合多年的学习经验总结出了提高程序员学习能_程序员努力的方向
文章浏览阅读6.7w次,点赞134次,收藏738次。FreeMarker概述FreeMarker 是一款 模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。 是一个Java类库。FreeMarker 被设计用来生成 HTML Web 页面,特别是基于 MVC 模式的应用程序,将视图从业务逻辑中抽离处理,业务中不再包括视图的展示,而是将视图交给 FreeMarker 来输出。虽然 FreeMarker 具有一些编程的能力,但通常由 Java 程序准备要显示的数据,由 FreeMar_freemarker