二叉树的广度优先遍历

cpp 复制代码
//
// Created by Administrator on 2026/4/28.
//

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

typedef int ElementType;
struct TreeNode;
typedef struct TreeNode *PtrToNode;
typedef PtrToNode Tree;

struct TreeNode {
  ElementType Element;
  Tree Left;
  Tree Right;
};

Tree CreateTree(ElementType rootElement);
PtrToNode CreateNode(ElementType element);
void InsertLeftChild(PtrToNode parent, ElementType element);
void InsertRightChild(PtrToNode parent, ElementType element);
void LevelOrderTraversal(PtrToNode parent);
void DestroyTree(Tree T);



typedef enum { false, true } bool;
typedef PtrToNode QElemSet;
#define NIL -1;

typedef struct QueueNode *Position;
struct QueueNode {
  QElemSet data;
  Position next;
};

typedef struct QueueHeadNode *Queue;
struct QueueHeadNode {
  int size;
  Position front;
  Position rear;
};

bool isEmpty(Queue queue);
Queue InitQueue();
bool EnQueue(Queue queue, QElemSet x);
bool DeQueue(Queue queue);
QElemSet GetFront(Queue queue);
void PrintQueue(Queue queue);
void DestroyQueue(Queue queue);



Tree CreateTree(ElementType rootElement) {
  Tree T = (Tree)malloc(sizeof(struct TreeNode));
  if (T == NULL) {
    printf("Failed to allocate memory for the new Tree\n");
    return NULL;
  }
  T->Element = rootElement;
  T->Left = NULL;
  T->Right = NULL;
  return T;
}

PtrToNode CreateNode(ElementType element) {
  PtrToNode node = (PtrToNode)malloc(sizeof(struct TreeNode));
  if (node == NULL) {
    printf("Failed to allocate memory for the new Tree\n");
    return NULL;
  }
  node->Element = element;
  node->Left = NULL;
  node->Right = NULL;
  return node;
}

void InsertLeftChild(PtrToNode parent,ElementType element) {
  if (parent == NULL) {
    printf("Parent is NULL\n");
    return;
  }
  if (parent->Left != NULL) {
    printf("The LeftChild already exists");
    return;
  }
  parent->Left = CreateNode(element);
}

void InsertRightChild(PtrToNode parent,ElementType element) {
  if (parent == NULL) {
    printf("Parent is NULL\n");
    return;
  }
  if (parent->Right != NULL) {
    printf("The RightChild already exists");
  }
  parent->Right = CreateNode(element);
}

void LevelOrderTraversal(PtrToNode parent) {
  Queue queue = InitQueue();
  EnQueue(queue,parent);
  while (!isEmpty(queue)) {
    PtrToNode front = GetFront(queue);
    DeQueue(queue);
    if (front!=NULL) {
      printf("%d ",front->Element);
      EnQueue(queue,front->Left);
      EnQueue(queue,front->Right);
    }
  }
}

void DestroyTree(Tree T) {
  if (T != NULL) {
    DestroyTree(T->Left);
    DestroyTree(T->Right);
    free(T);
  }
}





bool isEmpty(Queue queue) {
  return queue->size == 0;
}

Queue InitQueue() {
  Queue queue = (Queue)malloc(sizeof(struct QueueHeadNode));
  if (queue==NULL) return NULL;
  queue->size=0;
  queue->front=queue->rear=NULL;
  return queue;
}

bool EnQueue(Queue queue, QElemSet x) {
  if (queue==NULL) return false;
  Position new_node = (Position)malloc(sizeof(struct QueueNode));
  if (new_node==NULL) {
    return false;
  }
  new_node->data=x;
  new_node->next=NULL;
  if (isEmpty(queue)) {
    queue->front=queue->rear=new_node;
  }else {
    queue->rear->next=new_node;
    queue->rear=new_node;
  }
  queue->size++;
  return true;
}

bool DeQueue(Queue queue) {
  if (queue==NULL) return false;
  Position temp=queue->front;
  queue->front=queue->front->next;
  free(temp);
  queue->size--;
  if (queue->front==NULL) {
    queue->rear=NULL;
  }
  return true;
}

QElemSet GetFront(Queue queue) {
  if (queue==NULL) return NULL;
  return queue->front->data;
}

void PrintQueue(Queue queue) {
  if (queue==NULL) return;
  Position p=queue->front;
  while (p!=NULL) {
    printf("%d ",p->data);
    p=p->next;
  }
  printf("\n");
}

void DestroyQueue(Queue queue) {
  if (queue==NULL) return;
  Position p=queue->front;
  while (p!=NULL) {
    Position temp=p;
    p=p->next;
    free(temp);
  }
  free(queue);
}






int main() {
  Tree T = CreateTree(1);
  InsertLeftChild(T, 2);
  InsertRightChild(T, 3);
  InsertLeftChild(T->Left, 4);
  InsertRightChild(T->Left, 5);
  LevelOrderTraversal(T);
  DestroyTree(T);
  return 0;
}

①:层次遍历二叉树就是从根节点开始,从上往下,从左往右一层一层得遍历每一个结点的算法,大致的逻辑是,先将根结点放进队列里,然后开始读取同时让根节点出队,接着先将左子结点入队,再将右子节点入队,这样队列里就有两个结点了,出队的顺序也是先左子节点,再右子节点,然后先出左子节点,再把左子节节点的子节点放进去,由于队列的特性,左子节点的子节点们排在右子节点后面,所以下一次出队的是右子节点,就这样完成了层次遍历。

②:为了让队列存储的元素类型为结点,只需要把PtrToNode起别名为QElemSet即可。

相关推荐
70asunflower1 小时前
C/C++ 自定义函数的常用规范:从入门到工程实践
c语言·c++
谭欣辰1 小时前
C++ DFS 与 BFS 剪枝方法详解
c++·算法·剪枝
love在水一方1 小时前
【Voxel-SLAM】Data Structures / 数据结构文档(二)
数据结构·人工智能·机器学习
Via_Neo1 小时前
乘积最大问题
数据结构·算法
CN-Dust1 小时前
【C++专题】格式化输出与输入
开发语言·c++·算法
自我意识的多元宇宙1 小时前
数据结构----插入排序
数据结构·算法·排序算法
im_AMBER1 小时前
Leetcode 162 除了自身以外数组的乘积 | 接雨水
开发语言·javascript·数据结构·算法·leetcode
Westward-sun.1 小时前
YOLO目标检测算法与mAP评估指标详解(附示例)
算法·yolo·目标检测
cpp_25012 小时前
P1873 [COCI 2011/2012 #5] EKO / 砍树
数据结构·c++·算法·题解·二分答案·洛谷·csp