树:连通无回路的无向图
二叉树:树中节点的度不大于2的有序树
结点:包含一个数据元素及若干指向子树分支的信息
结点的度:一个结点拥有子树的数目称为结点的度
叶子结点:也称为终端结点,没有子树的结点或者度为零的结点
分支结点:也称为非终端结点,度不为零的结点称为非终端结点
树的度:树中所有结点的度的最大值
树的深度:也称为树的高度,树中所有结点的层次最大值称为树的深度
有序树:如果树中各棵子树的次序是有先后次序,则称该树为有序树
建树模板:
#include <bits/stdc++.h>
using namespace std;
const int N = 100;
char str[N];///读入的字符串
int cnt;///树的序号,当有元素要存到里面时才自增1
int now;///字符串中光标的位置
struct tree {
char data;///字符型数据
int lc, rc;///左孩子,右孩子
}a[N];///节点的结构
int create(){///主函数先序读入str,递归建树
char temp = str[now ++];///temp代表当前的字符,并且将光标挪到下面
if(temp == ','){///如果该节点为空,标记其为-1,作为孩子返回
return -1;
}
int id = cnt ++;///从id = 0开始存
///先序:“根 左 右”
///故 先存数据,再找左右
a[id].data = temp;
a[id].lc = create();
a[id].rc = create();
return id;
}
/*
先序:“根 左 右”
中序:“左 根 右”
后序:“左 右 根”
其实变化的只有函数套用的顺序
中序是 1.找左节点 2.输出根 3. 找右节点
先序就是 1 2交换位置
后序就是 2 3交换位置
下面依次是先序/中序/后序输出
*/
void bef(int id){
if(id == -1){
return ;
}
printf("%c",a[id].data);
bef(a[id].lc);
bef(a[id].rc);
}
void mid(int id){
if(id == -1){
return ;
}
mid(a[id].lc);
printf("%c",a[id].data);
mid(a[id].rc);
}
void aft(int id){
if(id == -1){
return ;
}
aft(a[id].lc);
aft(a[id].rc);
printf("%c",a[id].data);
}
int main() {
return 0;
}
判断完全二叉树:
q.offer(root);
//是叶子节点或者只有左孩子的节点,也就是这两种不饱和的节点出现之后还需要判断后面的节点是否有孩子
// 如果只有右孩子的不饱和节点一定不是完全二叉树
// 一开始让不饱和节点置为false,找到之后设为true
boolean isLeafOrLeft=false;
while(!q.isEmpty()) {
BTNode cur = q.poll();
//得到第一个不饱和节点之后
if (isLeafOrLeft) {
//从第一个不饱和结点之后,所有节点不能有孩子
if (null != cur.left || null != cur.right) {
System.out.println("该二叉树不是完全二叉树");
return false;
}
}//没找到不饱和节点就继续按照层序遍历寻找
else {
//cur节点左右孩子都存在
if (null != cur.left && null != cur.right) {
q.offer(cur.left);
q.offer(cur.right);
} else if (null != cur.left) {
//只有左孩子:找到不饱和节点,标记isLeafOrLeft=true
q.offer(cur.left);
isLeafOrLeft = true;
} else if (null != cur.right) {
//只有右孩子:找到不饱和节点,一定不是完全二叉树,返回false
System.out.println("该二叉树不是完全二叉树");
return false;
} else {
//cur是叶子节点:找到不饱和节点:标记isLeafOrLeft=true
isLeafOrLeft = true;
}
}
}
System.out.println("该二叉树是完全二叉树");
return true;
完全二叉树、完美二叉树建树:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1010;
int n,number[maxn],CBT[maxn],indexl=0;
void inorder(int root)
{
if(root>n)return;
inorder(root*2);//往左子树递归
CBT[root]=number[indexl++];
inorder(root*2+1);//往右子树递归
}
int main()
{
cin>>n;
for(int i=0;i<n;i++)cin>>number[i];
sort(number,number+n); //二叉搜索树中序
inorder(1);
for(int i=1;i<=n;i++)
{
cout<<CBT[i];
if(i<n)cout<<" ";
}
return 0;
}