数据结构之二叉树的前中后序遍历以及层序遍历

简介: 数据结构之二叉树的前中后序遍历以及层序遍历

学习目标:读完这篇博客搞定二叉树的前中后序以及层序遍历

首先:你应该明白什么是二叉树,下面这幅图就是一个完全二叉树

ff451a1bb517427889559720f801c288.png

其实所谓的二叉树就是一个节点有小于等于二个分支的树,可以没有分支,可以有1条分支,可以有两条分支,这便是二叉树

  • 还有就是我们要理解二叉树的分治,以及递归,我们要把大事化小,一层一层来解决!

学习内容:二叉树的前中后以及层序遍历的代码实现

我们先来学习一下前序遍历吧,首先什么是前序遍历呢?其实二叉树有根,左子树以及右子树,而二叉树的前序遍历其实就是先遍历根节点在遍历左子树最后在遍历右子树,好讲了这么多都不如上代码来的实际!

struct node

{

   datatype data;

   struct node* plch;

   struct node* prch;

};


struct node* create_bree(void)

{

   struct node* pa = malloc(sizeof(struct node));

   struct node* pb = malloc(sizeof(struct node));

   struct node* pc = malloc(sizeof(struct node));

   struct node* pd = malloc(sizeof(struct node));

   struct node* pe = malloc(sizeof(struct node));

   struct node* pf = malloc(sizeof(struct node));

   struct node* pg = malloc(sizeof(struct node));

   struct node* ph = malloc(sizeof(struct node));

   struct node* pi = malloc(sizeof(struct node));


   pa->data = 'a';

   pb->data = 'b';

   pc->data = 'c';

   pd->data = 'd';

   pe->data = 'e';

   pf->data = 'f';

   pg->data = 'g';

   ph->data = 'h';

   pi->data = 'i';

 

   pa->plch = pb;

   pa->prch = pc;


   pb->plch = pd;

   pb->prch = pe;

 

   pc->plch = NULL;

   pc->prch = pf;


   pd->plch = NULL;

   pd->prch = NULL;

 

   pe->plch = pg;

   pe->prch = ph;


   pf->plch = pi;

   pf->prch = NULL;


   pg->plch = NULL;

   pg->prch = NULL;

 

   ph->plch = NULL;

   ph->prch = NULL;

 

   pi->plch = NULL;

   pi->prch = NULL;


   return pa;

}

//先序遍历

void privot(struct node* proot)

{

   if (proot != NULL)

   {

       if (proot != NULL)

           printf("%c-->", proot->data);

       if (proot->plch != NULL)

           privot(proot->plch);

       if (proot->prch != NULL)

           privot(proot->prch);

   }

}


int main()

{

   struct node* pa = create_bree();

   privot(pa);

   printf("\n");


   return 0;


}

void inorderprint(struct node* proot)

{

   if (proot != NULL)

   {

       if (proot->plch != NULL)

           inorderprint(proot->plch);

       if (proot != NULL)

           printf("%c-->", proot->data);

       if (proot->prch != NULL)

           inorderprint(proot->prch);

   }

}

void houxuprint(struct node* proot)

{

   if (proot != NULL)

   {

       if (proot->plch != NULL)

           houxuprint(proot->plch);

       if (proot->prch != NULL)

           houxuprint(proot->prch);

       if (proot != NULL)

           printf("%c-->", proot->data);

   }

}

最后的话,就来到最重点的时候了哦,就要来写我们的层序遍历了,层序遍历的算法我这里利用了链式队列来实现的,其实层序遍历就是一层一层遍历,从左到右遍历完一层就直接往下一层继续遍历。接下来就是放全部的代码啦!

#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>

#include <stdbool.h>

#include <stdlib.h>

#include <assert.h>


typedef struct node* QDataType;


typedef struct QueueNode

{

   struct QueueNode* next;

   QDataType data;

}QNode;


typedef struct Queue

{

   QNode* head;

   QNode* tail;

}Queue;


void QueueInit(Queue* pq)

{

   assert(pq);

   pq->head = pq->tail = NULL;

}

void QueueDestory(Queue* pq)

{

   assert(pq);

   QNode* cur = pq->head;

   while (cur)

   {

       QNode* next = cur->next;

       free(cur);

       cur = next;

   }

   pq->head = pq->tail = NULL;

}

//队尾入

void QueuePush(Queue* pq, QDataType x)

{

   assert(pq);

   QNode* newnode = (QNode*)malloc(sizeof(QNode));

   if (newnode == NULL)

   {

       printf("malloc fail\n");

       exit(-1);

   }

   newnode->data = x;

   newnode->next = NULL;

   if (pq->tail == NULL)

   {

       pq->head = pq->tail = newnode;

   }

   else

   {

       pq->tail->next = newnode;

       pq->tail = newnode;

   }

}

void QueuePop(Queue* pq)

{

   assert(pq);

   assert(pq->head);

   if (pq->head->next == NULL)

   {

       free(pq->head);

       pq->head = pq->tail = NULL;

   }

   else

   {

       QNode* next = pq->head->next;

       free(pq->head);

       pq->head = next;

   }


}

QDataType QueueFront(Queue* pq)

{

   assert(pq);

   assert(pq->head);


   return pq->head->data;

}

QDataType QueueBack(Queue* pq)

{

   assert(pq);

   assert(pq->head);


   return pq->tail->data;

}

int QueueSize(Queue* pq)

{

   assert(pq);

   int size = 0;

   QNode* cur = pq->head;

   while (cur)

   {

       ++size;

       cur = cur->next;

   }

   return size;

}

bool QueueEmpty(Queue* pq)

{

   assert(pq);

   return pq->head == NULL;

}

typedef char datatype;


struct node

{

   datatype data;

   struct node* plch;

   struct node* prch;

};


struct node* create_bree(void)

{

   struct node* pa = malloc(sizeof(struct node));

   struct node* pb = malloc(sizeof(struct node));

   struct node* pc = malloc(sizeof(struct node));

   struct node* pd = malloc(sizeof(struct node));

   struct node* pe = malloc(sizeof(struct node));

   struct node* pf = malloc(sizeof(struct node));

   struct node* pg = malloc(sizeof(struct node));

   struct node* ph = malloc(sizeof(struct node));

   struct node* pi = malloc(sizeof(struct node));


   pa->data = 'a';

   pb->data = 'b';

   pc->data = 'c';

   pd->data = 'd';

   pe->data = 'e';

   pf->data = 'f';

   pg->data = 'g';

   ph->data = 'h';

   pi->data = 'i';

 

   pa->plch = pb;

   pa->prch = pc;


   pb->plch = pd;

   pb->prch = pe;

 

   pc->plch = NULL;

   pc->prch = pf;


   pd->plch = NULL;

   pd->prch = NULL;

 

   pe->plch = pg;

   pe->prch = ph;


   pf->plch = pi;

   pf->prch = NULL;


   pg->plch = NULL;

   pg->prch = NULL;

 

   ph->plch = NULL;

   ph->prch = NULL;

 

   pi->plch = NULL;

   pi->prch = NULL;


   return pa;

}

//先序遍历

void privot(struct node* proot)

{

   if (proot != NULL)

   {

       if (proot != NULL)

           printf("%c-->", proot->data);

       if (proot->plch != NULL)

           privot(proot->plch);

       if (proot->prch != NULL)

           privot(proot->prch);

   }

 

}

void inorderprint(struct node* proot)

{

   if (proot != NULL)

   {

       if (proot->plch != NULL)

           inorderprint(proot->plch);

       if (proot != NULL)

           printf("%c-->", proot->data);

       if (proot->prch != NULL)

           inorderprint(proot->prch);

   }

}

void houxuprint(struct node* proot)

{

   if (proot != NULL)

   {

       if (proot->plch != NULL)

           houxuprint(proot->plch);

       if (proot->prch != NULL)

           houxuprint(proot->prch);

       if (proot != NULL)

           printf("%c-->", proot->data);

   }

}


void cengxubianli(struct node* proot)

{

   if (proot == NULL)

   {

       return;

   }

   Queue pq;

   QueueInit(&pq);

   QueuePush(&pq, proot);

   while (!QueueEmpty(&pq))

   {

       struct node* head = QueueFront(&pq);                                

       QueuePop(&pq);

       printf("%c ", head->data);

       if (head->plch != NULL)

       {

           QueuePush(&pq, head->plch);

       }

       if (head->prch != NULL)

       {

           QueuePush(&pq, head->prch);

       }

   }

   printf("\n");

}

int main()

{

   struct node* pa = create_bree();

   privot(pa);

   printf("\n");

   inorderprint(pa);

   printf("\n");

   houxuprint(pa);

   printf("\n");

   cengxubianli(pa);

   return 0;

}

 

好啦本次的代码就全部实现完啦,祝大家学习快乐!

目录
相关文章
|
1月前
|
Java C++
【C++数据结构——树】二叉树的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现二叉树的基本运算。​ 相关知识 创建二叉树 销毁二叉树 查找结点 求二叉树的高度 输出二叉树 //二叉树节点结构体定义 structTreeNode{ intval; TreeNode*left; TreeNode*right; TreeNode(intx):val(x),left(NULL),right(NULL){} }; 创建二叉树 //创建二叉树函数(简单示例,手动构建) TreeNode*create
52 12
|
1月前
|
C++
【C++数据结构——树】二叉树的性质(头歌实践教学平台习题)【合集】
本文档介绍了如何根据二叉树的括号表示串创建二叉树,并计算其结点个数、叶子结点个数、某结点的层次和二叉树的宽度。主要内容包括: 1. **定义二叉树节点结构体**:定义了包含节点值、左子节点指针和右子节点指针的结构体。 2. **实现构建二叉树的函数**:通过解析括号表示串,递归地构建二叉树的各个节点及其子树。 3. **使用示例**:展示了如何调用 `buildTree` 函数构建二叉树并进行简单验证。 4. **计算二叉树属性**: - 计算二叉树节点个数。 - 计算二叉树叶子节点个数。 - 计算某节点的层次。 - 计算二叉树的宽度。 最后,提供了测试说明及通关代
50 10
|
1月前
|
存储 算法 测试技术
【C++数据结构——树】二叉树的遍历算法(头歌教学实验平台习题) 【合集】
本任务旨在实现二叉树的遍历,包括先序、中序、后序和层次遍历。首先介绍了二叉树的基本概念与结构定义,并通过C++代码示例展示了如何定义二叉树节点及构建二叉树。接着详细讲解了四种遍历方法的递归实现逻辑,以及层次遍历中队列的应用。最后提供了测试用例和预期输出,确保代码正确性。通过这些内容,帮助读者理解并掌握二叉树遍历的核心思想与实现技巧。
54 2
|
2月前
|
数据库
数据结构中二叉树,哈希表,顺序表,链表的比较补充
二叉搜索树,哈希表,顺序表,链表的特点的比较
数据结构中二叉树,哈希表,顺序表,链表的比较补充
|
1月前
|
数据采集 存储 算法
【C++数据结构——图】图的遍历(头歌教学实验平台习题) 【合集】
本文介绍了图的遍历算法,包括深度优先遍历(DFS)和广度优先遍历(BFS)。深度优先遍历通过递归方式从起始节点深入探索图,适用于寻找路径、拓扑排序等场景;广度优先遍历则按层次逐层访问节点,适合无权图最短路径和网络爬虫等应用。文中提供了C++代码示例,演示了如何实现这两种遍历方法,并附有测试用例及结果,帮助读者理解和实践图的遍历算法。
49 0
|
3月前
|
机器学习/深度学习 存储 算法
数据结构实验之二叉树实验基础
本实验旨在掌握二叉树的基本特性和遍历算法,包括先序、中序、后序的递归与非递归遍历方法。通过编程实践,加深对二叉树结构的理解,学习如何计算二叉树的深度、叶子节点数等属性。实验内容涉及创建二叉树、实现各种遍历算法及求解特定节点数量。
137 4
|
3月前
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
364 9
|
3月前
|
存储 算法
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
58 1
|
1月前
|
存储 C语言 C++
【C++数据结构——栈与队列】顺序栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现顺序栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 1.初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储
150 77
|
13天前
|
DataX
☀☀☀☀☀☀☀有关栈和队列应用的oj题讲解☼☼☼☼☼☼☼
### 简介 本文介绍了三种数据结构的实现方法:用两个队列实现栈、用两个栈实现队列以及设计循环队列。具体思路如下: 1. **用两个队列实现栈**: - 插入元素时,选择非空队列进行插入。 - 移除栈顶元素时,将非空队列中的元素依次转移到另一个队列,直到只剩下一个元素,然后弹出该元素。 - 判空条件为两个队列均为空。 2. **用两个栈实现队列**: - 插入元素时,选择非空栈进行插入。 - 移除队首元素时,将非空栈中的元素依次转移到另一个栈,再将这些元素重新放回原栈以保持顺序。 - 判空条件为两个栈均为空。