[置顶] 数据结构——二叉树 前序、中序、后序、递归遍历和非递归遍历
2017-10-28 18:03
459 查看
这是我做过的GitHub小项目(知天气),入手安卓的朋友可以拿我的代码做参考,大家可怜可怜给个赞吧哈哈!https://github.com/Xxianglei/HeartWeather
一、基本概念
每个结点最多有两棵子树,左子树和右子树,次序不可以颠倒。
性质:
1、非空二叉树的第n层上至多有2^(n-1)个元素。
2、深度为h的二叉树至多有2^h-1个结点。
满二叉树:所有终端都在同一层次,且非终端结点的度数为2。
在满二叉树中若其深度为h,则其所包含的结点数必为2^h-1。
完全二叉树:除了最大的层次即成为一颗满二叉树且层次最大那层所有的结点均向左靠齐,即集中在左面的位置上,不能有空位置。
对于完全二叉树,设一个结点为i则其父节点为i/2,2i为左子节点,2i+1为右子节点。
二、存储结构
顺序存储:
将数据结构存在一块固定的数组中。
[cpp]
view plain
copy
print?
#define LENGTH 100
typedef char datatype;
typedef struct node{
datatype data;
115de
int lchild,rchild;
int parent;
}Node;
Node tree[LENGTH];
int length;
int root;
虽然在遍历速度上有一定的优势,但因所占空间比较大,是非主流二叉树。二叉树通常以链式存储。
链式存储:
[cpp]
view plain
copy
print?
typedef int Status;
typedef int TElemType;
typedef struct BiTNode{
TElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode , *BiTree;
三.二叉树的创建(先序创建)
[cpp]
view plain
copy
print?
void createBiTree(BiTree &T)
{
char c;
cin >> c;
if('#' == c)
T = NULL;
else
{
if(!(T=(BiTNode *)malloc(sizeof(BiTNode))))exit(-2);
T->data = c;
createBiTree(T->lchild);
createBiTree(T->rchild);
}
}
四,输出二叉树
[cpp]
view plain
copy
print?
//输出二叉树
void PrintBTree( BiTree &T){
if(T!=NULL){
printf("%c",T->data); //输出根节点的值
if(T->lchild!=NULL||T->rchild!=NULL){
printf("(");
PrintBTree(T->lchild);//输出左子树
if(T->rchild!=NULL)
printf(",");
PrintBTree(T->rchild);//输出右子树
printf(")");
}
}
}
遍历即将树的所有结点访问且仅访问一次。按照根节点
置的不同分为前序遍历,中序遍历,后序遍历。
前序遍历:根节点->左子树->右子树
中序遍历:左子树->根节点->右子树
后序遍历:左子树->右子树->根节点
例如:求下面树的三种遍历
前序遍历:abdefgc
中序遍历:debgfac
后序遍历:edgfbca
[cpp]
view plain
copy
print?
void Preorder(BiTree &T){
if(T!=NULL){
printf("%c,",T->data);
Preorder(T->lchild);
Preorder(T->rchild);
}
}
//中序遍历
void Inorder(BiTree &T){
if(T!=NULL) {
Inorder(T->lchild);
printf("%c,",T->data);
Inorder(T->rchild);
}
}
//后序遍历
void Postorder(BiTree &T){
if(T!=NULL){
Postorder(T->lchild);
Postorder(T->rchild);
printf("%c,",T->data);
}
}
六,中序非递归遍历
[cpp]
view plain
copy
print?
// 中序非递归
void FInorder(BiTree T){
BiTree p;
BiTree s[StackMaxSize]; //定义s数组作为存储根结点的指针的栈使用
int top = -1; //栈顶指针置为-1,表示空栈
p=T; //跟指针
if(!p){
printf("空树");
}
while(p||top!=-1){ //不是空树或者栈不为空
while(p){
top++;
s[top]=p;
p=p->lchild;
}
p=s[top]; //将值给p
s[top]=NULL; //制空s【top】这个位置
top--; //top向上移一个位置
printf("%c,",p->data); //输出p对应的数值
p=p->rchild; //访问右子树
}
}
图示过程:
完整代码(简单代码)
[cpp]
view plain
copy
print?
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#define QueueMaxSize 20 //定义队列数组长度
#define StackMaxSize 10 //定义栈数组长度
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
using namespace std; //以上是一些宏定义和头文件,在此不多赘述
typedef int Status;
typedef int TElemType;
typedef struct BiTNode{
TElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode , *BiTree;
void createBiTree(BiTree &T)
{
char c;
cin >> c;
if('#' == c)
T = NULL;
else
{
if(!(T=(BiTNode*)malloc(sizeof(BiTNode))))exit(-2);
T->data = c;
createBiTree(T->lchild);
createBiTree(T->rchild);
}
}
//输出二叉树
void PrintBTree( BiTree &T){
if(T!=NULL){
printf("%c",T->data); //输出根节点的值
if(T->lchild!=NULL||T->rchild!=NULL){
printf("(");
PrintBTree(T->lchild);//输出左子树
if(T->rchild!=NULL)
printf(",");
PrintBTree(T->rchild);//输出右子树
printf(")");
}
}
}
//前序遍历
void Preorder(BiTree &T){
if(T!=NULL){
printf("%c,",T->data);
Preorder(T->lchild);
Preorder(T->rchild);
}
}
//中序遍历
void Inorder(BiTree &T){
if(T!=NULL) {
Inorder(T->lchild);
printf("%c,",T->data);
Inorder(T->rchild);
}
}
//后序遍历
void Postorder(BiTree &T){
if(T!=NULL){
Postorder(T->lchild);
Postorder(T->rchild);
printf("%c,",T->data);
}
}
// 中序非递归
void FInorder(BiTree T){
BiTree p;
BiTree s[StackMaxSize]; //定义s数组作为存储根结点的指针的栈使用
int top = -1; //栈顶指针置为-1,表示空栈
p=T; //跟指针
if(!p){
printf("空树");
}
while(p||top!=-1){ //不是空树或者栈不为空
while(p){
top++;
s[top]=p;
p=p->lchild;
}
p=s[top]; //将值给p
s[top]=NULL; //制空s【top】这
位置
top--; //top向上移一个
置
printf("%c,",p->data); //输出p对应的数值
p=p->rchild; //访问右
树
}
}
int main()
{
BiTree bt;
printf("先序建立二叉树,#号代表空\n");
createBiTree(bt);
PrintBTree(bt);
printf("\n");
printf("前序:");
Preorder(bt);
printf("\n");
printf("中序:");
Inorder(bt);
printf("\n");
printf("后序:");
Postorder(bt);
printf("\n");
printf("中序非递归:");
FInorder(bt);
}
自己输入一个二叉树的元素试一试,比如:
先序建立二叉树,#号代表空
ABD##E##CF##G##
A(B(D,E),C(F,G))
前序:A,B,D,E,C,F,G,
中序:D,B,E,A,F,C,G,
后序:D,E,B,F,G,C,A,
中序非递归:D,B,E,A,F,C,G,
一、基本概念
每个结点最多有两棵子树,左子树和右子树,次序不可以颠倒。
性质:
1、非空二叉树的第n层上至多有2^(n-1)个元素。
2、深度为h的二叉树至多有2^h-1个结点。
满二叉树:所有终端都在同一层次,且非终端结点的度数为2。
在满二叉树中若其深度为h,则其所包含的结点数必为2^h-1。
完全二叉树:除了最大的层次即成为一颗满二叉树且层次最大那层所有的结点均向左靠齐,即集中在左面的位置上,不能有空位置。
对于完全二叉树,设一个结点为i则其父节点为i/2,2i为左子节点,2i+1为右子节点。
二、存储结构
顺序存储:
将数据结构存在一块固定的数组中。
[cpp]
view plain
copy
print?
#define LENGTH 100
typedef char datatype;
typedef struct node{
datatype data;
115de
int lchild,rchild;
int parent;
}Node;
Node tree[LENGTH];
int length;
int root;
#define LENGTH 100 typedef char datatype; typedef struct node{ datatype data; int lchild,rchild; int parent; }Node; Node tree[LENGTH]; int length; int root;
虽然在遍历速度上有一定的优势,但因所占空间比较大,是非主流二叉树。二叉树通常以链式存储。
链式存储:
[cpp]
view plain
copy
print?
typedef int Status;
typedef int TElemType;
typedef struct BiTNode{
TElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode , *BiTree;
typedef int Status; typedef int TElemType; typedef struct BiTNode{ TElemType data; struct BiTNode *lchild,*rchild; }BiTNode , *BiTree;
三.二叉树的创建(先序创建)
[cpp]
view plain
copy
print?
void createBiTree(BiTree &T)
{
char c;
cin >> c;
if('#' == c)
T = NULL;
else
{
if(!(T=(BiTNode *)malloc(sizeof(BiTNode))))exit(-2);
T->data = c;
createBiTree(T->lchild);
createBiTree(T->rchild);
}
}
void createBiTree(BiTree &T) { char c; cin >> c; if('#' == c) T = NULL; else { if(!(T=(BiTNode *)malloc(sizeof(BiTNode))))exit(-2); T->data = c; createBiTree(T->lchild); createBiTree(T->rchild); } }
四,输出二叉树
[cpp]
view plain
copy
print?
//输出二叉树
void PrintBTree( BiTree &T){
if(T!=NULL){
printf("%c",T->data); //输出根节点的值
if(T->lchild!=NULL||T->rchild!=NULL){
printf("(");
PrintBTree(T->lchild);//输出左子树
if(T->rchild!=NULL)
printf(",");
PrintBTree(T->rchild);//输出右子树
printf(")");
}
}
}
//输出二叉树 void PrintBTree( BiTree &T){ if(T!=NULL){ printf("%c",T->data); //输出根节点的值 if(T->lchild!=NULL||T->rchild!=NULL){ printf("("); PrintBTree(T->lchild);//输出左子树 if(T->rchild!=NULL) printf(","); PrintBTree(T->rchild);//输出右子树 printf(")"); } } }五,二叉树的(递归)遍历
遍历即将树的所有结点访问且仅访问一次。按照根节点
置的不同分为前序遍历,中序遍历,后序遍历。
前序遍历:根节点->左子树->右子树
中序遍历:左子树->根节点->右子树
后序遍历:左子树->右子树->根节点
例如:求下面树的三种遍历
前序遍历:abdefgc
中序遍历:debgfac
后序遍历:edgfbca
[cpp]
view plain
copy
print?
void Preorder(BiTree &T){
if(T!=NULL){
printf("%c,",T->data);
Preorder(T->lchild);
Preorder(T->rchild);
}
}
//中序遍历
void Inorder(BiTree &T){
if(T!=NULL) {
Inorder(T->lchild);
printf("%c,",T->data);
Inorder(T->rchild);
}
}
//后序遍历
void Postorder(BiTree &T){
if(T!=NULL){
Postorder(T->lchild);
Postorder(T->rchild);
printf("%c,",T->data);
}
}
void Preorder(BiTree &T){ if(T!=NULL){ printf("%c,",T->data); Preorder(T->lchild); Preorder(T->rchild); } } //中序遍历 void Inorder(BiTree &T){ if(T!=NULL) { Inorder(T->lchild); printf("%c,",T->data); Inorder(T->rchild); } } //后序遍历 void Postorder(BiTree &T){ if(T!=NULL){ Postorder(T->lchild); Postorder(T->rchild); printf("%c,",T->data); } }
六,中序非递归遍历
[cpp]
view plain
copy
print?
// 中序非递归
void FInorder(BiTree T){
BiTree p;
BiTree s[StackMaxSize]; //定义s数组作为存储根结点的指针的栈使用
int top = -1; //栈顶指针置为-1,表示空栈
p=T; //跟指针
if(!p){
printf("空树");
}
while(p||top!=-1){ //不是空树或者栈不为空
while(p){
top++;
s[top]=p;
p=p->lchild;
}
p=s[top]; //将值给p
s[top]=NULL; //制空s【top】这个位置
top--; //top向上移一个位置
printf("%c,",p->data); //输出p对应的数值
p=p->rchild; //访问右子树
}
}
// 中序非递归 void FInorder(BiTree T){ BiTree p; BiTree s[StackMaxSize]; //定义s数组作为存储根结点的指针的栈使用 int top = -1; //栈顶指针置为-1,表示空栈 p=T; //跟指针 if(!p){ printf("空树"); } while(p||top!=-1){ //不是空树或者栈不为空 while(p){ top++; s[top]=p; p=p->lchild; } p=s[top]; //将值给p s[top]=NULL; //制空s【top】这个位置 top--; //top向上移一个位置 printf("%c,",p->data); //输出p对应的数值 p=p->rchild; //访问右子树 } }
图示过程:
完整代码(简单代码)
[cpp]
view plain
copy
print?
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#define QueueMaxSize 20 //定义队列数组长度
#define StackMaxSize 10 //定义栈数组长度
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
using namespace std; //以上是一些宏定义和头文件,在此不多赘述
typedef int Status;
typedef int TElemType;
typedef struct BiTNode{
TElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode , *BiTree;
void createBiTree(BiTree &T)
{
char c;
cin >> c;
if('#' == c)
T = NULL;
else
{
if(!(T=(BiTNode*)malloc(sizeof(BiTNode))))exit(-2);
T->data = c;
createBiTree(T->lchild);
createBiTree(T->rchild);
}
}
//输出二叉树
void PrintBTree( BiTree &T){
if(T!=NULL){
printf("%c",T->data); //输出根节点的值
if(T->lchild!=NULL||T->rchild!=NULL){
printf("(");
PrintBTree(T->lchild);//输出左子树
if(T->rchild!=NULL)
printf(",");
PrintBTree(T->rchild);//输出右子树
printf(")");
}
}
}
//前序遍历
void Preorder(BiTree &T){
if(T!=NULL){
printf("%c,",T->data);
Preorder(T->lchild);
Preorder(T->rchild);
}
}
//中序遍历
void Inorder(BiTree &T){
if(T!=NULL) {
Inorder(T->lchild);
printf("%c,",T->data);
Inorder(T->rchild);
}
}
//后序遍历
void Postorder(BiTree &T){
if(T!=NULL){
Postorder(T->lchild);
Postorder(T->rchild);
printf("%c,",T->data);
}
}
// 中序非递归
void FInorder(BiTree T){
BiTree p;
BiTree s[StackMaxSize]; //定义s数组作为存储根结点的指针的栈使用
int top = -1; //栈顶指针置为-1,表示空栈
p=T; //跟指针
if(!p){
printf("空树");
}
while(p||top!=-1){ //不是空树或者栈不为空
while(p){
top++;
s[top]=p;
p=p->lchild;
}
p=s[top]; //将值给p
s[top]=NULL; //制空s【top】这
位置
top--; //top向上移一个
置
printf("%c,",p->data); //输出p对应的数值
p=p->rchild; //访问右
树
}
}
int main()
{
BiTree bt;
printf("先序建立二叉树,#号代表空\n");
createBiTree(bt);
PrintBTree(bt);
printf("\n");
printf("前序:");
Preorder(bt);
printf("\n");
printf("中序:");
Inorder(bt);
printf("\n");
printf("后序:");
Postorder(bt);
printf("\n");
printf("中序非递归:");
FInorder(bt);
}
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#define QueueMaxSize 20 //定义队列数组长度
#define StackMaxSize 10 //定义栈数组长度
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
using namespace std; //以上是一些宏定义和头文件,在此不多赘述
typedef int Status;
typedef int TElemType;
typedef struct BiTNode{
TElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode , *BiTree;
void createBiTree(BiTree &T)
{
char c;
cin >> c;
if('#' == c)
T = NULL;
else
{
if(!(T=(BiTNode*)malloc(sizeof(BiTNode))))exit(-2);
T->data = c;
createBiTree(T->lchild);
createBiTree(T->rchild);
}
}
//输出二叉树 void PrintBTree( BiTree &T){ if(T!=NULL){ printf("%c",T->data); //输出根节点的值 if(T->lchild!=NULL||T->rchild!=NULL){ printf("("); PrintBTree(T->lchild);//输出左子树 if(T->rchild!=NULL) printf(","); PrintBTree(T->rchild);//输出右子树 printf(")"); } } }
//前序遍历
void Preorder(BiTree &T){ if(T!=NULL){ printf("%c,",T->data); Preorder(T->lchild); Preorder(T->rchild); } } //中序遍历 void Inorder(BiTree &T){ if(T!=NULL) { Inorder(T->lchild); printf("%c,",T->data); Inorder(T->rchild); } } //后序遍历 void Postorder(BiTree &T){ if(T!=NULL){ Postorder(T->lchild); Postorder(T->rchild); printf("%c,",T->data); } }
// 中序非递归
void FInorder(BiTree T){
BiTree p;
BiTree s[StackMaxSize]; //定义s数组作为存储根结点的指针的栈使用
int top = -1; //栈顶指针置为-1,表示空栈
p=T; //跟指针
if(!p){
printf("空树");
}
while(p||top!=-1){ //不是空树或者栈不为空
while(p){
top++;
s[top]=p;
p=p->lchild;
}
p=s[top]; //将值给p
s[top]=NULL; //制空s【top】这
位置
top--; //top向上移一个
置
printf("%c,",p->data); //输出p对应的数值
p=p->rchild; //访问右
树
}
}
int main()
{
BiTree bt;
printf("先序建立二叉树,#号代表空\n");
createBiTree(bt);
PrintBTree(bt);
printf("\n");
printf("前序:");
Preorder(bt);
printf("\n");
printf("中序:");
Inorder(bt);
printf("\n");
printf("后序:");
Postorder(bt);
printf("\n");
printf("中序非递归:");
FInorder(bt);
}
自己输入一个二叉树的元素试一试,比如:
先序建立二叉树,#号代表空
ABD##E##CF##G##
A(B(D,E),C(F,G))
前序:A,B,D,E,C,F,G,
中序:D,B,E,A,F,C,G,
后序:D,E,B,F,G,C,A,
中序非递归:D,B,E,A,F,C,G,
相关文章推荐
- 数据结构-二叉树(递归前序、中序、后序遍历;栈实现中序变量;二叉树镜像)
- 数据结构(六)——二叉树 前序、中序、后序、层次遍历及非递归实现 查找、统计个数、比较、求深度的递归实现
- 数据结构(六)——二叉树 前序、中序、后序、层次遍历及非递归实现 查找、统计个数、比较、求深度的递归实现
- 数据结构 ——二叉树 前序、中序、后序、层次遍历及非递归实现 查找、统计个数、比较、求深度的递归实现
- 数据结构---二叉树的前序、中序、后序遍历的递归和非递归 实现(C++)
- C++实现二叉树的递归遍历与非递归遍历(先序、中序、后序、层序)
- 数据结构-二叉树的前序、中序、后序遍历的递归和非递归实现
- 数据结构_二叉树的先序建立与先序,中序,后序(递归)遍历方式_C语言源代码
- 数据结构 —— 二叉树 前序、中序、后序、层次遍历及非递归实现 查找、统计个数、比较、求深度的递归实现
- 数据结构:二叉树的前序,中序,后序遍历(递归和非递归)
- 二叉树的先序、中序、后序遍历方法(递归与非递归方法)——《数据结构》
- 【数据结构】二叉树结点插入和前序、中序、后序遍历的递归实现
- 二叉树基本操作的递归实现(二叉树建立,先序,中序,后序,深度的递归遍历。广度优先,高度优先的非递归遍历)
- 二叉树的先序、中序、后序遍历的递归和非递归实现
- 数据结构二叉树的实现,前序、中序、后序遍历
- 二叉树 前序,中序,后序遍历 --非递归遍历
- 二叉树先序、中序,后序遍历的递归和非递归实现
- 二叉树的遍历:前序,中序,后序,层序--包括递归和非递归实现
- 非递归遍历二叉树的四种策略-先序、中序、后序和层序
- 非递归遍历二叉树的四种策略-先序、中序、后序和层序