二叉樹按層遍歷(每層一行)

問題:
這裏寫圖片描述

如上二叉樹,請按層遍歷,每層一行,遍歷結果如下:

1
2   3
4   5   6   7
8

我的思路:
在按層遍歷之前,我們可以思考一下,如果我們從根結點看起,通過根節點,我們就能找到下一層中同層的所有的節點,得到下一層所有的節點,那麼就能找到下下一層同層的所有的節點,以此類推,就能實現按層遍歷了,但是由於樹的原因,我們不可能直接按層遍歷,所以得找到一個數據結構,能保存同層中不能一次性訪問的節點,經過分析,符合先進先出條件,那麼隊列就當仁不讓的站出來啦!
上面一段分析了實現按層遍歷,但是題目條件是需要一層一行的輸出,因此我們就需要適時的給輸出加上換行。我的想法是能不能在隊列中保存節點信息的同時,稍帶的把節點所在層數也保存起來,只要遇到層數改變,就在輸出前加上回車,不是就實現了按層輸出,每層一行的要求嗎?是的!
代碼如下:

#include<stdio.h>
#include<stdlib.h>

#define SQU_MAX 100

//定義二叉樹節點
struct BinaryTreeNode
{
    int id;
    struct BinaryTreeNode *left;
    struct BinaryTreeNode *right;
};

//保存節點內容和節點高度
struct BinaryTreeWithHight
{
    int height;
    struct BinaryTreeNode *data;
};

//隊列結構體
typedef struct
{
    struct BinaryTreeWithHight *data[SQU_MAX];
    int top;
    int length;
}Queue;

//創建二叉樹
struct BinaryTreeNode* createBinaryTree()
{
    int id;
    scanf("%d",&id);
    if (id == 0)
    {
        return NULL;
    }
    struct BinaryTreeNode *root;
    root=(struct BinaryTreeNode *)malloc(sizeof(struct BinaryTreeNode));
    root->id=id;
    root->left = createBinaryTree();
    root->right = createBinaryTree();
    return root;
}

//先序遍歷二叉樹
void printBinaryTreeFirst(struct BinaryTreeNode *root)
{
    if(root == NULL)
    {
        return;
    }
    printf("%d\t\n",root->id);
    printBinaryTreeFirst(root->left);
    printBinaryTreeFirst(root->right);
}


//返回隊列長度
int QueueLength(Queue *queue)
{
    return queue->length;
}

//判空
int IsEmpty(Queue *queue)
{
    if(queue->length == 0)
    {
        return 1;
    }
    return 0;
}
//判滿
int IsFull(Queue *queue)
{
    if(queue->length == SQU_MAX)
    {
        return 1;
    }
    return 0;
}


//入隊列
int InsertQueue(struct BinaryTreeWithHight *data, Queue *queue)
{
    if(IsFull(queue))
    {
        printf("隊列已滿!\n");
        return 0;
    }
    queue->top = (queue->top+1) % SQU_MAX;
    queue->length++;
    queue->data[queue->top]=data;
    return 1;
}

//出隊列
struct BinaryTreeWithHight *DeleteQueue(Queue *queue)
{
    if(IsEmpty(queue))
    {
        printf("隊列爲空!\n");
        return NULL;
    }
    int tail = (queue->top - queue->length + SQU_MAX + 1) % SQU_MAX;
    struct BinaryTreeWithHight *rtu;
    rtu = queue->data[tail];
    queue->length--;
    return rtu;
}

//按層遍歷
int PrintBinaryTreeByBayer(struct BinaryTreeNode*root, Queue *queue)
{
    if(root == NULL)
    {
        return -1;
    }

    //隊列層數或高度
    int curr_hight=1;

    struct BinaryTreeWithHight *data;
    data = (struct BinaryTreeWithHight *)malloc(sizeof(struct BinaryTreeWithHight));
    data->data=root;
    data->height=curr_hight;

    //將根結點入隊列
    InsertQueue(data,queue);

    while(!IsEmpty(queue))
    {
        struct BinaryTreeWithHight *tmp;

        //將根隊列出棧
        tmp = DeleteQueue(queue);

        //如果遍歷到新的層,則先回車再輸出
        if(tmp->height > curr_hight)
        {
            curr_hight++;
            printf("\n");
        }
        //輸出
        printf("%d\t", tmp->data->id);

        //如果左子樹不爲空
        if(tmp->data->left != NULL)
        {

            //入隊列
            struct BinaryTreeWithHight *left;
            left = (struct BinaryTreeWithHight *)malloc(sizeof(struct BinaryTreeWithHight));
            left->height=tmp->height+1;
            left->data = tmp->data->left;
            InsertQueue(left,queue);
        }
        //如果右子樹不爲空
        if(tmp->data->right != NULL)
        {
            //入隊列
            struct BinaryTreeWithHight *right;
            right = (struct BinaryTreeWithHight *)malloc(sizeof(struct BinaryTreeWithHight));
            right->height = tmp->height+1;
            right->data = tmp->data->right;
            InsertQueue(right, queue);
        }
    }
    return 0;
}

//初始化隊列
void InitQueue(Queue **queue)
{
    *queue=(Queue *)malloc(sizeof(Queue));
    (*queue)->top = -1;
    (*queue)->length = 0;
}

int main()
{
    struct BinaryTreeNode *root;
    root = createBinaryTree();
    printBinaryTreeFirst(root);
    Queue *queue;
    InitQueue(&queue);
    PrintBinaryTreeByBayer(root,queue);
    printf("\n");
}

結果如下:
這裏寫圖片描述

發佈了129 篇原創文章 · 獲贊 203 · 訪問量 45萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章