二叉树的广度优先遍历

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即可。

相关推荐
JieE21214 小时前
JS 到底有多少种数据类型?从ECMA规范到内存本质,一文彻底搞懂
javascript·数据结构·面试
努力努力再努力wz15 小时前
【内存管理与高并发内存池系列】从 mmap 到 malloc:文件映射、匿名映射与 glibc 内存分配机制详解
linux·c语言·数据结构·数据库·c++·qt·链表
J2虾虾15 小时前
C 语言 void 完全用法
c语言·开发语言
八解毒剂15 小时前
数据结构-平衡二叉树——对二叉搜索树的优化
数据结构·c++·算法
wu_ye_m15 小时前
学习c语言第35天 函数声明和定义
c语言·开发语言·学习
运行时记录15 小时前
别再手动写提示词了 — SkillOpt 让技能文档自己进化
算法
啦啦啦啦啦zzzz16 小时前
算法总结(二分查找、双指针)
c++·算法
qq_85730581916 小时前
python语法
开发语言·python·算法
DXM052116 小时前
第9期|从机器学习到深度学习:AI遥感解译的进化逻辑
人工智能·算法·计算机视觉
小蒋学算法17 小时前
算法-阶乘函数后K个零
算法