给定一个二叉树,返回它的 前序 遍历。

示例:

输入: [1,null,2,3]
1
\
2
/
3 输出: [1,2,3]

进阶: 递归算法很简单,你可以通过迭代算法完成吗?

前序遍历


前序遍历首先访问根节点,然后遍历左子树,最后遍历右子树。

用c语言来实现比较麻烦,现在大概介绍下我的思路,首先题目先要实现一个前序遍历,如果用递归,会比较简单,几行代码就可以实现,但是现在要求使用迭代发来实现。整个遍历过程是,访问根节点,然后遍历其左子树,然后再看左子树是否有其左孩子和右孩子。因为在查看左孩子之后,还要再查看根节点的右孩子,所以每次需要把根节点记录下来,需要存在栈中。所以我们需要实现一个栈,有压栈和出栈操作。另外我们需要一个链表来存放已经访问过的节点,到最后,需要把这些节点统一存储到一个数组中,然后返回。

下面来看下我码的代码

/* 链表节点 用于存储输出结果 */
struct listNode {
int val;
struct listNode *next;
}; struct list {
int count;
struct listNode *head;
struct listNode *tail;
}; /* 栈节点,用于存储已经遍历过的根节点 */
struct StackNode
{
void *entry;
struct StackNode *next;
}; struct stack {
struct StackNode *top;
}; void init_stack(struct stack *s)
{
s->top = NULL;
} void stack_push(struct stack *s, void *np)
{
struct StackNode *node = malloc(sizeof(struct StackNode));
node->entry = np;
node->next = s->top;
s->top = node;
}; void *stack_pop(struct stack *s)
{
struct StackNode *np = s->top;
void *node = np->entry;
s->top = np->next;
free(np);
return node;
}; bool isEmpty(struct stack *s)
{
return (s->top == NULL) ? true : false;
} void init_list(struct list *l)
{
l->count = 0;
l->head = NULL;
l->tail = NULL;
} void add_new_node(struct list *l, struct listNode *node)
{
if (!l->head)
{
l->head = node;
l->tail = node;
l->count = 1;
return;
} l->tail->next = node;
l->tail = node;
l->count++;
}

这些是辅助函数

int* preorderTraversal(struct TreeNode* root, int* returnSize){
struct TreeNode *pNode = root;
struct listNode *newNode = NULL;
struct list *l = malloc(sizeof(struct list));
struct stack *s = malloc(sizeof(struct stack));
int *r = NULL;
int i = 0;
struct listNode *head = NULL;
init_list(l);
init_stack(s); while (pNode != NULL || !isEmpty(s))
{
if (pNode != NULL)
{
newNode = malloc(sizeof(struct listNode));
newNode->val = pNode->val;
newNode->next = NULL;
add_new_node(l, newNode);
stack_push(s, (void *)pNode);
pNode = pNode->left;
}
else
{
pNode = (struct TreeNode *)stack_pop(s);
pNode = pNode->right;
}
} r = malloc(sizeof(int) * l->count);
head = l->head;
while(head && i < l->count)
{
r[i] = head->val;
i++;
head = head->next;
}
*returnSize = l->count; return r;
}

这个是具体的前序遍历函数。

对应的中序遍历的核心代码如下:

 while (pNode != NULL || !isEmpty(s))
{
if (pNode != NULL)
{
stack_push(s, (void *)pNode);
pNode = pNode->left;
}
else
{
pNode = (struct TreeNode *)stack_pop(s);
newNode = malloc(sizeof(struct listNode));
newNode->val = pNode->val;
newNode->next = NULL;
add_new_node(l, newNode);
pNode = pNode->right;
}
}

后序遍历如下:

while (pNode != NULL || !isEmpty(s))
{
if (pNode != NULL)
{
stack_push(s, (void *)pNode);
pNode = pNode->left;
}
else
{
seek = (struct TreeNode *)stack_seek(s);
if (seek->right == NULL || last == seek->right)
{
stack_pop(s);
newNode = malloc(sizeof(struct listNode));
newNode->val = seek->val;
newNode->next = NULL;
add_new_node(l, newNode);
last = seek;
}
else
{
pNode = seek->right;
}
}
}

(leetcode)二叉树的前序遍历-c语言实现的更多相关文章

  1. (leetcode)二叉树的层次遍历-c语言实现

    这段代码,在后面跑测试用例时,出现了stack-overflow,但是原因还不清楚. 问题如下:  二叉树的层次遍历   给定一个二叉树,返回其按层次遍历的节点值. (即逐层地,从左到右访问所有节点) ...

  2. 【LeetCode题解】144_二叉树的前序遍历

    目录 [LeetCode题解]144_二叉树的前序遍历 描述 方法一:递归 Java 代码 Python 代码 方法二:非递归(使用栈) Java 代码 Python 代码 [LeetCode题解]1 ...

  3. LeetCode:二叉树的前序遍历【144】

    LeetCode:二叉树的前序遍历[144] 题目描述 给定一个二叉树,返回它的 前序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,2,3] 题目分析 如果用递 ...

  4. LeetCode 144. 二叉树的前序遍历(Binary Tree Preorder Traversal)

    144. 二叉树的前序遍历 144. Binary Tree Preorder Traversal 题目描述 给定一个二叉树,返回它的 前序 遍历. LeetCode144. Binary Tree ...

  5. LeetCode:144_Binary Tree Preorder Traversal | 二叉树的前序遍历 | Medium

    题目:Binary Tree Preorder Traversal 二叉树的前序遍历,同样使用栈来解,代码如下: struct TreeNode { int val; TreeNode* left; ...

  6. Java实现 LeetCode 144 二叉树的前序遍历

    144. 二叉树的前序遍历 给定一个二叉树,返回它的 前序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,2,3] /** * Definition for a ...

  7. Leetcode(144)-二叉树的前序遍历

    给定一个二叉树,返回它的 前序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,2,3] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 二叉树的前序遍历有递归 ...

  8. 【LeetCode】144. 二叉树的前序遍历

    144. 二叉树的前序遍历 知识点:二叉树:递归:Morris遍历 题目描述 给你二叉树的根节点 root ,返回它节点值的 前序 遍历. 示例 输入:root = [1,null,2,3] 输出:[ ...

  9. 剑指offer面试题:输入某二叉树的前序遍历和中序遍历,输出后序遍历

    二叉树的先序,中序,后序如何遍历,不在此多说了.直接看题目描述吧(题目摘自九度oj剑指offer面试题6): 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结 ...

随机推荐

  1. Pandas之isna,fillna

    isna() 释义 筛选为NaN的布尔值,可接受单个标量或者数组 举例 筛选stu_name为NaN的所有行: df = pd.DataFrame({'stu_name': ['Tom', 'Tony ...

  2. PHP面试常考内容之面向对象(2)

    PHP面试专栏正式起更,每周一.三.五更新,提供最好最优质的PHP面试内容.继上一篇"PHP面试常考内容之面向对象(1)"发表后,今天更新(2),需要(1)的可以直接点击文字进行跳 ...

  3. Solution -「CF 510E」Fox And Dinner

    \(\mathcal{Description}\)   Link.   给定正整数集合 \(\{a_n\}\),求一种把这些数放置在任意多个圆环上的方案,使得每个环的大小大于 \(2\) 且环上相邻两 ...

  4. 《操作系统导论》第5章 | 进程API

    本章主要讨论UNIX系统中的进程创建.UNIX系统采用了一种非常有趣的创建新进程的方式,即通过一对系统调用:fork()和exec().进程还可以通过第三个系统调用wait(),来等待其创建的子进程执 ...

  5. 【一天一个小知识10/20】Unity安卓获取麦克风并录音保存。

    2021-10-20 10:42:16 #region 模块信息 // **************************************************************** ...

  6. Python中from … import …语句

    from - import -语句可以让你从模块中导入一个指定的部分到当前模块

  7. python-利用json模块处理json数据几个函数总结

    1.前言 json是一种轻量级的数据交换格式,它是JavaScript的子集,易于人阅读和编写. 前端和后端进行数据交互,其实就是JS和Python进行数据交互. 接口间或者前后端间的语言不一致,不同 ...

  8. CSRF POST型

    实验目的 掌握POST型CSRF基础知识 实验原理 管理员点击恶意链接,密码被修改 实验内容 POST型CSRF漏洞 实验环境描述 带有CSRF漏洞的注册登录系统 实验步骤 登录密码 用户名为 roo ...

  9. Wireshark教程之安装

    实验目的 1.工具介绍 2.主要应用 实验原理 安装wireshark 实验内容 1.网络管理员用来解决网络问题 2.网络安全工程师用来检测安全隐患 3.开发人员用来测试执行情况 4.学习网络协议 实 ...

  10. Wireshark教程之统计功能

    实验目的 1.工具介绍 2.主要应用 实验原理 Wireshark的原名是Ethereal,新名字是2006年起用的.当时Ethereal的主要开发者Gerald决定离开他原来供职的公司NIS,并继续 ...