- 了解完全二叉树和满二叉树
满二叉树:
除最后一层无任何子节点外,每一层上的所有结点都有两个子结点(最后一层上的无子结点的结点 为叶子结点)。也可以这样理解,除叶子结点外的所有结点均有两个子结点。节点数达到最大值。所有叶子结点必须在同一层上。
完全二叉树:
若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。 - 前序中序后序遍历
同时知道中序遍历和其他另一种遍历才能知道树的结构 - 二叉搜索树
题:判断两序列是否为一个二叉搜索树序列
/*
二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树:
若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。
查找算法:
在二叉排序树b中查找x的过程为:
若b是空树,则搜索失败,
否则:若x等于b的根结点的数据域之值,则查找成功;
否则:若x小于b的根结点的数据域之值,则搜索左子树;
否则:查找右子树。
插入算法:
向一个二叉排序树b中插入一个结点s的算法,过程为:
若b是空树,则将s所指结点作为根结点插入,否则:
若s->data等于b的根结点的数据域之值,则返回,否则:
若s->data小于b的根结点的数据域之值,则把s所指结点插入到左子树中,否则:
把s所指结点插入到右子树中。
*/
// 对输入的数字序列构建二叉排序树,并对他们进行前序和中序的遍历,依次比较两次遍历的结果是否相同,
// 相同则说明两棵二叉排序树相同
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <iostream>
using namespace std;
struct Node
{
int c;
Node *lchild;
Node *rchild;
}Tree[110];
int loc;
//申请节点空间
Node *create()
{
Tree[loc].lchild = Tree[loc].rchild = NULL;
return &Tree[loc++];
}
//保存二叉树遍历结果,将每一棵树的前序遍历得到的字符串与中序遍历得到的字符串连接,得到遍历结果的字符串
char str1[110], str2[110];
int size1, size2; //保存在字符串数组中的遍历得到的字符个数
char *str; //当前正在保存的字符串
Node *Insert(Node *T, int x)
{
if (T == NULL)
{
T = create();
T->c = x;
return T;
}
else if (x < T->c)
{
T->lchild = Insert(T->lchild, x);
}
else if (x> T->c)
{
T->rchild = Insert(T->rchild, x);
}
}
void postOrder(Node *T)
{
if (T ->lchild != NULL)
{
postOrder(T->lchild);
}
if (T -> rchild != NULL)
{
postOrder(T->rchild);
}
str[size1++] = T->c + '0';
}
void inOrder(Node *T)
{
if (T->lchild != NULL)
{
postOrder(T->lchild);
}
str[size2++] = T->c + '0';
if (T->rchild != NULL)
{
postOrder(T->rchild);
}
}
int main()
{
int n;
char tmp[15];
while (scanf_s("%d", &n) != EOF && n != 0)
{
loc = 0;
Node *T = NULL;
cin >> tmp;
for (int i = 0; tmp[i] != 0; i++)
{
T = Insert(T, tmp[i] - '0'); //按顺序将数字插入二叉排序树
}
size1 = 0;
str = str1; //将正在保存的字符串设置为第一个字符串
postOrder(T);
inOrder(T);
str1[size1] = 0; //像第一个字符串最后一个字符后添加空字符,方便子使用字符串函数
while (n--)
{
cin >> tmp;
Node *T2 = NULL;
for ( int i = 0; tmp[i] != 0; i++)
{
T2 = Insert(T2, tmp[i] - '0');
}
size2 = 0;
str = str2;
postOrder(T2);
inOrder(T2);
str2[size2] = 0;
puts(strcmp(str1, str2) == 0 ? "Yes" : "No");
}
}
return 0;
}
二叉排序树,
建立二叉排序树,并进行前中后序排列
/*
二叉排序树:对于树上任意一个节点,其上的数值必须大于等于其左子树上任意节点数值,小于等于其右子树上任意节点的数值
*/
#include<stdio.h>
#include<string.h>
using namespace std;
//二叉树结构体
struct Node
{
Node* lchild;
Node* rchild;
int c;//保存数字
}Tree[100];
int loc; //静态数组中被使用的元素的个数
//申请未使用的节点
Node *create()
{
Tree[loc].lchild = Tree[loc].rchild = NULL;
return &Tree[loc++];
}
//插入数字,x为要插入的数字
Node *Insert(Node *T, int x)
{
if (T == NULL)//如果当前树为空
{
T = create(); //创建节点
T->c = x; //数字直接插入当前根节点
return T;
}
else if (x < T->c) //如果小于当前根节点数值
{
T->lchild = Insert(T->lchild, x);//插入当前根节点的左子树
}
else if (x > T->c) //如果大于当前根节点数值
{
T->rchild = Insert(T->rchild, x);//插入当前根节点的右子树
}
//如果存在相同大小的数字,直接不管忽略
return T;
}
//后序遍历
void postOrder(Node *T) {
if (T->lchild != NULL)
{
postOrder(T->lchild);
}
if (T->rchild != NULL)
{
postOrder(T->rchild);
}
printf("%d ", T->c);
}
//中序遍历
void inOrder(Node *T) {
if (T->lchild != NULL)
{
inOrder(T->lchild);
}
printf("%d ", T->c);
if (T->rchild != NULL)
{
inOrder(T->rchild);
}
}
//前序遍历
void preOrder(Node *T) {
printf("%d ", T->c);
if (T->lchild != NULL)
{
preOrder(T->lchild);
}
if (T->rchild != NULL)
{
preOrder(T->rchild);
}
}
int main()
{
int n;
while (scanf_s("%d", &n) != EOF)
{
loc = 0;
Node *T = NULL;
for (int i = 0; i< n; i++)
{
int x;
scanf_s("%d", &x);
T = Insert(T, x);
}
preOrder(T);
printf("\n");
inOrder(T);
printf("\n");
postOrder(T);
printf("\n");
}
return 0;
}