二叉树的先序、中序、后序,层序遍历以及叶子结点数量、高度、宽度

#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)); //计算宽度
}

猜你喜欢

转载自blog.csdn.net/qq_37575994/article/details/122019816