二叉树的层序遍历 相关知识

2023.9.9:

题目:

 

//编写一个程序读入用户输入的一串先序遍历的字符串

//根据这个字符串创建一个二叉树并以指针的方式存储

//题目示例字符串:ABC##DEG##F###

代码以及注释分析:

typedef int BTDataType;
typedef struct BinaryTreeNode
{
	BTDataType data;
	struct BinaryTreeNode* left;
	struct BinaryTreeNode* right;
}BTNode;



//这个函数接收一个int类型数组的首元素地址、一个用于记录当前处理位置的指针pi
BTNode* BinaryTreeCreate(BTDataType* a, int* pi)
{
	//当程序读到该字符为符号#时,在树中创建空结点NULL
	if (a[*pi] == '#')
	{
		(*pi)++;
		return NULL;
	}

	//在树中开辟一个新的结点,通过malloc函数创建新的空间
	//并通过一个if语句来判断malloc是否成功
	BTNode* root = (BTNode*)malloc(sizeof(BTNode));
	if (root == NULL)

	{
		perror("malloc fail\n");
		return NULL;
	}

	//将创建好的树(目前只有一个根节点)
	//将它的内容设置为字符串的一个字符

	root->data = a[*pi];
	(*pi)++;                                   //字符串向后走一个字符

	//通过递归的方式将下一个字符的地址传入函数
	root->left = BinaryTreeCreate(a, pi);
	root->right = BinaryTreeCreate(a, pi);

	//递归完成时,将创建好的树的根节点地址返回
	return root;

}

//通过typedef关键字将定义的二叉树结点

//定义为名称"BTNode"

//每个二叉树结点都拥有一个int类型的“data”数据

//并且拥有相同类型的两个指针(都为BinaryTreeNode类型)

typedef int BTDataType;

typedef struct BinaryTreeNode

{

BTDataType data;

struct BinaryTreeNode* left;

struct BinaryTreeNode* right;

}BTNode;

(图中的结点结构体已经通过typedef关键字重新命名为:BTNode)

 

层序遍历:

复习:有关队列的知识(使用ChatGPT

队列是一种常见的数据结构,它按照先进先出(FIFO)的原则管理元素。在队列中,新元素被添加到队列的末尾,而从队列中删除元素时,总是从队列的前端进行操作。这样确保了先进入队列的元素先被处理。

队列通常具有以下两个基本操作:

1. 入队(enqueue):将元素添加到队列的末尾。

2. 出队(dequeue):从队列的前端删除并返回元素。

除了基本操作外,队列还具有其他常用的操作,例如:

- 判空(isEmpty):判断队列是否为空。

- 判满(isFull):判断队列是否已满。

- 获取队首元素(front):返回队列的第一个元素,而不删除它。

- 获取队列长度(size):返回队列中元素的数量。



#include <stdio.h>

#include <stdlib.h>

#include <stdbool.h>

 

 #define MAX_SIZE 100

 

 // 定义队列结构

 typedef struct {

     int data[MAX_SIZE];

     int front;  // 队首索引

     int rear;  // 队尾索引

} Queue;

 

// 初始化队列

void initQueue(Queue* queue) {

    queue->front = 0;

    queue->rear = -1;

}

 

// 入队

void enqueue(Queue* queue, int item) {

    if (queue->rear == MAX_SIZE - 1) {

        printf("队列已满,无法入队。\n");

        return;

    }

 

    queue->rear++;

    queue->data[queue->rear] = item;

    printf("入队元素:%d\n", item);

}

 

// 出队

int dequeue(Queue* queue) {

    if (queue->rear < queue->front) {

        printf("队列为空,无法出队。\n");

        return -1;

    }

 

    int item = queue->data[queue->front];

    queue->front++;

    printf("出队元素:%d\n", item);

    return item;

}

 

// 判空

bool isEmpty(Queue* queue) {

    return queue->rear < queue->front;

}

 

// 判满

bool isFull(Queue* queue) {

    return queue->rear == MAX_SIZE - 1;

}

 

// 获取队首元素

int front(Queue* queue) {

    if (isEmpty(queue)) {

        printf("队列为空。\n");

        return -1;

    }

    return queue->data[queue->front];

}

 

// 获取队列长度

int size(Queue* queue) {

    return queue->rear - queue->front + 1;

}

 

int main() {

    Queue queue;

    initQueue(&queue);

 

    enqueue(&queue, 1);

    enqueue(&queue, 2);

    enqueue(&queue, 3);

 

    printf("队列长度:%d\n", size(&queue));

    printf("队首元素:%d\n", front(&queue));

 

    dequeue(&queue);

    dequeue(&queue);

 

    printf("队列长度:%d\n", size(&queue));

    printf("队首元素:%d\n", front(&queue));

 

    return 0;

}

​

```

在上面的代码中,使用结构体 `Queue` 定义了一个队列。它包含一个整型数组 `data` 作为队列的存储空间,以及 `front` 和 `rear` 分别表示队首和队尾的索引。

使用 `initQueue` 函数来初始化队列,将 `front` 设为0,`rear` 设为-1。

`enqueue` 函数用于将元素入队。首先检查队列是否已满,如果已满则打印提示信息并返回。否则,将 `rear` 向后移动一位,并将元素存入 `data` 数组中。

`dequeue` 函数用于将元素出队。首先检查队列是否为空,如果为空则打印提示信息并返回-1。否则,返回队首元素,并将 `front` 向后移动一位。

`isEmpty` 函数用于判断队列是否为空,如果 `rear` 小于 `front`,则队列为空。

`isFull` 函数用于判断队列是否已满,如果 `rear` 等于 `MAX_SIZE - 1`,则队列已满。

`front` 函数用于获取队首元素,如果队列为空,则打印提示信息并返回-1。

`size` 函数用于获取队列的长度,计算方法为 `rear - front + 1`。

在主函数中,初始化队列,然后进行一系列的入队和出队操作,并打印队列的长度和队首元素。

另外一种通过队列先进先出实现二叉树销毁的方法:

主要思路:上一层出队列的时候代入子节点,以此遍历整棵树

代码:

 

判断一棵树是不是完全二叉树:

思路:如果在进行层序遍历的时候遇到了NULL值,但是后面的数值全部都为NULL值,则能说明该树为完全二叉树,如果存在非空数据,说明不是完全二叉树

#include <stdbool.h>

#include <stdio.h>

#include <stdlib.h>

 

// 定义二叉树节点结构

typedef struct BTNode {

    int data;

    struct BTNode* left;

    struct BTNode* right;

} BTNode;

 

// 创建新的二叉树节点

BTNode* createNode(int data) {

    BTNode* node = malloc(sizeof(BTNode));

    node->data = data;

    node->left = NULL;

    node->right = NULL;

    return node;

}

 

// 判断一棵树是否是完全二叉树

bool BinaryTreeComplete(BTNode* root) {

    if (root == NULL) {

        return true;

    }

 

    // 创建队列并初始化

    BTNode** queue = malloc(sizeof(BTNode*) * 1000);

    int front = 0;  // 队首索引

    int rear = 0;   // 队尾索引

 

    // 将根节点入队

    queue[rear++] = root;

 

    // 标记是否遇到过空节点

    bool foundNull = false;

 

    while (front < rear) {

        BTNode* node = queue[front++];

 

        // 如果遇到空节点,并且后续还有非空节点,说明不是完全二叉树

        if (node == NULL) {

            foundNull = true;

        } else {

            // 如果已经遇到过空节点,并且当前节点非空,说明不是完全二叉树

            if (foundNull) {

                free(queue);

                return false;

            }

 

            // 将当前节点的左子节点和右子节点入队

            queue[rear++] = node->left;

            queue[rear++] = node->right;

        }

    }

 

    free(queue);

    return true;

}

 

int main() {

    // 构造示例二叉树

    BTNode* root = createNode(1);

    root->left = createNode(2);

    root->right = createNode(3);

    root->left->left = createNode(4);

    root->left->right = createNode(5);

    root->right->left = createNode(6);

 

    // 判断是否是完全二叉树

    bool isComplete = BinaryTreeComplete(root);

 

    // 打印结果

    if (isComplete) {

        printf("这棵树是完全二叉树\n");

    } else {

        printf("这棵树不是完全二叉树\n");

    }

 

    // 释放内存

    free(root->left->left);

    free(root->left->right);

    free(root->right->left);

    free(root->left);

    free(root->right);

    free(root);

 

    return 0;

}

代码:

深度优先遍历和广度优先遍历:

举例:

DFS:前、中、后序遍历

BFS:层序遍历





评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值