#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct node
{
int data;
struct node *lchild, *rchild;
} * BitTree;
//构造成二叉有序树
void createTree(BitTree &T, int a[], int len)
{
node *head = (node *)malloc(sizeof(node));
head->data = a[0];
head->lchild = NULL;
head->rchild = NULL;
T = head;
for (int i = 1; i < len; i++)
{
node *p = (node *)malloc(sizeof(node));
p->data = a[i];
p->lchild = NULL;
p->rchild = NULL;
node *temp = head;
while (temp != NULL)
{
if (a[i] < temp->data)
{ //新元素更小
if (temp->lchild == NULL)
{ //当前节点的左结点为空,直接存放进去
temp->lchild = p;
break;
}
else
{ //还有比当前节点更小的结点,让当前节点变成更小的那个结点
temp = temp->lchild;
}
}
else
{ //
if (temp->rchild == NULL)
{
temp->rchild = p;
break;
}
else
{
temp = temp->rchild;
}
}
}
}
}
//将二叉树按照先序输出
void PreOrderTraverse(BitTree T)
{
if (T != NULL)
{
printf("%d ", T->data);
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
}
//将二叉树按照中序输出
void InOrderTraverse(BitTree T)
{
if (T != NULL)
{
InOrderTraverse(T->lchild);
printf("%d ", T->data);
InOrderTraverse(T->rchild);
}
}
//将二叉树按照后序输出
void PostOrderTraverse(BitTree T)
{
if (T != NULL)
{
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
printf("%d ", T->data);
}
}
//计算叶子节点个数
int leaf(BitTree T)
{
if (T == NULL)
return 0;
if (T->lchild == NULL && T->rchild == NULL)
return 1;
return leaf(T->lchild) + leaf(T->rchild);
}
//二叉树的深度
int deepth(BitTree T)
{
if (T == NULL)
{
return 0;
}
int x = deepth(T->lchild);
int y = deepth(T->rchild);
return x > y ? x + 1 : y + 1;
}
//层序遍历,一般借用队列,以下用数组简化代码
void floorOrderTraverse(BitTree T)
{
node *nodes[11];
int front = 0, end = 0;
node *temp = T;
nodes[end++] = temp;
while (front != end)
{
printf("%d ", nodes[front++]->data);
if (temp->lchild != NULL)
{
nodes[end++] = temp->lchild;
}
if (temp->rchild != NULL)
{
nodes[end++] = temp->rchild;
}
temp = nodes[front];
}
printf("\n");
}
//二叉树的宽度(直接在层序遍历的基础上改造即可):每遍历一层,保存最大的宽度
int weight(BitTree T)
{
//层数标记
int floors[10];
node *nodes[11];
int front = 0, end = 0;
node *temp = T;
nodes[end++] = temp;
floors[end - 1] = 0;
while (front != end)
{
if (temp->lchild != NULL)
{
nodes[end++] = temp->lchild;
floors[end - 1] = floors[front] + 1;
}
if (temp->rchild != NULL)
{
nodes[end++] = temp->rchild;
floors[end - 1] = floors[front] + 1;
}
temp = nodes[++front];
}
//每个结点位于第多少层(从0开始)
for (int i = 0; i < 10; i++)
{
printf("%2d ", floors[i]);
}
printf("\n");
//计算相同层数的数量并比较得出宽度
int width = 0;
for (int i = 0; i <= floors[9]; i++)//层号从小到大,最后一个就是最底部的层号
{
int j = i;
int w = 1;
for (; j < 10 && floors[j] == i; j++)//这里可以再优化,像kmp的不回溯,多跳几步,不必从i开始
{
w++;
}
if (width < w)
{
width = w;
}
}
return width;
}
//随机数组
void createList(int a[], int len)
{
srand(time(0));
for (int i = 0; i < len; i++)
{
a[i] = rand() % 100;
}
for (int i = 0; i < len; i++)
{
printf("%d ", a[i]);
}
printf("\n");
}
int main()
{
int a[10];
createList(a, 10); //生成随机数组
BitTree T = NULL;
createTree(T, a, 10); //构建二叉排序树
printf("先序遍历:\n");
PreOrderTraverse(T); //先序遍历
printf("\n");
printf("叶子个数:%d\n", leaf(T)); //计算叶子结点
printf("树的深度:%d\n", deepth(T)); //计算最大深度
printf("层序遍历:\n");
floorOrderTraverse(T); //层序遍历
printf("树的宽度:%d\n", weight(T)); //计算宽度
}
二叉树的先序、中序、后序,层序遍历以及叶子结点数量、高度、宽度
最新推荐文章于 2022-04-22 21:37:29 发布