C前序遍历二叉树Morris Traversal算法
首先来递归算法,简单易懂:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h> typedef struct TreeNode{
char data;
struct TreeNode *lchild, *rchild;
}TreeNode; void PreOrderTraverse(TreeNode *t){
if( NULL == t ) return;
printf("%c",t->data);
PreOrderTraverse(t->lchild);
PreOrderTraverse(t->rchild);
}
然后是栈模拟递归:
typedef struct StackNode{
TreeNode *pdata;
struct StackNode *next;
}StackNode;
typedef struct Stack{
StackNode *top;
}Stack;
Stack *init_s(){
Stack *pnew = (Stack *)malloc(sizeof(Stack));
pnew->top = NULL;
return pnew;
}
void push(Stack *s,TreeNode *p){
StackNode *pnew = (StackNode *)malloc(sizeof(StackNode));
pnew->pdata = p;
pnew->next = s->top;
s->top = pnew;
}
bool empty_stack(Stack *s){
return NULL == s->top;
}
TreeNode *pop(Stack *s){
TreeNode *p = NULL;
StackNode *pn = NULL;
if( ! empty_stack(s) ){
pn = s->top;
p = pn->pdata;
s->top = pn->next;
free(pn);
}
return p;
}
void PreOrderTraverse(TreeNode *t){
if( NULL == t ) return;
TreeNode *p = NULL;
Stack *s = init_s();
push(s,t);
while( ! empty_stack(s) ){
p = pop(s);
if( NULL == p ){
continue;
}
printf("%c",p->data);
push(s,p->rchild);
push(s,p->lchild);
}
}
Morris Traversal算法:空间复杂度O(1):
用线索二叉树(threaded binary tree)的概念,利用叶子的左右闲指针指向遍历的前驱或者后继节点。
算法如下:
1、初始化当前节点为root
2、若当前节点不为空
a) 若当前节点没有左孩子
访问当前节点,并将当前节点移向右孩子
b) 若当前节点有左孩子
找到左子树的最右边那个节点
若它的右指针为空,访问当前节点,把它的右指针指向cur,并移动到当前节点到左孩子
若它的右指针为当前节点,则把它的右指针重新设为空(恢复树),并移动到当前节点的右孩子
3、重复第2步
void PreOrderTraverse(TreeNode *t){
if( NULL == t ) return;
TreeNode *pcur = t, *pre = NULL;
while( pcur ){
if( pcur->lchild ){
pre = pcur->lchild;
while( pcur != pre->rchild && NULL != pre->rchild ){
pre = pre->rchild;
}
if( pre->rchild == pcur ){
pre->rchild = NULL;
pcur = pcur->rchild;
}
else{
printf("%c",pcur->data);
pre->rchild = pcur;
pcur = pcur->lchild;
}
}
else{
printf("%c",pcur->data);
pcur = pcur->rchild;
}
}
}
main函数:
int main(){
TreeNode *t = (TreeNode *)malloc(sizeof(TreeNode));
TreeNode *pnew = (TreeNode *)malloc(sizeof(TreeNode));
t->data = 'A';
t->lchild = pnew;
t->lchild->data = 'B';
t->lchild->lchild = NULL;
pnew = (TreeNode *)malloc(sizeof(TreeNode));
t->lchild->rchild = pnew;
t->lchild->rchild->data = 'D';
t->lchild->rchild->lchild = NULL;
t->lchild->rchild->rchild = NULL;
pnew = (TreeNode *)malloc(sizeof(TreeNode));
t->rchild = pnew;
t->rchild->data = 'C';
t->rchild->lchild = NULL;
t->rchild->rchild = NULL;
PreOrderTraverse(t);
printf("\n");
}
C前序遍历二叉树Morris Traversal算法的更多相关文章
- LeetCode OJ:Binary Tree Preorder Traversal(前序遍历二叉树)
Given a binary tree, return the preorder traversal of its nodes' values. For example:Given binary tr ...
- Binary Tree Inorder/Preorder Traversal 返回中序和前序/遍历二叉树的元素集合
给定一个二叉树,以集合方式返回其中序/先序方式遍历的所有元素. 有两种方法,一种是经典的中序/先序方式的经典递归方式,另一种可以结合栈来实现非递归 Given a binary tree, retur ...
- 额外空间复杂度O(1) 的二叉树遍历 → Morris Traversal,你造吗?
开心一刻 一天,有个粉丝遇到感情方面的问题,找我出出主意 粉丝:我女朋友吧,就是先天有点病,听不到人说话,也说不了话,现在我家里人又给我介绍了一个,我该怎么办 我:这个问题很难去解释,我觉得一个人活着 ...
- 二叉树 Java 实现 前序遍历 中序遍历 后序遍历 层级遍历 获取叶节点 宽度 ,高度,队列实现二叉树遍历 求二叉树的最大距离
数据结构中一直对二叉树不是很了解,今天趁着这个时间整理一下 许多实际问题抽象出来的数据结构往往是二叉树的形式,即使是一般的树也能简单地转换为二叉树,而且二叉树的存储结构及其算法都较为简单,因此二叉树显 ...
- 用c语言实现前序创建二叉树(递归),分别用前序,中序,后序遍历,以及分别输出节点个数和叶子节点个数
本人c语言小白一枚,近期在学习数据结构(c语言版),特写此随笔,做一些总结和分享,如有不当之处,请各位技术大牛斧正 首先我们用一个结构体来抽象树的结点,代码如下(这里我们存放的数据为char型,大家可 ...
- java编写二叉树以及前序遍历、中序遍历和后序遍历 .
/** * 实现二叉树的创建.前序遍历.中序遍历和后序遍历 **/ package DataStructure; /** * Copyright 2014 by Ruiqin Sun * All ri ...
- c++实现二叉树层序、前序创建二叉树,递归非递归实现二叉树遍历
#include <iostream> #include <cstdio> #include <stdio.h> #include <string> # ...
- leecode刷题(28)-- 二叉树的前序遍历
leecode刷题(28)-- 二叉树的前序遍历 二叉树的前序遍历 给定一个二叉树,返回它的 前序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,2,3] 思路 ...
- Qt实现 动态化遍历二叉树(前中后层次遍历)
binarytree.h 头文件 #ifndef LINKEDBINARYTREE_H #define LINKEDBINARYTREE_H #include<c++/algorithm> ...
随机推荐
- 如何通过Restful API的方式读取SAP Commerce Cloud的Product Reference
从SAP官网上找到api的说明: https://api.sap.com/api/commerce_services/resource api endpoint: /rest/v2/electroni ...
- MySQL Binlog--基于ROW模式的binlog event大小限制
参数binlog-row-event-max-size:Specify the maximum size of a row-based binary log event, in bytes. Rows ...
- Mysql5.7降级到5.6遇到的坑
任何版本的升级或降级都存在兼容的问题,DB更为明显,废话不多说,直接进入主题,问题描述如下: Specified key was too long; max key length is 767 byt ...
- wampserver环境配置局域网访问
安装好wamp后,想用手机通过局域访问电脑上wamp下的网页,结果出现如下提示403错误: 第一步:找到 conf 这个文件: 找到下图中红色方框中的onlineoffline tag - don’t ...
- 7. Input and Output
7. Input and Output There are several ways to present the output of a program; data can be printed i ...
- pom中添加插件打包上传源码
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> ...
- /sys 和 /dev 区别
参考:What's the “/sys” directory for? Directory - /sys in linux 前言 各种Linux发行版下面似乎都有/sys目录,tree查看下面内容,会 ...
- vi / vim 字符替换详解
:s/idoxu/isTester.com/g 替换当前行所有 idoxu 为 isTester.com :n,$s/idoxu/isTester.com/ #替换第 n 行开始到最后一行中每一行的第 ...
- vue-cli3.0 脚手架搭建项目的过程详解
1.安装vue-cli 3.0 ? 1 2 3 npm install -g @vue/cli # or yarn global add @vue/cli 安装成功后查看版本:vue -V(大写的V) ...
- mysql启动错误:Starting MySQL.. ERROR! The server quit without updating PID file错误
1.原因是因为 mysql-bin.0000*的文件占满系统盘,磁盘空间不足导致无法写入. 解决方法: 如果不需要二进制日志文件,二进制文件可以实现数据库复制以及即时点恢复. 查看日志在配置文件的da ...