二叉树层序遍历

文章提供了四种不同的C++实现方式,使用队列进行二叉树的层次遍历(广度优先搜索)。这四种方法包括标准库queue、固定大小数组、动态数组以及链表实现的队列,展示了如何从根节点开始,按层遍历每个节点并输出其值。
摘要由CSDN通过智能技术生成

用STL中的queue实现

//
// Created by Cauchyshy on 2023/5/23.
//

// 层次遍历(广度遍历)从上到下 从左到右一层一层遍历
// 逻辑 利用队列 没有这个就没有直接转换成简洁递归了 有栈可以转简洁递归
#include <iostream>
#include <cstdio>
#include <queue>

using namespace std;

struct treeNode {
    int a; // 数据成员
    struct treeNode *pFather; // 父节点
    struct treeNode *pLeft; // 左孩子
    struct treeNode *pRight; // 右孩子
};



void look(struct treeNode *root) {
    queue<struct treeNode *> que;
    if (root != NULL) {
        que.push(root);
    }
    while (!que.empty()) {
        printf("%d ", que.front()->a);
        if (que.front()->pLeft != NULL) que.push(que.front()->pLeft);
        if (que.front()->pRight != NULL) que.push(que.front()->pRight);
        que.pop();
    }
}

int main() {
    struct treeNode t1 = { 1 };
    struct treeNode t2 = { 2 };
    struct treeNode t3 = { 3 };
    struct treeNode t4 = { 4 };
    struct treeNode t5 = { 5 };
    struct treeNode t6 = { 6 };
    struct treeNode t7 = { 7 };
    struct treeNode t8 = { 8 };
    struct treeNode t9 = { 9 };
    struct treeNode t10 = { 10 };

    // 链接
    t1.pLeft = &t2;
    t1.pRight = &t3;
    t1.pFather = NULL;

    t2.pLeft = &t4;
    t2.pRight = &t5;
    t2.pFather = &t1;

    t3.pRight = &t6;
    t3.pLeft = NULL;
    t3.pFather = &t1;

    t4.pLeft = NULL;
    t4.pRight = NULL;
    t4.pFather = &t2;

    t5.pLeft = &t7;
    t5.pRight = &t8;
    t5.pFather = &t2;

    t6.pLeft = &t9;
    t6.pRight = &t10;
    t6.pFather = &t3;

    t7.pLeft = NULL;
    t7.pRight = NULL;
    t7.pFather = &t5;

    t8.pLeft = NULL;
    t8.pRight = NULL;
    t8.pFather = &t5;

    t9.pLeft = NULL;
    t9.pRight = NULL;
    t9.pFather = &t6;

    t10.pLeft = NULL;
    t10.pRight = NULL;
    t10.pFather = &t6;
    look(&t1);

    return 0;
}

尾动队列数组实现

//
// Created by Cauchyshy on 2023/5/23.
//

// 层次遍历(广度遍历)从上到下 从左到右一层一层遍历
// 逻辑 利用队列 没有这个就没有直接转换成简洁递归了 有栈可以转简洁递归
#include <iostream>
#include <cstdio>

using namespace std;

struct treeNode {
    int a; // 数据成员
    struct treeNode *pFather; // 父节点
    struct treeNode *pLeft; // 左孩子
    struct treeNode *pRight; // 右孩子
};

#define QUEUS_SIZE 16

// 移动元素型数组队列
struct treeNode *queue[QUEUS_SIZE]; // 队列 只装树的节点
int queueHead = 0; // 队头 默认第一个元素
int queueTail = -1; // 队尾

void push(struct treeNode *node) {
    queueTail++; // 尾巴下标+1
    queue[queueTail] = node; // 入队
}

// 移动数组元素
void move(void) {
    for (int i = 1; i <= queueTail; ++i) { // 队头出掉  后面元素向前移动
        queue[i - 1] = queue[i];
    }
}

struct treeNode *pop(void) {
    if (queueHead > queueTail)
        return NULL; // 无元素 直接返回
    struct treeNode *temp = queue[queueHead];
    move();
    queueTail--; // 队尾减一 因为向前移动了
    return temp;
}



void look(struct treeNode *root) {
    if (root != NULL) {
        push(root);
    }
    while (!(queueHead > queueTail)) {
        printf("%d ", queue[queueHead]->a);
        if (queue[queueHead]->pLeft != NULL) push(queue[queueHead]->pLeft);
        if (queue[queueHead]->pRight != NULL) push(queue[queueHead]->pRight);
        pop();
    }
}

int main() {
    struct treeNode t1 = { 1 };
    struct treeNode t2 = { 2 };
    struct treeNode t3 = { 3 };
    struct treeNode t4 = { 4 };
    struct treeNode t5 = { 5 };
    struct treeNode t6 = { 6 };
    struct treeNode t7 = { 7 };
    struct treeNode t8 = { 8 };
    struct treeNode t9 = { 9 };
    struct treeNode t10 = { 10 };

    // 链接
    t1.pLeft = &t2;
    t1.pRight = &t3;
    t1.pFather = NULL;

    t2.pLeft = &t4;
    t2.pRight = &t5;
    t2.pFather = &t1;

    t3.pRight = &t6;
    t3.pLeft = NULL;
    t3.pFather = &t1;

    t4.pLeft = NULL;
    t4.pRight = NULL;
    t4.pFather = &t2;

    t5.pLeft = &t7;
    t5.pRight = &t8;
    t5.pFather = &t2;

    t6.pLeft = &t9;
    t6.pRight = &t10;
    t6.pFather = &t3;

    t7.pLeft = NULL;
    t7.pRight = NULL;
    t7.pFather = &t5;

    t8.pLeft = NULL;
    t8.pRight = NULL;
    t8.pFather = &t5;

    t9.pLeft = NULL;
    t9.pRight = NULL;
    t9.pFather = &t6;

    t10.pLeft = NULL;
    t10.pRight = NULL;
    t10.pFather = &t6;
    look(&t1);

    return 0;
}

头动队列层序遍历

//
// Created by Cauchyshy on 2023/5/23.
//

// 层次遍历(广度遍历)从上到下 从左到右一层一层遍历
// 逻辑 利用队列 没有这个就没有直接转换成简洁递归了 有栈可以转简洁递归
// 浪费空间型 头出一个后面不移动 定义头下边遍历 做逻辑移动 让下一个元素代表队头即可
#include <iostream>
#include <cstdio>

using namespace std;

struct treeNode {
    int a; // 数据成员
    struct treeNode *pFather; // 父节点
    struct treeNode *pLeft; // 左孩子
    struct treeNode *pRight; // 右孩子
};

#define QUEUS_SIZE 16

// 移动元素型数组队列
struct treeNode *queue[QUEUS_SIZE]; // 队列 只装树的节点
int queueHead = 0; // 队头 默认第一个元素
int queueTail = -1; // 队尾

void push(struct treeNode *node) {
    queueTail++; // 尾巴下标+1
    queue[queueTail] = node; // 入队
}


struct treeNode *pop(void) {
    if (queueHead > queueTail)
        return NULL; // 无元素 直接返回
    queueHead++;
    return queue[queueHead - 1];
}



void look(struct treeNode *root) {
    if (root != NULL) {
        push(root);
    }
    while (!(queueHead > queueTail)) {
        printf("%d ", queue[queueHead]->a);
        if (queue[queueHead]->pLeft != NULL) push(queue[queueHead]->pLeft);
        if (queue[queueHead]->pRight != NULL) push(queue[queueHead]->pRight);
        pop();
    }
}

int main() {
    struct treeNode t1 = { 1 };
    struct treeNode t2 = { 2 };
    struct treeNode t3 = { 3 };
    struct treeNode t4 = { 4 };
    struct treeNode t5 = { 5 };
    struct treeNode t6 = { 6 };
    struct treeNode t7 = { 7 };
    struct treeNode t8 = { 8 };
    struct treeNode t9 = { 9 };
    struct treeNode t10 = { 10 };

    // 链接
    t1.pLeft = &t2;
    t1.pRight = &t3;
    t1.pFather = NULL;

    t2.pLeft = &t4;
    t2.pRight = &t5;
    t2.pFather = &t1;

    t3.pRight = &t6;
    t3.pLeft = NULL;
    t3.pFather = &t1;

    t4.pLeft = NULL;
    t4.pRight = NULL;
    t4.pFather = &t2;

    t5.pLeft = &t7;
    t5.pRight = &t8;
    t5.pFather = &t2;

    t6.pLeft = &t9;
    t6.pRight = &t10;
    t6.pFather = &t3;

    t7.pLeft = NULL;
    t7.pRight = NULL;
    t7.pFather = &t5;

    t8.pLeft = NULL;
    t8.pRight = NULL;
    t8.pFather = &t5;

    t9.pLeft = NULL;
    t9.pRight = NULL;
    t9.pFather = &t6;

    t10.pLeft = NULL;
    t10.pRight = NULL;
    t10.pFather = &t6;
    look(&t1);

    return 0;
}

链表队列层序遍历

//
// Created by Cauchyshy on 2023/5/23.
//

// 层次遍历(广度遍历)从上到下 从左到右一层一层遍历
// 逻辑 利用队列 没有这个就没有直接转换成简洁递归了 有栈可以转简洁递归
// 无空头 尾添加 头出
#include <iostream>
#include <cstdio>
#include <malloc.h>

using namespace std;

struct treeNode {
    int a; // 数据成员
    struct treeNode *pFather; // 父节点
    struct treeNode *pLeft; // 左孩子
    struct treeNode *pRight; // 右孩子
};

struct queue {
    struct treeNode *node; // 指向树的节点
    struct queue *next; // 队节点后指针
};

struct queue *queueHead; // 队头 空头
struct queue *queuetail; // 队尾

void push(struct treeNode* node) {
    if (NULL == node) {
        return ;
    }
    // 申请空间 并赋值
    struct queue *temp = (struct queue*)malloc(sizeof(struct queue));
    if (NULL == temp) {
        return ;
    }
    temp->node = node;
    temp->next = NULL;

    // 链接 判断头尾指针
    if (NULL == queueHead) {
        queueHead = temp;
        queuetail = temp;
    } else {
        queuetail->next = temp;
        queuetail = queuetail->next; // 赋值完尾巴移动
    }
}

struct treeNode *pop(void) {
    if (NULL == queuetail) {
        return NULL;
    }
    struct queue *tmp = queueHead;
    struct treeNode *tp = tmp->node;
    queueHead = queueHead->next; // 记录完头后面走
    if (NULL == queueHead) {
        queuetail = NULL; // 万一为空了
    }
    free(tmp);
    return tp;
}

void look(struct treeNode *root) {
    if (root != NULL) {
        push(root);
    }
    while (1) {
        struct treeNode *temp = pop();
        printf("%d ", temp->a);
        if (temp->pLeft != NULL) push(temp->pLeft);
        if (temp->pRight != NULL) push(temp->pRight);
        if (queueHead == NULL) break;
        // pop();
    }
}

int main() {
    struct treeNode t1 = { 1 };
    struct treeNode t2 = { 2 };
    struct treeNode t3 = { 3 };
    struct treeNode t4 = { 4 };
    struct treeNode t5 = { 5 };
    struct treeNode t6 = { 6 };
    struct treeNode t7 = { 7 };
    struct treeNode t8 = { 8 };
    struct treeNode t9 = { 9 };
    struct treeNode t10 = { 10 };

    // 链接
    t1.pLeft = &t2;
    t1.pRight = &t3;
    t1.pFather = NULL;

    t2.pLeft = &t4;
    t2.pRight = &t5;
    t2.pFather = &t1;

    t3.pRight = &t6;
    t3.pLeft = NULL;
    t3.pFather = &t1;

    t4.pLeft = NULL;
    t4.pRight = NULL;
    t4.pFather = &t2;

    t5.pLeft = &t7;
    t5.pRight = &t8;
    t5.pFather = &t2;

    t6.pLeft = &t9;
    t6.pRight = &t10;
    t6.pFather = &t3;

    t7.pLeft = NULL;
    t7.pRight = NULL;
    t7.pFather = &t5;

    t8.pLeft = NULL;
    t8.pRight = NULL;
    t8.pFather = &t5;

    t9.pLeft = NULL;
    t9.pRight = NULL;
    t9.pFather = &t6;

    t10.pLeft = NULL;
    t10.pRight = NULL;
    t10.pFather = &t6;
    look(&t1);

    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

只微

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值