二叉树的广度优先遍历

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

相关推荐
zero.cyx12 小时前
软件设计师(3)数据结构
数据结构
夏日听雨眠12 小时前
数据结构(堆排序,基数排序)
数据结构·算法
什仙12 小时前
Ansys Maxwell 默认求解器选择
人工智能·笔记·算法·基础·ansys·maxwell
weixin_3077791312 小时前
基于Vosk与CTranslate2的实时语音识别翻译系统 —— 完整C++实现详解
人工智能·算法·自动化·语音识别·原型模式
akarinnnn12 小时前
深入理解内存函数:原理、应用与优化
c语言·网络·数据结构·算法
一行代码一行诗++13 小时前
for循环中的break和continue
数据结构·算法
Tisfy13 小时前
LeetCode 3043.最长公共前缀的长度:哈希表(不转string)
算法·leetcode·散列表·题解·哈希表
代码中介商13 小时前
排序算法完全指南(三):插入排序深度详解
算法·排序算法
承渊政道13 小时前
【贪心算法】(经典实战应用解析(六):整数替换、俄罗斯套娃信封问题、可被三整除的最⼤和、距离相等的条形码、重构字符串)
c++·算法·leetcode·贪心算法·排序算法·动态规划·哈希算法
宠..13 小时前
VS Code SSH 远程连接 Ubuntu 并实现快速运行(C/C++示例)
java·运维·c语言·开发语言·c++·ubuntu·ssh