c/c++叉树的创建与遍历(非递归遍历左右中,不破坏树结构)
二叉树的创建与遍历(非递归遍历左右中,不破坏树结构)
创建
二叉树的递归3种遍历方式:
1,先中心,再左树,再右树
2,先左树,再中心,再右树
3,先左树,再右树,再中心
二叉树的非递归4种遍历方式:
1,先中心,再左树,再右树
2,先左树,再中心,再右树
3,先左树,再右树,再中心
4,层级遍历
二叉树的查找,求高度,求个数,求父节点,复制二叉树,释放二叉树
编译方法,用gcc编译不过去,用g++编译,命令如下:
g++ -g nodestack.c nodequeue.c bintree.c bintreemain.c
bintree.h
#ifndef __BINTREE__
#define __BINTREE__
#include <stdio.h>
#include <malloc.h>
#include <assert.h>
#define ElemType char
typedef struct BinTreeNode{
ElemType data;
struct BinTreeNode* leftChild;
struct BinTreeNode* rightChild;
}BinTreeNode;
typedef struct BinTree{
BinTreeNode* root;
ElemType ref;
}BinTree;
void init(BinTree* tr, ElemType val);
void createBinTree(BinTree* bt);
void createBinTree_str(BinTree* bt, char** str);
//先中心,再左树,再右树
void show_clr(BinTree* tr);
//先左树,再中心,再右树
void show_lcr(BinTree* tr);
//先左树,再右树,再中心
void show_lrc(BinTree* tr);
//层级遍历
void show_level(BinTree* tr);
//二叉树的查找方法1
int get_size1(BinTree* tr);
//二叉树的查找方法2
int get_size2(BinTree* tr);
//求二叉树的高度
int get_height(BinTree* tr);
//查找二叉树
BinTreeNode* search(BinTree* tr, ElemType key);
//求某个节点的父节点
BinTreeNode* get_parent(BinTree* tr, BinTreeNode* p);
//树是否为空
bool isBintreeEmpty(BinTree* tr);
//复制一课二叉树
void copy(BinTree* tr1, BinTree* tr2);
//释放二叉树
void bintree_clear(BinTree* tr);
//先中心,再左树,再右树
void display_clr(BinTree* tr);
//先左树,再中心,再右树
void display_lcr(BinTree* tr);
//先左树,再右树,再中心
void display_lrc(BinTree* tr);
//先左树,再右树,再中心
void display_lrc1(BinTree* tr);
#endif
bintree.c
#include "bintree.h"
#include "nodequeue.h"
#include "nodestack.h"
void init(BinTree* tr, ElemType val){
tr->root = NULL;
tr->ref = val;
}
void createRoot(BinTree* bt, BinTreeNode** t){
ElemType item;
scanf("%c", &item);
if(item == bt->ref){
*t = NULL;
}
else{
*t = (BinTreeNode*)malloc(sizeof(BinTreeNode));
assert(*t != NULL);
(*t)->data = item;
createRoot(bt, &((*t)->leftChild));
createRoot(bt, &((*t)->rightChild));
}
}
void createBinTree(BinTree* bt){
createRoot(bt, &(bt->root));
}
void createNode_str(BinTree* bt, BinTreeNode** t, char** str){
if(**str == '\0'){
return;
}
if(**str == bt->ref){
*t = NULL;
*str = *str + 1;
}
else{
*t = (BinTreeNode*)malloc(sizeof(BinTreeNode));
(*t)->data = **str;
*str = *str + 1;
createNode_str(bt, &((*t)->leftChild), str);
createNode_str(bt, &((*t)->rightChild), str);
}
}
void createBinTree_str(BinTree* bt, char** str){
createNode_str(bt, &(bt->root), str);
}
//先中心,再左树,再右树
void show_node_clr(BinTreeNode* n){
if(NULL == n)return;
else{
printf("%c ", n->data);
show_node_clr(n->leftChild);
show_node_clr(n->rightChild);
}
}
//先中心,再左树,再右树
void show_clr(BinTree* tr){
show_node_clr(tr->root);
}
//先左树,再中心,再右树
void show_node_lcr(BinTreeNode* n){
if(NULL == n)return;
else{
show_node_lcr(n->leftChild);
printf("%c ", n->data);
show_node_lcr(n->rightChild);
}
}
//先左树,再中心,再右树
void show_lcr(BinTree* tr){
show_node_lcr(tr->root);
}
//先左树,再右树,再中心
void show_node_lrc(BinTreeNode* n){
if(NULL == n)return;
else{
show_node_lrc(n->leftChild);
show_node_lrc(n->rightChild);
printf("%c ", n->data);
}
}
//先左树,再右树,再中心
void show_lrc(BinTree* tr){
show_node_lrc(tr->root);
}
//非递归层级遍历
//利用队列,先进先出
void show_node_level(BinTreeNode* n){
if(NULL == n) return;
NodeQueue queue;
init_queue(&queue);
enQueue(&queue, n);
BinTreeNode* tmp;
while(!isQueueEmpty(&queue)){
if(getHead(&queue) == NULL)break;
tmp = getHead(&queue)->data;
deQueue(&queue);
printf("%c ", tmp->data);
if(tmp->leftChild != NULL)
enQueue(&queue, tmp->leftChild);
if(tmp->rightChild != NULL)
enQueue(&queue, tmp->rightChild);
}
printf("\n");
}
//层级遍历
void show_level(BinTree* tr){
show_node_level(tr->root);
}
//--------------------分界线--------------------
//取得树中节点个数
void get_node_size1(BinTreeNode* n, int* p){
if (NULL == n)return;
else{
*p = *p + 1;
get_node_size1(n->leftChild, p);
get_node_size1(n->rightChild, p);
}
}
//取得树中节点个数
int get_size1(BinTree* tr){
int size = 0;
get_node_size1(tr->root, &size);
return size;
}
int get_node_size2(BinTreeNode* p){
if(NULL == p) return 0;
else{
return get_node_size2(p->leftChild) + get_node_size2(p->rightChild) + 1;
}
}
int get_size2(BinTree* tr){
return get_node_size2(tr->root);
}
//分别求左右树的高度,哪个高,哪就是树的高度
void get_node_height(BinTreeNode* n, int* p){
if(NULL == n) return;
*p = *p + 1;
int t1 = 0, t2 = 0;
get_node_height(n->leftChild, &t1);
get_node_height(n->rightChild,&t2);
if(t1 > t2)
*p = *p + t1;
else
*p = *p + t2;
}
int get_height(BinTree* tr){
int size = 0;
if(tr->root != NULL) size++;
int t1 = 0, t2 = 0;
get_node_height(tr->root->leftChild, &t1);
get_node_height(tr->root->rightChild, &t2);
return t1 > t2 ? t1 + size : t2 + size;
}
//递归查找节点,如果在左节点找到了,就不需要查找右节点了
BinTreeNode* search_node(BinTreeNode* n, ElemType key){
if (NULL == n || n->data == key){
return n;
}else{
BinTreeNode* tmp;
tmp = search_node(n->leftChild, key);
if(NULL == tmp){
tmp = search_node(n->rightChild, key);
}
return tmp;
}
}
BinTreeNode* search(BinTree* tr, ElemType key){
BinTreeNode* n = NULL;
n = search_node(tr->root, key);
return n;
}
//递归查找父节点,如果父节点的左节点已经为目标节点,就不需要再判断这个父节点的右节点了。
BinTreeNode* get_node_parent(BinTreeNode* n, BinTreeNode* target){
if(NULL == n || NULL == target) return NULL;
if(n->leftChild == target || n->rightChild == target){
return n;
}
else{
BinTreeNode* tmp = NULL;
tmp = get_node_parent(n->leftChild, target);
if(NULL == tmp){
tmp = get_node_parent(n->rightChild, target);
}
return tmp;
}
}
BinTreeNode* get_parent(BinTree* tr, BinTreeNode* target){
get_node_parent(tr->root, target);
}
bool isBintreeEmpty(BinTree* tr){
return NULL == tr->root;
}
void copy_node(BinTreeNode** n1, BinTreeNode* n2){
if(NULL == n2){
*n1 = NULL;
return;
}else{
BinTreeNode* p = (BinTreeNode*)malloc(sizeof(BinTreeNode*));
p->data = n2->data;
*n1 = p;
copy_node(&((*n1)->leftChild), n2->leftChild);
copy_node(&((*n1)->rightChild), n2->rightChild);
}
}
void copy(BinTree* tr1, BinTree* tr2){
copy_node(&(tr1->root), tr2->root);
}
void bintree_node_clear(BinTreeNode** n){
if(NULL == *n)return;
bintree_node_clear(&((*n)->leftChild));
bintree_node_clear(&((*n)->rightChild));
free(*n);
*n = NULL;
}
void bintree_clear(BinTree* tr){
bintree_node_clear(&(tr->root));
// init(tr, '#');
}
//非递归 先中心,再左树,再右树
//利用栈,先进后出
void display_node_clr(BinTreeNode* n){
if(NULL == n){
printf("是空树\n");
return;
}
nodestack stack;
init(&stack);
push(&stack, n);
Node* tmp = NULL;
while(0 != stack.size){
tmp = pop(&stack);
if(NULL == tmp) continue;
printf("%c ", tmp->data->data);
if(tmp->data->rightChild != NULL)
push(&stack, tmp->data->rightChild);
if(tmp->data->leftChild != NULL)
push(&stack, tmp->data->leftChild);
}
}
//非递归 先中心,再左树,再右树
void display_clr(BinTree* tr){
display_node_clr(tr->root);
}
//非递归 先左树,再中心,再右树
//利用栈,先进后出
void display_node_lcr(BinTreeNode* n){
if(NULL == n){
printf("是空树\n");
return;
}
nodestack stack;
init(&stack);
push(&stack, n);
Node* tmp = NULL;
while(0 != stack.size){
tmp = pop(&stack);
if(NULL != tmp->data->leftChild){
if(NULL != tmp->data->rightChild){
push(&stack, tmp->data->rightChild);
}
//中心节点
push(&stack, tmp->data);
push(&stack, tmp->data->leftChild);
}
else{
//再把中心节点pop出来
if(NULL == tmp->data->rightChild){
printf("%c ", tmp->data->data);
//pop出来的tmp为中心节点
tmp = pop(&stack);
if(NULL == tmp)continue;
printf("%c ", tmp->data->data);
}
else{
printf("%c ", tmp->data->data);
push(&stack, tmp->data->rightChild);
}
}
}
}
//非递归 先左树,再中心,再右树
void display_lcr(BinTree* tr){
display_node_lcr(tr->root);
}
//非递归 先左树,再右树,再中心
//利用栈,先进后出
//关键点,把有子树的父节点的tag设置成R。当pop出的节点有子节点,并且此节点的tag为R的话,就说明此节点的子节点已经入栈了,所以直接打印出来。
void display_node_lrc(BinTreeNode* n){
if(NULL == n){
printf("是空树\n");
return;
}
nodestack stack;
init(&stack);
push(&stack, n);
Node* tmp = NULL;
while(0 != stack.size){
tmp = pop(&stack);
if(tmp->tag == R){
printf("%c ", tmp->data->data);
continue;
}
if(NULL != tmp->data->leftChild){
//中心节点
push(&stack, tmp->data);
//把中心节点的属性设置成R
stack.top->tag = R;
if(NULL != tmp->data->rightChild){
push(&stack, tmp->data->rightChild);
}
push(&stack, tmp->data->leftChild);
}
else{
if(NULL == tmp->data->rightChild){
printf("%c ", tmp->data->data);
}
else{
//中心节点
push(&stack, tmp->data);
//把中心节点的属性设置成R
stack.top->tag = R;
push(&stack, tmp->data->rightChild);
}
}
}
}
//非递归 先左树,再右树,再中心
void display_lrc(BinTree* tr){
display_node_lrc(tr->root);
}
bintreemain.c
#include "bintree.h"
int main(){
BinTree tr;
init(&tr, '#');
//ABC##DE##F##G##H##
//createBinTree(&tr);
char* a = "ABC##DE##F##G#H##";
//char* a = "AB##C##";
BinTree tr1;
init(&tr1, '#');
createBinTree_str(&tr1, &a);
show_clr(&tr1);
printf("\n");
show_lcr(&tr1);
printf("\n");
show_lrc(&tr1);
printf("\n");
show_level(&tr1);
//非递归遍历,中 左 右
display_clr(&tr1);
printf("\n");
//非递归遍历,左 中 右
display_lcr(&tr1);
printf("\n");
//非递归遍历,左 右 中
display_lrc(&tr1);
printf("\n");
return 0;
}
nodequeue.h
#ifndef __NODEQUEUE__
#define __NODEQUEUE__
#include <stdio.h>
#include <malloc.h>
#include <assert.h>
#include <memory.h>
#include <stdbool.h>
struct BinTreeNode;
#define ElemType1 BinTreeNode*
typedef struct Node{
ElemType1 data;
struct Node* next;
}Node;
typedef struct NodeQueue{
Node* front;
Node* tail;
size_t size;
}NodeQueue;
void init_queue(NodeQueue*);
void enQueue(NodeQueue*, ElemType1);
void deQueue(NodeQueue*);
void show_list(NodeQueue*);
int length(NodeQueue*);
void clear(NodeQueue*);
void destroy(NodeQueue*);
Node* getHead(NodeQueue*);
bool isQueueEmpty(NodeQueue*);
#endif
nodequeue.c
#include "nodequeue.h"
void init_queue(NodeQueue* queue){
queue->front = queue->tail = (Node*)malloc(sizeof(Node));
queue->tail->next = NULL;
queue->size = 0;
}
//入队(尾插)
void enQueue(NodeQueue* queue, ElemType1 val){
Node* p = (Node*)malloc(sizeof(Node));
p->data = val;
if(queue->front->next == NULL){
queue->front->next = p;
}
else{
queue->tail->next = p;
}
queue->tail = p;
p->next = NULL;
queue->size++;
}
//出队(头删)
void deQueue(NodeQueue* queue){
if(queue->size == 0)return;
Node* tmp = queue->front->next;
queue->front->next = queue->front->next->next;
free(tmp);
queue->size--;
}
nt length(NodeQueue* queue){
return queue->size;
}
void show_list(NodeQueue* queue){
Node* p = queue->front;
while(p->next != NULL){
printf("%d\n", p->next->data);
p = p->next;
}
}
void clear(NodeQueue* queue){
if(queue->size == 0)return;
Node* p = queue->front;
Node* tmp;
while(p->next != NULL){
tmp = p->next;
p = p->next;
free(tmp);
}
queue->tail = queue->front;
queue->tail->next = NULL;
queue->size = 0;
}
void destroy(NodeQueue* queue){
clear(queue);
free(queue->front);
}
Node* getHead(NodeQueue* queue){
return queue->front->next;
}
bool isQueueEmpty(NodeQueue* queue){
return queue->front == queue->tail;
}
nodestack.h
#ifndef __NODESTACK__
#define __NODESTACK__
#include <stdio.h>
#include <malloc.h>
#include <assert.h>
#include <memory.h>
#include <stdbool.h>
struct BinTreeNode;
typedef BinTreeNode* ElemType2;
typedef enum{L, R}Tag;
typedef struct Node{
ElemType2 data;
Tag tag;
struct Node *next;
}Node;
typedef struct nodestack{
int size;
Node *base;
Node *top;
}nodestack;
void init(nodestack*);
void push(nodestack*, ElemType2);
void show_list(nodestack*);
Node* pop(nodestack*);
int length(nodestack*);
void clear(nodestack*);
void destroy(nodestack*);
#endif
nodestack.c
#include "nodestack.h"
Node* createNode(ElemType2 val){
Node* n = (Node*)malloc(sizeof(Node));
n->data = val;
n->tag = L;
n->next = NULL;
return n;
}
void init(nodestack* stack){
stack->size = 0;
stack->top = NULL;
stack->base = NULL;
}
void push(nodestack* stack, ElemType2 x){
Node* n = createNode(x);
//当栈为空的时候
if(stack->base == NULL){
stack->top = stack->base = n;
n->next = NULL;
stack->size++;
return;
}
n->next = stack->top;
stack->top = n;
stack->size++;
}
void show_list(nodestack* stack){
Node* top = stack->top;
while(top != NULL){
printf("%d\n", top->data);
top = top->next;
}
}
Node* pop(nodestack* stack){
if(stack->size == 0)return NULL;
Node* n = stack->top;
stack->top = stack->top->next;
stack->size--;
return n;
}
int length(nodestack* stack){
return stack->size;
}
void clear(nodestack* stack){
Node* top = stack->top;
Node* tmp;
while(top != NULL){
tmp = top;
top = top->next;
free(tmp);
}
stack->top = stack->base = NULL;
stack->size = 0;
}
void destroy(nodestack* stack){
clear(stack);
}
c/c++叉树的创建与遍历(非递归遍历左右中,不破坏树结构)的更多相关文章
- c/c++二叉树的创建与遍历(非递归遍历左右中,破坏树结构)
二叉树的创建与遍历(非递归遍历左右中,破坏树结构) 创建 二叉树的递归3种遍历方式: 1,先中心,再左树,再右树 2,先左树,再中心,再右树 3,先左树,再右树,再中心 二叉树的非递归4种遍历方式: ...
- Java实现二叉树的创建、递归/非递归遍历
近期复习数据结构中的二叉树的相关问题,在这里整理一下 这里包含: 1.二叉树的先序创建 2.二叉树的递归先序遍历 3.二叉树的非递归先序遍历 4.二叉树的递归中序遍历 5.二叉树的非递归中序遍历 6. ...
- 145.Binary Tree Postorder Traversal---二叉树后序非递归遍历
题目链接 题目大意:后序遍历二叉树. 法一:普通递归,只是这里需要传入一个list来存储遍历结果.代码如下(耗时1ms): public List<Integer> postorderTr ...
- 数据结构二叉树的递归与非递归遍历之java,javascript,php实现可编译(1)java
前一段时间,学习数据结构的各种算法,概念不难理解,只是被C++的指针给弄的犯糊涂,于是用java,web,javascript,分别去实现数据结构的各种算法. 二叉树的遍历,本分享只是以二叉树中的先序 ...
- C++编程练习(17)----“二叉树非递归遍历的实现“
二叉树的非递归遍历 最近看书上说道要掌握二叉树遍历的6种编写方式,之前只用递归方式编写过,这次就用非递归方式编写试一试. C++编程练习(8)----“二叉树的建立以及二叉树的三种遍历方式“(前序遍历 ...
- 非递归遍历N-ary树Java实现
2019-03-25 14:10:51 非递归遍历二叉树的Java版本实现之前已经进行了总结,这次做的是非递归遍历多叉树的Java版本实现. 在非递归遍历二叉树的问题中我个人比较推荐的是使用双whil ...
- ZT 二叉树的非递归遍历
ZT 二叉树的非递归遍历 二叉树的非递归遍历 二叉树是一种非常重要的数据结构,很多其它数据结构都是基于二叉树的基础演变而来的.对于二叉树,有前序.中序以及后序三种遍历方法.因为树的定义本身就 是递归定 ...
- c语言描述的二叉树的基本操作(层序遍历,递归,非递归遍历)
#include<stdio.h> #include<stdlib.h> #define OK 1 #define ERROR 0 #define TRUE 1 #define ...
- WPF树形菜单--递归与非递归遍历生成树结构的集合
一.新建了WPF项目作为测试,使用TreeView控件进行界面展示. 第一步创建实体类TreeEntity: public class TreeEntity { private int _mid; p ...
随机推荐
- 【Flask-RESTPlus系列】Part2:响应编组
0x00 内容概览 响应编组 基本使用 重命名属性 默认值 自定义字段及多值情况 Url及其他具体字段 复杂结构 列表字段 嵌套字段 api.model()工厂 clone实现复制 api.inher ...
- https下 http的会被阻塞 This request has been blocked; the content must be served over HTTPS.
如何在HTTPS 网页中引入HTTP资源: Mixed Content? https://segmentfault.com/q/1010000005872734/a-1020000005874533 ...
- MySQL中间件之ProxySQL(13):ProxySQL集群
返回ProxySQL系列文章:http://www.cnblogs.com/f-ck-need-u/p/7586194.html ProxySQL有原生的集群功能,但是这个原生的集群功能还正在试验阶段 ...
- advanced installer重新打包教程
一.简介 本次利用Advanced Installer软件里的Repackager重封装工具进行测试制作MSI安装包,还开可以利用Advanced Installerr制作MSI安装包 原理为执行两次 ...
- 注册asp.net 4.0版本到IIS服务器中
在IIS服务器的运维的过程中,有时候部署asp.net网站发现未安装.net framework对应版本信息,此时就需要重新将.net framework对应的版本注册到IIS中,此处以重新注册.ne ...
- 【转载】ASP.NET生成图片的缩略图
图片处理是C#程序开发中时常会涉及到的一个业务,除了图像的上传.保存以及下载等功能外,根据上传的图片生成一个缩略图也是常见业务,在C#语言中,可以通过Image类提供的相关方法对图片进行操作,如指定宽 ...
- 杭电ACM2002--计算球体积
计算球体积 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submi ...
- .NET MVC JSON JavaScriptSerializer 字符串的长度超过 maxJsonLength 值问题的解决
[ArgumentException: 使用 JSON JavaScriptSerializer 序列化或还原序列化期间发生错误.字符串的长度超过在 maxJsonLength 属性上设定的值. 参数 ...
- [android] 采用服务录制电话&服务的生命周期
根据上一节代码里,加入一个录音功能,上传到服务器,就能实现一个录制器 当手机处于通话状态时,开启录音机 获取MediaRecorder对象,通过new出来 调用MediaRecorder对象的setA ...
- Hibernate入门(十)inverse
双向关联产生多余的SQL语句 /** * 添加一个订单到id为6的客户中 */ @Test public void fun1(){ Session session = HibernateUtils.g ...