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

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

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

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

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;

}

 

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

目录
相关文章
|
8天前
|
数据库
数据结构中二叉树,哈希表,顺序表,链表的比较补充
二叉搜索树,哈希表,顺序表,链表的特点的比较
数据结构中二叉树,哈希表,顺序表,链表的比较补充
|
2月前
|
机器学习/深度学习 存储 算法
数据结构实验之二叉树实验基础
本实验旨在掌握二叉树的基本特性和遍历算法,包括先序、中序、后序的递归与非递归遍历方法。通过编程实践,加深对二叉树结构的理解,学习如何计算二叉树的深度、叶子节点数等属性。实验内容涉及创建二叉树、实现各种遍历算法及求解特定节点数量。
93 4
|
2月前
|
C语言
【数据结构】二叉树(c语言)(附源码)
本文介绍了如何使用链式结构实现二叉树的基本功能,包括前序、中序、后序和层序遍历,统计节点个数和树的高度,查找节点,判断是否为完全二叉树,以及销毁二叉树。通过手动创建一棵二叉树,详细讲解了每个功能的实现方法和代码示例,帮助读者深入理解递归和数据结构的应用。
142 8
|
3月前
|
存储 算法 关系型数据库
数据结构与算法学习二一:多路查找树、二叉树与B树、2-3树、B+树、B*树。(本章为了解基本知识即可,不做代码学习)
这篇文章主要介绍了多路查找树的基本概念,包括二叉树的局限性、多叉树的优化、B树及其变体(如2-3树、B+树、B*树)的特点和应用,旨在帮助读者理解这些数据结构在文件系统和数据库系统中的重要性和效率。
32 0
数据结构与算法学习二一:多路查找树、二叉树与B树、2-3树、B+树、B*树。(本章为了解基本知识即可,不做代码学习)
|
3月前
|
存储 算法
探索数据结构:分支的世界之二叉树与堆
探索数据结构:分支的世界之二叉树与堆
|
2月前
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
230 9
|
2月前
|
存储 算法
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
37 1
|
2月前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
68 5
|
2月前
|
存储 算法 Java
数据结构的栈
栈作为一种简单而高效的数据结构,在计算机科学和软件开发中有着广泛的应用。通过合理地使用栈,可以有效地解决许多与数据存储和操作相关的问题。
|
2月前
|
存储 JavaScript 前端开发
执行上下文和执行栈
执行上下文是JavaScript运行代码时的环境,每个执行上下文都有自己的变量对象、作用域链和this值。执行栈用于管理函数调用,每当调用一个函数,就会在栈中添加一个新的执行上下文。