二叉树基本概念
树是复杂的非线性结构,二叉树是其中的一种特殊的树。二叉树的非跟节点有且仅有一个父亲节点,所有节点最多有两个子节点。
本文先是使用递归的方法将用户输入的数组用递归的方法生成一个二叉树,在对这个二叉树实现二叉树的基本操作——先序遍历,
中序遍历,后续遍历,层次遍历,求树深的基本操作。
基本操作的实现
二叉树的构建
先录入输入的数组到数组a中,再根据树中的位置和数值位置的对应关系来构建二叉树。其中999表示空节点。
//初始化树节点
Tree* initTree(){
Tree *T;
T = (Tree*)malloc(sizeof(Tree)); //分配空间
T->data = 999;
T->lchild = NULL;
T->rchild = NULL;
return T;
}
Tree* buildTree(){
Tree* T = initTree(); //树的根结点
int h; //存储树高
ElemType* a; //存储输入的数
printf("输入数的高度:");
scanf("%d",&h);
if(h<1){
printf("高度参数非法");
}else{
a = scanfall(h);
if(h==1){
T->data = a[1];
}else{
T->data = a[1];
buildTree_1(T,a,1,h);
}
}
return T;
}
//读取输入的数的信息
ElemType* scanfall(int h){
int n = pow(2,h); //计算最大节点个数
printf("\n请按照层次输入二叉树的%d各元素,空用999表示\n",n-1);
ElemType *a;
a = (ElemType*)malloc(sizeof(ElemType)*n);
int i = 1;
int item;
while(i<n){
printf("请输入元素:");
scanf("%d",&item);
a[i++] = item;
}
return a;
}
//递归方式构建树
int buildTree_1(Tree *T,ElemType *a,int s,int h){
//节点非空时创建节点并接在树上
if(a[2*s]==999){
//return 0;
}else{
Tree *p = initTree();
p->data = a[2*s];
T->lchild = p;
}
if(a[2*s+1]==999){
//return 0;
}else{
Tree *q = initTree();
q->data = a[2*s+1];
T->rchild = q;
}
//向下层递归延伸
if(s<pow(2,h-2)){
if(T->lchild!=NULL){
buildTree_1(T->lchild,a,2*s,h);
}
if(T->rchild!=NULL){
buildTree_1(T->rchild,a,2*s+1,h);
}
}
}
二叉树的先序遍历
先访问父节点再依次访问左子树和右子树
//先序遍历
void mlr(Tree* T){
Tree* p = T;
printf("-%d-",T->data);
if(T->lchild!=NULL){
mlr(T->lchild);
}
if(T->rchild!=NULL){
mlr(T->rchild);
}
}
二叉树的中序遍历
//中序遍历
void lmr(Tree* T){
if(T->lchild!=NULL){
lmr(T->lchild);
}
printf("-%d-",T->data);
if(T->rchild!=NULL){
lmr(T->rchild);
}
}
二叉树的后序遍历
//后序遍历
void lrm(Tree* T){
if(T->lchild!=NULL){
lrm(T->lchild);
}
if(T->rchild!=NULL){
lrm(T->rchild);
}
printf("-%d-",T->data);
}
二叉树的层次遍历
//层次遍历
void traverse(Tree *T){
Tree* p = T;
Tree* Q[100]; //用以保存数的节点
int front = -1;
int rear = -1;
Q[++front] = p;
while(rear<front){
p = Q[++rear];
printf("-%d-",p->data);
if(p->lchild){
Q[++front] = p->lchild;
}
if(p->rchild){
Q[++front] = p->rchild;
}
}
二叉树的高
//获得树高
int high(Tree* T){
if(T==NULL){
return 0;
}else{
int l = high(T->lchild);
int r = high(T->rchild);
//树的高度为左右子树中高的一棵+1
if(l>r){
return ++l;
}else{
return ++r;
}
}
}
完整的测试用例
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <math.h>
typedef int ElemType;
typedef struct Tree{
ElemType data;
Tree *lchild,*rchild;
}; //定义数结构
Tree* initTree(); //初始化树节点
ElemType* scanfall(int h); //获得输入的树
Tree* buildTree(); //用输入元素构建二叉树
//构建树使用的递归函数
int buildTree_1(Tree *T,ElemType *a,int s,int h);
void mlr(Tree* T); //先序遍历二叉树
void lmr(Tree* T); //中序遍历二叉树
void lrm(Tree* T); //后序遍历二叉树
int high(Tree* T); //递归方式获得二叉树的高
void traverse(Tree* T); //层次遍历二叉树
int main(){
Tree *T = buildTree(); //构造二叉树
int h = high(T); //获得二叉树的高
printf("\n树的高度为:%d",h);
printf("\n先序遍历结果:\n");
mlr(T);
printf("\n中序遍历结果:\n");
lmr(T);
printf("\n后序遍历结果:\n");
lrm(T);
printf("\n层次遍历结果\n");
traverse(T);
//getchar();
}
//初始化树节点
Tree* initTree(){
Tree *T;
T = (Tree*)malloc(sizeof(Tree)); //分配空间
T->data = 999;
T->lchild = NULL;
T->rchild = NULL;
return T;
}
Tree* buildTree(){
Tree* T = initTree(); //树的根结点
int h; //存储树高
ElemType* a; //存储输入的数
printf("输入数的高度:");
scanf("%d",&h);
if(h<1){
printf("高度参数非法");
}else{
a = scanfall(h);
if(h==1){
T->data = a[1];
}else{
T->data = a[1];
buildTree_1(T,a,1,h);
}
}
return T;
}
//读取输入的数的信息
ElemType* scanfall(int h){
int n = pow(2,h); //计算最大节点个数
printf("\n请按照层次输入二叉树的%d各元素,空用999表示\n",n-1);
ElemType *a;
a = (ElemType*)malloc(sizeof(ElemType)*n);
int i = 1;
int item;
while(i<n){
printf("请输入元素:");
scanf("%d",&item);
a[i++] = item;
}
return a;
}
//递归方式构建树
int buildTree_1(Tree *T,ElemType *a,int s,int h){
//节点非空时创建节点并接在树上
if(a[2*s]==999){
//return 0;
}else{
Tree *p = initTree();
p->data = a[2*s];
T->lchild = p;
}
if(a[2*s+1]==999){
//return 0;
}else{
Tree *q = initTree();
q->data = a[2*s+1];
T->rchild = q;
}
//向下层递归延伸
if(s<pow(2,h-2)){
if(T->lchild!=NULL){
buildTree_1(T->lchild,a,2*s,h);
}
if(T->rchild!=NULL){
buildTree_1(T->rchild,a,2*s+1,h);
}
}
}
//先序遍历
void mlr(Tree* T){
Tree* p = T;
printf("-%d-",T->data);
if(T->lchild!=NULL){
mlr(T->lchild);
}
if(T->rchild!=NULL){
mlr(T->rchild);
}
}
//中序遍历
void lmr(Tree* T){
if(T->lchild!=NULL){
lmr(T->lchild);
}
printf("-%d-",T->data);
if(T->rchild!=NULL){
lmr(T->rchild);
}
}
//后序遍历
void lrm(Tree* T){
if(T->lchild!=NULL){
lrm(T->lchild);
}
if(T->rchild!=NULL){
lrm(T->rchild);
}
printf("-%d-",T->data);
}
//获得树高
int high(Tree* T){
if(T==NULL){
return 0;
}else{
int l = high(T->lchild);
int r = high(T->rchild);
//树的高度为左右子树中高的一棵+1
if(l>r){
return ++l;
}else{
return ++r;
}
}
}
//层次遍历
void traverse(Tree *T){
Tree* p = T;
Tree* Q[100]; //用以保存数的节点
int front = -1;
int rear = -1;
Q[++front] = p;
while(rear<front){
p = Q[++rear];
printf("-%d-",p->data);
if(p->lchild){
Q[++front] = p->lchild;
}
if(p->rchild){
Q[++front] = p->rchild;
}
}
}