二叉树遍历

先序

递归

int *res;

void preorder(struct TreeNode *root, int *returnSize) {
if (root == NULL) return;
// 根左右
res[(*returnSize)++] = root->val;
preorder(root->left, returnSize);
preorder(root->right, returnSize);
} int *preorderTraversal(struct TreeNode *root, int *returnSize) {
res = (int *) malloc(sizeof(int) * 100);
*returnSize = 0;
preorder(root, returnSize);
return res;
}

迭代

int *preorderTraversal(struct TreeNode *root, int *returnSize) {
int *res = (int *) malloc(sizeof(int) * 100);
*returnSize = 0;
struct TreeNode *stack[100];
int top = 0; while (top != 0 || root != NULL) {
// 左子树入栈
while (root != NULL) {
// 访问
res[(*returnSize)++] = root->val;
stack[top++] = root;
root = root->left;
} root = stack[--top];
root = root->right;
} return res;
}

迭代(右子树先入栈)

int *preorderTraversal(struct TreeNode *root, int *returnSize) {
int *res = (int *) malloc(sizeof(int) * 100);
*returnSize = 0;
if (root == NULL) return res;
struct TreeNode *stack[100];
int top = 0;
stack[top++] = root; while (top != 0) {
root = stack[--top];
res[(*returnSize)++] = root->val;
// 右子树先入栈
if (root->right != NULL) stack[top++] = root->right;
if (root->left != NULL) stack[top++] = root->left;
}
return res;
}

右左根访问,再反转序列

int *res;

void dfs(struct TreeNode *root, int *returnSize) {
if (root == NULL) return;
// 按右左根的顺序访问,再把序列反过来
dfs(root->right, returnSize);
dfs(root->left, returnSize);
res[(*returnSize)++] = root->val;
} int *preorderTraversal(struct TreeNode *root, int *returnSize) {
res = (int *) malloc(sizeof(int) * 100);
*returnSize = 0;
if (root == NULL) return res;
dfs(root, returnSize); // 序列反过来
int left = 0, right = *returnSize - 1;
while (left < right) {
int temp = res[left];
res[left] = res[right];
res[right] = temp;
left++;
right--;
} return res;
}

Morris

int *res;

// Morris
void preorderMorris(struct TreeNode *root, int *returnSize) {
if (root == NULL) return; struct TreeNode *cur = root; while (cur != NULL) {
if (cur->left != NULL) {
// 左子树不空,遍历左子树,找到左子树的最右侧节点
struct TreeNode *rightMost = cur->left;
while (rightMost->right != NULL && rightMost->right != cur) {
rightMost = rightMost->right;
}
// 最右侧节点的右指针指向NULL或者cur
if (rightMost->right == NULL) {
// 有左右孩子的节点第一次被访问
res[(*returnSize)++] = cur->val;
// 把最右侧节点的right指向cur
rightMost->right = cur;
// 访问左子树
cur = cur->left;
} else {
// 有左右孩子的节点第二次被访问
// 恢复
rightMost->right = NULL;
// 遍历右子树
cur = cur->right;
}
} else {
// 只有右孩子的节点只会被访问一次
res[(*returnSize)++] = cur->val;
// 遍历右子树
cur = cur->right;
}
}
} int *preorderTraversal(struct TreeNode *root, int *returnSize) {
res = (int *) malloc(sizeof(int) * 100);
*returnSize = 0;
if (root == NULL) return res;
preorderMorris(root, returnSize);
return res;
}

中序

递归

int *res;

void inorder(struct TreeNode *root, int *returnSize) {
if (root == NULL) return;
// 左根右
inorder(root->left, returnSize);
res[(*returnSize)++] = root->val;
inorder(root->right, returnSize);
} int *inorderTraversal(struct TreeNode *root, int *returnSize) {
res = (int *) malloc(sizeof(int) * 100);
*returnSize = 0;
inorder(root, returnSize);
return res;
}

迭代

int *inorderTraversal(struct TreeNode *root, int *returnSize) {
int *res = (int *) malloc(sizeof(int) * 100);
*returnSize = 0;
struct TreeNode *stack[100];
int top = 0; while (top != 0 || root != NULL) {
// 左子树入栈
while (root != NULL) {
stack[top++] = root;
root = root->left;
} root = stack[--top];
// 访问
res[(*returnSize)++] = root->val;
root = root->right;
} return res;
}

Morris

int *res;

void inorderMorris(struct TreeNode *root, int *returnSize) {
if (root == NULL) return;
struct TreeNode *cur = root;
while (cur != NULL) {
if (cur->left != NULL) {
struct TreeNode *rightMost = cur->left;
while (rightMost->right != NULL && rightMost->right != cur) {
rightMost = rightMost->right;
}
if (rightMost->right == NULL) {
rightMost->right = cur;
cur = cur->left;
} else {
// 有左右孩子的节点第二次被经过,左子树都遍历完了,访问节点
res[(*returnSize)++] = cur->val;
rightMost->right = NULL;
cur = cur->right;
}
} else {
// 只有右孩子的节点只会被经过一次,直接访问
res[(*returnSize)++] = cur->val;
cur = cur->right;
}
}
} int *inorderTraversal(struct TreeNode *root, int *returnSize) {
res = (int *) malloc(sizeof(int) * 100);
*returnSize = 0;
if (root == NULL) return res;
inorderMorris(root, returnSize);
return res;
}

后序

递归

int *res;

void postOrder(struct TreeNode *root, int *returnSize) {
if (root == NULL) return;
// 左右根
postOrder(root->left, returnSize);
postOrder(root->right, returnSize);
res[(*returnSize)++] = root->val;
} int *postorderTraversal(struct TreeNode *root, int *returnSize) {
res = (int *) malloc(sizeof(int) * 100);
*returnSize = 0;
postOrder(root, returnSize);
return res;
}

迭代

int *postorderTraversal(struct TreeNode *root, int *returnSize) {
int *res = (int *) malloc(sizeof(int) * 100);
*returnSize = 0;
struct TreeNode *stack[100];
int top = 0;
// 记录上个访问的节点
struct TreeNode *pre = NULL; while (top != 0 || root != NULL) {
// 左子树入栈
while (root != NULL) {
stack[top++] = root;
root = root->left;
} root = stack[--top];
if (root->right == NULL || root->right == pre) {
// 右子树为空或者已经访问完了,可以访问这个节点了
res[(*returnSize)++] = root->val;
pre = root;
root = NULL;
} else {
// 遍历右子树
// 先把当前节点再次压栈
stack[top++] = root;
root = root->right;
}
} return res;
}

Morris

int *res;

// 把右子树反转
struct TreeNode *reverseRightTree(struct TreeNode *root) {
struct TreeNode *pre = NULL;
struct TreeNode *cur = root;
while (cur != NULL) {
struct TreeNode *nextRight = cur->right;
cur->right = pre;
pre = cur;
cur = nextRight;
}
return pre;
} // 自底向上访问右节点(访问反转后的右节点)
void visitReversedRightTree(struct TreeNode *root, int *returnSize) {
// 反转右子树
struct TreeNode *reversed = reverseRightTree(root);
struct TreeNode *cur = reversed;
while (cur != NULL) {
res[(*returnSize)++] = cur->val;
cur = cur->right;
}
// 反转回去
reverseRightTree(reversed);
} void postorderMorris(struct TreeNode *root, int *returnSize) {
struct TreeNode *cur = root;
while (cur != NULL) {
if (cur->left != NULL) {
struct TreeNode *rightMost = cur->left;
while (rightMost->right != NULL && rightMost->right != cur) {
rightMost = rightMost->right;
}
if (rightMost->right == NULL) {
rightMost->right = cur;
cur = cur->left;
} else {
rightMost->right = NULL;
// 一个节点被第二次经过的时候,自底向上访问左子树的所有的右节点
visitReversedRightTree(cur->left, returnSize);
cur = cur->right;
}
} else {
cur = cur->right;
}
}
// 再遍历一次
visitReversedRightTree(root, returnSize);
} int *postorderTraversal(struct TreeNode *root, int *returnSize) {
res = (int *) malloc(sizeof(int) * 100);
*returnSize = 0;
if (root == NULL) return res;
postorderMorris(root, returnSize);
return res;
}

层序

int **levelOrder(struct TreeNode *root, int *returnSize, int **returnColumnSizes) {
// 一层最多元素个数
const int size = 1002;
// 最多层数
const int leverMax = 2000; // 返回的二维数组,第一维表示所在层,第二维表示该层的所有元素
int **res = (int **) malloc(sizeof(int *) * leverMax);
// 一维的维度(多少层)
*returnSize = 0;
// 每个二维的维度(每层多少元素)
*returnColumnSizes = (int *) malloc(sizeof(int) * leverMax);
if (root == NULL) return res; // 循环队列
struct TreeNode *queue[size];
int lever = 0;
// 保存每层元素个数,下标就是所在层,从0开始
int *columnSize = (int *) calloc(leverMax, sizeof(int));
int front = 0, rear = 0;
queue[rear++] = root; while (front != rear) {
// 当前层元素数
int count = (rear - front + size) % size;
res[lever] = (int *) malloc(sizeof(int) * count);
int temp = 0;
while (count-- > 0) {
root = queue[(front++) % size];
// 记录当前层的元素
res[lever][temp++] = root->val;
// 当前层元素总数加一
columnSize[lever]++;
if (root->left != NULL) queue[(rear++) % size] = root->left;
if (root->right != NULL) queue[(rear++) % size] = root->right;
}
// 加一层
lever++;
} *returnSize = lever;
for (int i = 0; i < lever; ++i)
(*returnColumnSizes)[i] = columnSize[i];
return res;
}

二叉树遍历(C语言版)的更多相关文章

  1. 二叉树的建立与递归遍历C语言版

    </pre><pre name="code" class="cpp">#include <stdio.h> #include ...

  2. 二叉树的基本操作(C语言版)

    今天走进数据结构之二叉树 二叉树的基本操作(C 语言版) 1 二叉树的定义 二叉树的图长这样: 二叉树是每个结点最多有两个子树的树结构,常被用于实现二叉查找树和二叉堆.二叉树是链式存储结构,用的是二叉 ...

  3. 二叉树遍历(非递归版)——python

    二叉树的遍历分为广度优先遍历和深度优先遍历 广度优先遍历(breadth first traversal):又称层次遍历,从树的根节点(root)开始,从上到下从从左到右遍历整个树的节点. 深度优先遍 ...

  4. 学习笔记——二叉树相关算法的实现(Java语言版)

    二叉树遍历概念和算法 遍历(Traverse): 所谓遍历(Traversal)是指沿着某条搜索路线,依次对树中每个结点均做一次且仅做一次访问. 从二叉树的递归定义可知,一棵非空的二叉树由根结点及左. ...

  5. 数据结构(C语言版)-第5章 树和二叉树

    5.1  树和二叉树的定义 树(Tree)是n(n≥0)个结点的有限集,它或为空树(n = 0):或为非空树,对于非空树T:(1)有且仅有一个称之为根的结点:(2)除根结点以外的其余结点可分为m(m& ...

  6. 数据结构(c语言版)代码

    第1章  绪论       文档中源码及测试数据存放目录:数据结构\▲课本算法实现\▲01 绪论  概述        第一章作为绪论,主要介绍了数据结构与算法中的一些基本概念和术语.对于这些概念术语 ...

  7. c++学习书籍推荐《清华大学计算机系列教材:数据结构(C++语言版)(第3版)》下载

    百度云及其他网盘下载地址:点我 编辑推荐 <清华大学计算机系列教材:数据结构(C++语言版)(第3版)>习题解析涵盖验证型.拓展型.反思型.实践型和研究型习题,总计290余道大题.525道 ...

  8. 数据结构C语言版 有向图的十字链表存储表示和实现

    /*1wangxiaobo@163.com 数据结构C语言版 有向图的十字链表存储表示和实现 P165 编译环境:Dev-C++ 4.9.9.2 */ #include <stdio.h> ...

  9. 二叉树遍历(flist)(二叉树,已知中序层序,求先序)

    问题 C: 二叉树遍历(flist) 时间限制: 1 Sec  内存限制: 128 MB提交: 76  解决: 53[提交][状态][讨论版][命题人:quanxing][Edit] [TestDat ...

  10. 二叉树遍历(flist)(已知中序和按层遍历,求先序 )

    问题 F: 二叉树遍历(flist) 时间限制: 1 Sec  内存限制: 128 MB提交: 11  解决: 9[提交][状态][讨论版][命题人:quanxing][Edit] [TestData ...

随机推荐

  1. vue项目之主页布局

    1.背景 2.基本结构 代码: <template> <el-container class="home-container"> <!-- 头部--& ...

  2. mongo变更流使用及windows下副本集五分钟搭建

    mongodb的变更流解释: 变更流(Change Streams)允许应用程序访问实时数据变更,从而避免事先手动追踪  oplog 的复杂性和风险.应用程序可使用变更流来订阅针对单个集合.数据库或整 ...

  3. Dijkstra单源最短路模板

    struct DIJ { using i64 = long long; using PII = pair<i64, i64>; vector<i64> dis; vector& ...

  4. 看了这几个C语言例子,你一定和我一样连说5个卧槽,声音一次比一次大

    曾经我一直以为自己C语言学的还挺好的,直到看到这几个例子. 例1 首先来看一下,大师是如何求圆周率的,一口君实在词穷,first卧槽. #include <stdio.h> long a= ...

  5. tlmgr 操作

    宏包管理 sudo tlmgr install <package> # 安装宏包 sudo tlmgr install scheme-full # 安装全部宏包 sudo tlmgr re ...

  6. vue中代理解决跨域

    跨域是什么 简单的讲就是你在一个地方使用另一个地方的资源,被浏览器给挡下来了,不让不用!当然,它挡下来是有自己理由的:为了安全(╬▔皿▔)╯. 解决跨域 我是用vue开发的,就vue代理模式解决跨域说 ...

  7. 用Python实现阿拉伯数字转换成中国汉字

    要将阿拉伯数字转换成中国汉字表示的数字,我们需要一个映射表来转换每个数字,并且处理不同位数的数字(如十.百.千.万等). 1. Python实现阿拉伯数字转换成中国汉字 下面是一个完整的Python代 ...

  8. Mongodb入门5

    最近在用MongoDBKoa2做个小项目,记录一下: 首先,如何连接线上数据库: const url = `mongodb://user:pwd@ipaddr:27017/Blog`; const m ...

  9. ES6中的Set数据结构

    Set是ES6新推出的数据结构,Set结构里面的每个元素都是唯一的: 如何创建一个Set? // Set 构造函数接收一个数组进行初始化;如果什么都不传则创建一个空Set; var set = new ...

  10. CSS – Font Family

    前言 font-family 虽然只是一个 CSS 属性, 但是牵连许多东西, 所以独立一篇来讲. 网站一般上会使用 Google Fonts 作为 font-family, 下面会以一个 Googl ...