由二叉树深度优先遍历和广度优先遍历 看人最大的敌人其实是自己

最大的敌人其实是自己

最近报了极客时间的21天打卡,今天是第七天周日,感觉周六的时候是最难坚持的,因为自己想要利用这个打卡复习一下算法训练营的内容,虽然参加了,并且最后毕业了,但是自己还是感觉对常用的算法和数据结构一知半解,一知半解的评价都有点高,应该是不怎么解,所以要复习和巩固一下

从递归开始,递归的最主要的思想就是:

  • 找重复性,抵制人肉递归的诱惑
  • 找到最近最简方法,将其拆解成可重复解决的问题(重复子问题)
  • 数学归纳法思维

然后到树了,二叉树的前序、中序、后序遍历,其中需要使用到栈和队列,尤其是队列看了代码是没有理解的,也不是说没有理解使用队列遍历二叉树,应该是没有理解队列的实现和使用,因为在使用c写算法和数据结构,所以一直没有get到队列的精髓(从这里可以看出自己的基础是比较弱的,所以需要多多练习,多多实践)

自己需要使用队列的时候还是感觉到比较难的,其中有想要放弃的时候,可是放弃的话,下次你遇见到它的时候还是不会,还是不知道怎么写,所以咬下牙,克服掉它,下次就会好很多了。还要你一定要知道自己要什么,你才可能到你想要的地方。对于程序也是如此,你一定要明白和理解你要实现到什么效果,然后去分析、拆解、调试、获得反馈、优化,才可能写出你自己想要的代码。

为什么说人最大的敌人是自己呢?

在遇到困难或者不会的知识点的时候,心里面有两个你,一个你说:这个放一放把,后面遇到慢慢就会学会的,一个你说:这个你放了,后面你还是不会的,不如当下把它解决掉,学会,当然现实中大多数是后者,当然如果你超出你当前的知识水平学习特别难的东西的时候建议你选前者,如果这个问题你跳一下可以碰到的话,一定要选择后者,把它当前解决掉,fix掉。这个后面其实就是人性的懒惰。

还有不要贪心,遇到的好的东西,既想要A还想要B,你要知道自己没有那么多时间和精力都想要的,把自己最好的时间和精力留给最重要的人和事!

代码如下:

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

#define MAXSIZE 100
#define OK 1
#define ERROR 0

struct TreeNode {
   int val;
   struct TreeNode *left;
   struct TreeNode *right;
}TreeNode;

typedef struct {
   struct TreeNode* data[MAXSIZE];
   int front;
   int rear;
}SqQueue;

struct TreeNode* initTree() {
   struct TreeNode *root;
   int data;
   scanf("%d",&data);

   if (data == 0) {
    root = NULL;
    return root;
   }else {
    root = (struct TreeNode*)malloc(sizeof(struct TreeNode));
    if (!root) {
       return NULL;
    }
    root->val = data;
    printf("输入%d的左节点", data);
    root->left = initTree();
    printf("输入%d的右节点", data);
    root->right = initTree();
   }
   return root;
}

int EnQueue(SqQueue *Q,struct TreeNode *root) {
   if ((Q->rear+1)%MAXSIZE == Q->front) {
    return ERROR;
    }
    Q->data[Q->rear] = root;
    Q->rear = (Q->rear+1) % MAXSIZE;
    return OK;
}

int InitQueue(SqQueue *Q) {
   Q->front = 0;
   Q->rear = 0;
   return 1;
}

struct TreeNode* DeQueue(SqQueue *Q) {
    struct TreeNode *root;
    if (Q->front == Q->rear) {
       return ERROR;
    }
    root = Q->data[Q->front];
    Q->front = (Q->front+1) % MAXSIZE;
    return root;
}

void queueTraversal(struct TreeNode *root) {
   // 利用队列实现层序遍历
   if (!root) {
       return;
   }
   // 创建队列
   SqQueue q;
   InitQueue(&q);
   EnQueue(&q,root);
   int i = 0;
   printf("层序遍历是\n");
   while (q.front != q.rear) {
       root = DeQueue(&q);
       printf("%d ",root->val);
       if (root->left)
       EnQueue(&q,root->left);
       if (root->right)
       EnQueue(&q,root->right);
    }
   printf("\n");
}

void stackTraversal(struct TreeNode *root) {
    struct TreeNode* stack[100];
    int top = -1;
    printf("非递归中序比那里如下:\n");
    while (root || top != -1) {
    while (root) {
        // 把所有左树入栈
        top++;
        stack[top] = root;
        root = root->left;
    }
    if (top != -1) {
        root = stack[top];
        top--;
        printf("%d ",root->val);    // 输出节点数据
        root=root->right;
    }
    }
    printf("\n");
}

int main() {
   // 开辟头节点
   struct TreeNode* tree;
   // 将头节点指针传入函数参数为节点指针的参数
   tree = initTree();

   // 然后根据条件输入创建二叉树

   // 使用队列层序遍历二叉树
   queueTraversal(tree);
   // 使用栈深度遍历二叉树
   stackTraversal(tree);
   printf("Hello world\n");
   return 0;
}

参考文章:
C语言实现二叉树(创建,先序,中序,后序遍历的递归实现,以及非递归的中序遍历(栈),求树的高度)http://www.manongzj.com/blog/3-mcmgrgfddalajnn.html
二叉树利用队列实现层次遍历 https://blog.csdn.net/lafengxiaoyu/article/details/53240346

原文地址:https://www.cnblogs.com/zhangpengfei5945/p/12182172.html

时间: 2024-07-30 11:09:08

由二叉树深度优先遍历和广度优先遍历 看人最大的敌人其实是自己的相关文章

二分搜索树的深度优先遍历和广度优先遍历

二分搜索树的特点 二分搜索树首先是一个二叉树,其次其必须满足的条件是:每个节点的键值必须大于其左子节点,每个节点的键值必须小于其右子节点,这样以左右孩子为根的子树仍为二分搜索树,需要注意的是,二分搜索树不一定是一颗完全二叉树. 深度优先遍历 深度优先遍历的基本思想:对每一个可能的分支路径深入到不能再深入为止,而且每个结点只能访问一次.深度优先遍历的非递归的通用做法是采用栈.要特别注意的是,二分搜索树的深度优先遍历比较特殊,可以细分为前序遍历.中序遍历.后序遍历. 前序遍历:先访问当前节点,再依次

基于邻接表存储的图的深度优先遍历和广度优先遍历

一.深度优先遍历是连通图的一种遍历策略.其基本思想如下: 设x是当前被访问顶点,在对x做过访问标记后,选择一条从x出发的未检测过的边(x,y).若发现顶点y已访问过,则重新选择另一条从x出发的未检测过的边,否则沿边(x,y)到达未曾访问过的y,对y访问并将其标记为已访问过:然后从y开始搜索,直到搜索完从y出发的所有路径,即访问完所有从y出发可达的顶点之后,才回溯到顶点x,并且再选择一条从x出发的未检测过的边.上述过程直至从x出发的所有边都已检测过为止. 例如下图中: 1.从0开始,首先找到0的关

基于邻接矩阵存储的图的深度优先遍历和广度优先遍历

图的存储结构相比较线性表与树来说就复杂很多,对于线性表来说,是一对一的关系,所以用数组或者链表均可简单存放.树结构是一对多的关系,所以我们要将数组和链表的特性结合在一起才能更好的存放. 那么我们的图,是多对多的情况,另外图上的任何一个顶点都可以被看作是第一个顶点,任一顶点的邻接点之间也不存在次序关系. 仔细观察以下几张图,然后深刻领悟一下: 因为任意两个顶点之间都可能存在联系,因此无法以数据元素在内存中的物理位置来表示元素之间的关系(内存物理位置是线性的,图的元素关系是平面的). 如果用多重链表

多级树的深度优先遍历与广度优先遍历(Java实现)

目录 多级树的深度优先遍历与广度优先遍历(Java实现) 节点模型 深度优先遍历 广度优先遍历 多级树的深度优先遍历与广度优先遍历(Java实现) 深度优先遍历与广度优先遍历其实是属于图算法的一种,多级树可以看做是一种特殊的图,所以多级数的深/广遍历直接套用图结构的遍历方法即可. 工程中后端通常会用多级树来存储页面表单的各级联动类目,本文提供了深度遍历与广度遍历的示例,在使用时只要根据你的业务需求稍加改动即可. 我们知道,遍历有递归,非递归两种方式.在工程项目上,一般是禁用递归方式的,因为递归非

二叉树的深度优先遍历和广度优先遍历

1. 二叉树的深度优先遍历,使用栈Stack, DFS(Depth First Search) function DFS(root){ var stack = []; stack.push(root); var node = null; while(stack.length){ node = stack.pop(); //visit node.data; if(node.right){ stack.push(node.right); } if(node.left){ stack.push(nod

C++ 二叉树深度优先遍历和广度优先遍历

二叉树的创建代码==>C++ 创建和遍历二叉树 深度优先遍历:是沿着树的深度遍历树的节点,尽可能深的搜索树的分支. //深度优先遍历二叉树void depthFirstSearch(Tree root){ stack<Node *> nodeStack; //使用C++的STL标准模板库 nodeStack.push(root); Node *node; while(!nodeStack.empty()){ node = nodeStack.top(); printf(format, n

转:二叉树的深度优先遍历和广度优先遍历

转自:http://www.blogjava.net/fancydeepin/archive/2013/02/03/395073.html 深度优先搜索算法(Depth First Search),是搜索算法的一种.是沿着树的深度遍历树的节点,尽可能深的搜索树的分支. 当节点v的所有边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点.这一过程一直进行到已发现从源节点可达的所有节点为止. 如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为

树的深度优先遍历和广度优先遍历

1 import java.util.ArrayDeque; 2 3 public class BinaryTree { 4 static class TreeNode{ 5 int value; 6 TreeNode left; 7 TreeNode right; 8 9 public TreeNode(int value){ 10 this.value=value; 11 } 12 } 13 14 TreeNode root; 15 16 public BinaryTree(int[] ar

图的遍历---深度优先遍历与广度优先遍历

对下图进行遍历,分别采用深度优先和广度优先 1.深度优先遍历的主要思想:首先从一个未被访问的顶点作为起始顶点,沿当前顶点的边走到未访问过的顶点: 当没有未访问过的顶点时,则回到上一个顶点,继续试探访问别的顶点,直到所有顶点都被访问. 显然,深度优先遍历是沿着图的某一条分支遍历直到末端,然后回溯,再沿着另一条进行同样的遍历,直到所有顶点被访问. /*深度优先搜索算法遍历图的各个顶点*/ #include<stdio.h> int n, sum, book[101]; int e[101][101