面试常考之二叉树
2015-08-11 11:17
579 查看
二叉树在数据结构面试中的地位举足轻重,算得上是大公司面试必问,笔试必考;因为对二叉树的操作直接反应一个人的数据结构功底有多深厚,基础知识是否扎实。。。(一点废话),下面就二叉树的基本操作说一说二叉树的知识点,不对之处还请指正。
面试常考的几个操作:
1:二叉树的基本性质
2:递归建立二叉树
3:递归遍历二叉树(先序,中序,后序)
4:非递归遍历二叉树(先序,中序,后序)
5:求二叉树中的节点个数
6:求二叉树的深度
7:分层遍历二叉树
8:求二叉树第K层的节点个数
9:求二叉树的镜像
10:测试源码
下面就常用的算法给大家讲解这些二叉树的基本性质。
说明:
所有代码使用C语言编写,头信息,常量如下:
二叉树结构体,以及栈、队列的结构体(层次遍历,非递归要用到)如下:
1:二叉树的基本性质
一、二叉树第 i 层上最多有2i-1个节点
二、深度为 k 的二叉树,最多有2k - 1个节点
三、对于任意一颗二叉树T,如果其终端节点数为n1度数为2的节点数为n2 则 n1 = n2 + 1;
四、具有n个节点的完全二叉树深度为[ log2n] + 1;
2:递归建立二叉树
递归常见二叉树,先从左子树开始,arr 是调用传值过去的节点值,i 用于移动数组内的节点值
3:递归遍历二叉树(先序,中序,后序)
这是三中常规的遍历二叉树的方法,用的非常多,不仅便于理解,而且三个函数只是调用顺序不同,所以书上页数先给出了这三种遍历。当然在面试中也长问到。
4:非递归遍历二叉树(先序,中序,后序)
非递归遍历在面试中问的非常多,特别是大公司的面试,几乎是必问,所以这里就非递归的方法每个给出了两种
一、先序遍历:
先序遍历这里给出了两个方法,两种方法都是借助于栈来实现,具体的栈的操作在最后源程序中都有,看家可以看看,非递归的操作比递归麻烦得多,第一种方法是:首先根节点入栈,然后while循环一致判断栈是否为空,第二个while循环一直讲左节点入栈,知道左子树为空。其中PopN(S); 方法是为了将多余的空元素弹出。第二种方法比较推荐开始根节点不入栈,先判断根节点是否为空,这样栈空间中不会有空元素,效率高一点,并且便于理解
二、中序遍历:
中序遍历这里也给出2种方法。感觉和先序差不多,只是遍历顺序不同,处理的时候方式一样,这里不再多说。
二、后序遍历:
个人感觉后序遍历的非递归是三种遍历方式中最难的。写了很长时间,总感觉找不到一种合适的方法来保证孩子节点完全遍历。下面来说说这种非递归的遍历。其实会了也比较简单,对于结点P,要保证根结点在左孩子和右孩子访问之后才能访问,先将其入栈。如果P不存在左孩子和右孩子,可以直接访问;或者P 存在左孩子或者右孩子,访问过左孩子和右孩子后可以直接访问该结点。其他情况,则将P的右孩子和左孩子依次入栈。这个就会这一种,应该有其他方法,欢迎指出
5:求二叉树中的节点个数
其实就是遍历一遍二叉树,不再多说,看程序便知
6:求二叉树的深度
思想就是从左子树开始遍历,递归完整个树结构,如果二叉树不为空,二叉树的深度 = max(左子树深度, 右子树深度) + 1,参考代码如下:
7:分层遍历二叉树
一、树的层次结构分层打印与队列的的先进先出相似,所以我选择用队列来完成,首先根节点入队列,然后左孩子,又孩子以此入队列,打印即可
二、说到分层如果打印树的真实结构应该也可以,所以我想借助堆栈来实现,有兴趣的可以看一下,思想:其实和层次遍历一样,最难的是怎样控制换行先,我的想法是创建一个标志位*,当前行入栈完毕就插入标志位*遍历一个节点就把左孩子和右孩子入栈,以此一层一层的打印,代码检验过,不知道还有没有错误,欢迎指正
8:求二叉树第K层的节点个数
利用递归的次数来(孩子节点不为空的条件)来简介得到k层节点的个数,比较简单,代码如下
9:求二叉树的镜像
所谓的镜像其实就是左子树和右子树互换颠倒,如下面代码。
10:测试源码
最后附上完整的测试代码,其中包含了,队列的初始化,插入队列,出队列操作,栈的初始化,进栈,出栈,得到栈顶元,树的初始化素等也可以复习一下。中间可定有不对不足的地方,还望大神们多多指正
运行结果:
转载请注明出处,谢谢!
面试常考的几个操作:
1:二叉树的基本性质
2:递归建立二叉树
3:递归遍历二叉树(先序,中序,后序)
4:非递归遍历二叉树(先序,中序,后序)
5:求二叉树中的节点个数
6:求二叉树的深度
7:分层遍历二叉树
8:求二叉树第K层的节点个数
9:求二叉树的镜像
10:测试源码
下面就常用的算法给大家讲解这些二叉树的基本性质。
说明:
所有代码使用C语言编写,头信息,常量如下:
** * 树的基本操作tree */ #include <stdio.h> #include <stdlib.h> #include <string.h> #define ERROR -1 #define OK 1 #define OVERFLOW 2 #define STACK_INIT_SIZE 100 #define STACKINCREMENT 20 //最大队列长度 #define MAXQSIZE 100 typedef int Struct; typedef char TElement; typedef int Status; int i = 0; //记录树初始化过程,数据的偏移 int j = 0; //记录树初始化过程,数据的偏移
二叉树结构体,以及栈、队列的结构体(层次遍历,非递归要用到)如下:
//二叉树结构体(二叉链表存储结构) typedef struct BiNode{ TElement data; struct BiNode *lchild,*rchild; }BiTNode, *BiTree; //栈表示(用于非递归) typedef struct{ BiTree *base; BiTree *top; int stacksize; }SqStack; //使用队列,实现层次遍历 typedef struct QNode{ BiTree data; struct QNode *next; }QNode, *QueuePtr; typedef struct{ QueuePtr front; QueuePtr rear; }LinkQueue;
1:二叉树的基本性质
一、二叉树第 i 层上最多有2i-1个节点
二、深度为 k 的二叉树,最多有2k - 1个节点
三、对于任意一颗二叉树T,如果其终端节点数为n1度数为2的节点数为n2 则 n1 = n2 + 1;
四、具有n个节点的完全二叉树深度为[ log2n] + 1;
2:递归建立二叉树
递归常见二叉树,先从左子树开始,arr 是调用传值过去的节点值,i 用于移动数组内的节点值
//创建二叉树 Struct CreateBiTree(BiTree &T, char arr[]){ if(arr[i] == ' '){ i++; T = NULL; }else{ T = (BiTree)malloc(sizeof(BiNode)); if(!T){ exit(ERROR);//分配空间失败; } T->data = arr[i]; i++; CreateBiTree(T->lchild, arr); CreateBiTree(T->rchild, arr); } return OK; }
3:递归遍历二叉树(先序,中序,后序)
这是三中常规的遍历二叉树的方法,用的非常多,不仅便于理解,而且三个函数只是调用顺序不同,所以书上页数先给出了这三种遍历。当然在面试中也长问到。
//先序遍历(递归方法) int PrintTree(BiTree T){ if(T){ printf("%c ",T->data); PrintTree(T->lchild); PrintTree(T->rchild); } return OK; } //中序遍历(递归方法) int PrintTreeL(BiTree T){ if(T){ PrintTreeL(T->lchild); printf("%c ",T->data); PrintTreeL(T->rchild); } return OK; } //后序遍历(递归方法) int PrintTreeR(BiTree T){ if(T){ PrintTreeR(T->lchild); PrintTreeR(T->rchild); printf("%c ",T->data); } return OK; }
4:非递归遍历二叉树(先序,中序,后序)
非递归遍历在面试中问的非常多,特别是大公司的面试,几乎是必问,所以这里就非递归的方法每个给出了两种
一、先序遍历:
先序遍历这里给出了两个方法,两种方法都是借助于栈来实现,具体的栈的操作在最后源程序中都有,看家可以看看,非递归的操作比递归麻烦得多,第一种方法是:首先根节点入栈,然后while循环一致判断栈是否为空,第二个while循环一直讲左节点入栈,知道左子树为空。其中PopN(S); 方法是为了将多余的空元素弹出。第二种方法比较推荐开始根节点不入栈,先判断根节点是否为空,这样栈空间中不会有空元素,效率高一点,并且便于理解
//先序遍历(非递归方法)(方法1) int PrintTree_Re(BiTree T){ SqStack S; InitStack(S);//建立栈 Push(S,T); //树的根节点先入栈 BiTree P; while(StackEmpty(S) == 1){ while(GetTop(S,P) && P){ printf("%c ",P->data); Push(S,P->lchild); } PopN(S); if(StackEmpty(S) == 1){ Pop(S,P); Push(S,P->rchild); } } return OK; } //先序遍历(非递归方法)(方法2) int PrintTree_Re_T(BiTree T){ SqStack s; InitStack(s); BiTree p; p = T; while(p || StackEmpty(s) == 1){ while(p){ printf("%c ",p->data); Push(s,p); p = p->lchild; } if(StackEmpty(s) == 1){ Pop(s,p); p = p->rchild; } } return OK; }
二、中序遍历:
中序遍历这里也给出2种方法。感觉和先序差不多,只是遍历顺序不同,处理的时候方式一样,这里不再多说。
//中序遍历(非递归)(方法1) int PrintTreeL_Re(BiTree T){ SqStack S; InitStack(S);//建立栈 Push(S,T); //树的根节点先入栈 BiTree P; while(StackEmpty(S) == 1){ while(GetTop(S,P) && P){ Push(S,P->lchild); } PopN(S); if(StackEmpty(S) == 1){ Pop(S,P); printf("%c ",P->data); Push(S,P->rchild); } } return OK; } //中序遍历(非递归)(方法2) int PrintTreeL_Re_T(BiTree T){ SqStack S; InitStack(S);//建立栈 BiTree P; P = T; while(P || StackEmpty(S) == 1){ if(P){ Push(S,P); P = P->lchild; }else{ Pop(S,P); printf("%c ",P->data); P = P->rchild; } } return OK; }
二、后序遍历:
个人感觉后序遍历的非递归是三种遍历方式中最难的。写了很长时间,总感觉找不到一种合适的方法来保证孩子节点完全遍历。下面来说说这种非递归的遍历。其实会了也比较简单,对于结点P,要保证根结点在左孩子和右孩子访问之后才能访问,先将其入栈。如果P不存在左孩子和右孩子,可以直接访问;或者P 存在左孩子或者右孩子,访问过左孩子和右孩子后可以直接访问该结点。其他情况,则将P的右孩子和左孩子依次入栈。这个就会这一种,应该有其他方法,欢迎指出
//后序遍历(非递归方法) int PrintTreeR_Re(BiTree T){ SqStack s; InitStack(s);//建立栈 Push(s,T); //树的根节点先入栈 BiTree p,q; while(StackEmpty(s) == 1){ GetTop(s,p); if((p->lchild == NULL && p->rchild == NULL) || ( q && ( q == p->lchild || q == p->rchild))){ printf("%c ",p->data); PopN(s); q = p; }else{ if(p->rchild){ Push(s,p->rchild); } if(p->lchild){ Push(s,p->lchild); } } } return OK; }
5:求二叉树中的节点个数
其实就是遍历一遍二叉树,不再多说,看程序便知
//统计二叉树节点的个数 void getTreeNodeNum(BiTree T,int &num){ if(!T){ num = 0; } num++; if(T->lchild){ getTreeNodeNum(T->lchild,num); } if(T->rchild){ getTreeNodeNum(T->rchild,num); } }
6:求二叉树的深度
思想就是从左子树开始遍历,递归完整个树结构,如果二叉树不为空,二叉树的深度 = max(左子树深度, 右子树深度) + 1,参考代码如下:
//得到树的深度 int getTreeHeight(BiTree T){ int hl,hr,max; if(T!=NULL){ hl=getTreeHeight(T->lchild); hr=getTreeHeight(T->rchild); max=hl>hr?hl:hr; return (max+1); }else{ return 0; } }
7:分层遍历二叉树
一、树的层次结构分层打印与队列的的先进先出相似,所以我选择用队列来完成,首先根节点入队列,然后左孩子,又孩子以此入队列,打印即可
/*层次遍历二叉树(借助队列实现)*/ void HierarchicalTree_Q(BiTree T){ LinkQueue Q; InitQueue(Q); //建立队列 EnQueue(Q,T); //树的根节点先入列 BiTree Ta; while(Q.front != Q.rear){ DeQueue(Q,Ta); if(Ta->lchild){ EnQueue(Q,Ta->lchild); } if(Ta->rchild){ EnQueue(Q,Ta->rchild); } printf("%c ",Ta->data); } }
二、说到分层如果打印树的真实结构应该也可以,所以我想借助堆栈来实现,有兴趣的可以看一下,思想:其实和层次遍历一样,最难的是怎样控制换行先,我的想法是创建一个标志位*,当前行入栈完毕就插入标志位*遍历一个节点就把左孩子和右孩子入栈,以此一层一层的打印,代码检验过,不知道还有没有错误,欢迎指正
/*层次遍历二叉树(并且分层打印)(借助栈实现)*/ void HierarchicalTree_DA(BiTree T){ LinkQueue Q; InitQueue(Q);//建立队列 EnQueue(Q,T);//树的根节点先入列 BiTree Ta1,Tb1,Tc1; //创建标志位 char data[3] = {'*',' ',' '}; CreateBiTree(Ta1,data); //创建移动的指针 QueuePtr point; point = Q.front->next;//移动指针先指向头结点 EnQueue(Q,Ta1);//插入标志位 printf("\n"); while(point){ //判断左右节点 if(point->data->lchild || point->data->rchild){ if(point->data->lchild){ EnQueue(Q,point->data->lchild); } if(point->data->rchild){ EnQueue(Q,point->data->rchild); } } point = point->next; //指针下移一位 if(point->data->data == '*'){ if(!point->next){//判断是否到结尾(到结尾直接退出) break; } EnQueue(Q,Ta1);//插入标志节点 point = point->next; //如果遇到标志位,则指针下移 } } printf("\n"); //循环输出节点 while(Q.front != Q.rear){ DeQueue(Q,Tc1); char str = Tc1->data; if(str == '*'){ printf("\n"); }else{ printf("%c ",str); } } }
8:求二叉树第K层的节点个数
利用递归的次数来(孩子节点不为空的条件)来简介得到k层节点的个数,比较简单,代码如下
//得到第k层的节点个数 int getNodeNum(BiTree T, int k){ if (!T || k < 1){ return 0; } if (k == 1){ return 1; } return getNodeNum(T->lchild, k-1) + getNodeNum(T->rchild, k-1); }
9:求二叉树的镜像
所谓的镜像其实就是左子树和右子树互换颠倒,如下面代码。
//写出二叉树的镜像 void getNoClone(BiTree &T){ BiTree Ta; if(T){ Ta = T->lchild; T->lchild = T->rchild; T->rchild = Ta; getNoClone(T->lchild); getNoClone(T->rchild); } }
10:测试源码
最后附上完整的测试代码,其中包含了,队列的初始化,插入队列,出队列操作,栈的初始化,进栈,出栈,得到栈顶元,树的初始化素等也可以复习一下。中间可定有不对不足的地方,还望大神们多多指正
/**
* 树的基本操作tree
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ERROR -1
#define OK 1
#define OVERFLOW 2
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 20
//最大队列长度
#define MAXQSIZE 100
typedef int Struct;
typedef char TElement;
typedef int Status;
int i = 0; //记录树初始化过程,数据的偏移
int j = 0; //记录树初始化过程,数据的偏移
//二叉树结构体(二叉链表存储结构)
typedef struct BiNode{
TElement data;
struct BiNode *lchild,*rchild;
}BiTNode, *BiTree;
//栈表示
typedef struct{
BiTree *base;
BiTree *top;
int stacksize;
}SqStack;
//使用队列,实现层次遍历
typedef struct QNode{
BiTree data;
struct QNode *next;
}QNode, *QueuePtr;
typedef struct{
QueuePtr front;
QueuePtr rear;
}LinkQueue;
//初始化队列
Status InitQueue(LinkQueue &Q){
Q.front = Q.rear = (QueuePtr)malloc(sizeof(BiTree));//动态分配空间
if(!Q.front){
exit(ERROR);//分配空间失败
}
Q.front->next = NULL;
return OK;
}
//在队尾插入新元素
Status EnQueue(LinkQueue &Q, BiTree e){
QueuePtr p;
p = (QueuePtr)malloc(sizeof(BiTree));
if(!p){
exit(ERROR);//分配失败
}
p->data = e;
p->next = NULL;
Q.rear->next = p;
Q.rear = p;
return OK;
}
//删除队头元素,并用e返回
void DeQueue(LinkQueue &Q,BiTree &e){
if(Q.front != Q.rear){//先判断队列是否为空
QueuePtr p;
e = Q.front->next->data;
if(Q.front->next == Q.rear){//队列只有一个元素
p = Q.rear;
Q.rear = Q.front;
Q.front->next = NULL;
}else{
p = Q.front->next;
Q.front->next = p->next;
p->next = NULL;
}
//free(p->data);
}
}
//创建二叉树 Struct CreateBiTree(BiTree &T, char arr[]){ if(arr[i] == ' '){ i++; T = NULL; }else{ T = (BiTree)malloc(sizeof(BiNode)); if(!T){ exit(ERROR);//分配空间失败; } T->data = arr[i]; i++; CreateBiTree(T->lchild, arr); CreateBiTree(T->rchild, arr); } return OK; }
//先序遍历(递归方法)
int PrintTree(BiTree T){
if(T){
printf("%c ",T->data);
PrintTree(T->lchild);
PrintTree(T->rchild);
}
return OK;
}
//中序遍历(递归方法)
int PrintTreeL(BiTree T){
if(T){
PrintTreeL(T->lchild);
printf("%c ",T->data);
PrintTreeL(T->rchild);
}
return OK;
}
//后序遍历(递归方法)
int PrintTreeR(BiTree T){
if(T){
PrintTreeR(T->lchild);
PrintTreeR(T->rchild);
printf("%c ",T->data);
}
return OK;
}
//初始化栈
Struct InitStack(SqStack &S){
S.base = (BiTree *)malloc(STACK_INIT_SIZE * sizeof(BiTree));
S.top = S.base;
if(!S.base){
exit(ERROR);//分配失败
}
S.stacksize = STACK_INIT_SIZE;
return OK;
}
//push入栈操作
Struct Push(SqStack &S, BiTree T){
if(S.top - S.base >= S.stacksize){
S.base = (BiTree *)realloc(S.base,(S.stacksize + STACKINCREMENT) * sizeof(BiTree));
if(!S.base){
exit(ERROR);
}
S.top = S.base + S.stacksize;
S.stacksize += STACKINCREMENT;
}
*S.top = T;
S.top++;
return OK;
}
//出栈操作
Struct Pop(SqStack &S,BiTree &P){
if(S.base != S.top){
P = *(--S.top);
}
return OK;
}
//出栈操作
Struct PopN(SqStack &S){
if(S.base != S.top){
--S.top;
}
return OK;
}
//得到栈顶元素操作
Struct GetTop(SqStack S,BiTree &P){
if(S.base != S.top){
P = *(S.top - 1);
}
return OK;
}
//判断是否是空栈
int StackEmpty(SqStack S){
if(S.base != S.top){
return 1;
}else{
return 0;
}
}
//返回栈长度
int GetLength(SqStack S){
return S.top - S.base;
}
//先序遍历(非递归方法)(方法1)
int PrintTree_Re(BiTree T){
SqStack S;
InitStack(S);//建立栈
Push(S,T); //树的根节点先入栈
BiTree P;
while(StackEmpty(S) == 1){
while(GetTop(S,P) && P){
printf("%c ",P->data);
Push(S,P->lchild);
}
PopN(S);
if(StackEmpty(S) == 1){
Pop(S,P);
Push(S,P->rchild);
}
}
return OK;
}
//先序遍历(非递归方法)(方法2)
int PrintTree_Re_T(BiTree T){
SqStack s;
InitStack(s);
BiTree p;
p = T;
while(p || StackEmpty(s) == 1){
while(p){
printf("%c ",p->data);
Push(s,p);
p = p->lchild;
}
if(StackEmpty(s) == 1){
Pop(s,p);
p = p->rchild;
}
}
return OK;
}
//中序遍历(非递归)(方法1)
int PrintTreeL_Re(BiTree T){
SqStack S;
InitStack(S);//建立栈
Push(S,T); //树的根节点先入栈
BiTree P;
while(StackEmpty(S) == 1){
while(GetTop(S,P) && P){
Push(S,P->lchild);
}
PopN(S);
if(StackEmpty(S) == 1){
Pop(S,P);
printf("%c ",P->data);
Push(S,P->rchild);
}
}
return OK;
}
//中序遍历(非递归)(方法2)
int PrintTreeL_Re_T(BiTree T){
SqStack S;
InitStack(S);//建立栈
BiTree P;
P = T;
while(P || StackEmpty(S) == 1){
if(P){
Push(S,P);
P = P->lchild;
}else{
Pop(S,P);
printf("%c ",P->data);
P = P->rchild;
}
}
return OK;
}
//后序遍历(非递归方法)
int PrintTreeR_Re(BiTree T){
SqStack s;
InitStack(s);//建立栈
Push(s,T); //树的根节点先入栈
BiTree p,q;
while(StackEmpty(s) == 1){
GetTop(s,p);
if((p->lchild == NULL && p->rchild == NULL) || ( q && ( q == p->lchild || q == p->rchild))){
printf("%c ",p->data);
PopN(s);
q = p;
}else{
if(p->rchild){
Push(s,p->rchild);
}
if(p->lchild){
Push(s,p->lchild);
}
}
}
return OK;
}
/*层次遍历二叉树*/
void HierarchicalTree(BiTree T){
BiTree Ta = T;
if(Ta){
printf("%c ",Ta->data);
if(Ta->lchild){
//printf("%c ",Ta->lchild->data);
HierarchicalTree(Ta->lchild);
}
if(Ta->rchild){
//printf("%c ",Ta->rchild->data);
HierarchicalTree(Ta->rchild);
}
}
}
/*层次遍历二叉树(借助队列实现)*/
void HierarchicalTree_Q(BiTree T){
LinkQueue Q;
InitQueue(Q); //建立队列
EnQueue(Q,T); //树的根节点先入列
BiTree Ta;
while(Q.front != Q.rear){
DeQueue(Q,Ta);
if(Ta->lchild){
EnQueue(Q,Ta->lchild);
}
if(Ta->rchild){
EnQueue(Q,Ta->rchild);
}
printf("%c ",Ta->data);
}
}
/*层次遍历二叉树(并且分层打印)(借助队列实现)*/
void HierarchicalTree_DA(BiTree T){
LinkQueue Q;
InitQueue(Q);//建立队列
EnQueue(Q,T);//树的根节点先入列
BiTree Ta1,Tb1,Tc1;
//创建标志位
char data[3] = {'*',' ',' '};
CreateBiTree(Ta1,data);
//创建移动的指针
QueuePtr point;
point = Q.front->next;//移动指针先指向头结点
EnQueue(Q,Ta1);//插入标志位
printf("\n");
while(point){
//判断左右节点
if(point->data->lchild || point->data->rchild){
if(point->data->lchild){
EnQueue(Q,point->data->lchild);
}
if(point->data->rchild){
EnQueue(Q,point->data->rchild);
}
}
point = point->next; //指针下移一位
if(point->data->data == '*'){
if(!point->next){//判断是否到结尾(到结尾直接退出)
break;
}
EnQueue(Q,Ta1);//插入标志节点
point = point->next; //如果遇到标志位,则指针下移
}
}
printf("\n");
//循环输出节点
while(Q.front != Q.rear){
DeQueue(Q,Tc1);
char str = Tc1->data;
if(str == '*'){
printf("\n");
}else{
printf("%c ",str);
}
}
}
//统计二叉树节点的个数
void getTreeNodeNum(BiTree T,int &num){
if(!T){
num = 0;
}
num++;
if(T->lchild){
getTreeNodeNum(T->lchild,num);
}
if(T->rchild){
getTreeNodeNum(T->rchild,num);
}
}
//得到树的深度
int getTreeHeight(BiTree T){
int hl,hr,max;
if(T!=NULL){
hl=getTreeHeight(T->lchild);
hr=getTreeHeight(T->rchild);
max=hl>hr?hl:hr;
return (max+1);
}else{
return 0;
}
}
//得到第k层的节点个数
int getNodeNum(BiTree T, int k){
if (!T || k < 1){
return 0;
}
if (k == 1){
return 1;
}
return getNodeNum(T->lchild, k-1) + getNodeNum(T->rchild, k-1);
}
void main(){
i = 0;
//char Data[15] = {'A','B','C',' ',' ','D','E',' ','G',' ',' ','F',' ',' ',' '};
//char Data[15] = {'A','B','C',' ',' ','D','E',' ',' ','G',' ',' ','F',' ',' '};
char Data[16] = {'A','B','C',' ',' ',' ','D','E',' ','G',' ',' ','F',' ',' ',' '};
//char Data[7] = {'A','B','C',' ',' ',' ',' '};
//char Data[7] = {'A',' ','b',' ','c',' ',' '};
BiTree Ta,Tb;
CreateBiTree(Ta,Data);
printf("*****************递归方法遍历二叉树**************\n");
printf("先序遍历:");
PrintTree(Ta);
printf("\n");
printf("中序遍历:");
PrintTreeL(Ta);
printf("\n");
printf("后序遍历:");
PrintTreeR(Ta);
printf("\n");
printf("非递归先序遍历法1:");
PrintTree_Re(Ta);
printf("\n");
printf("非递归先序遍历法2:");
PrintTree_Re_T(Ta);
printf("\n");
printf("非递归中序遍历法1:");
PrintTreeL_Re(Ta);
printf("\n");
printf("非递归中序遍历法2:");
PrintTreeL_Re_T(Ta);
printf("\n");
printf("非递归后序遍历:");
PrintTreeR_Re(Ta);
printf("\n");
printf("层次遍历:");
HierarchicalTree_Q(Ta);
printf("\n");
printf("\n");
printf("层次遍历(分层显示):");
i = 0;
HierarchicalTree_DA(Ta);
printf("\n");
printf("总结点个数:");
int TreeNum = 0;
getTreeNodeNum(Ta,TreeNum);
printf("%d ",TreeNum);
printf("\n");
printf("树的深度:");
int TreeHeight = 0;
TreeHeight = getTreeHeight(Ta);
printf("%d ",TreeHeight);
printf("\n");
printf("得到第3层的节点个数:");
printf("%d",getNodeNum(Ta,3));
printf("\n");
}
运行结果:
转载请注明出处,谢谢!
相关文章推荐
- 100分程序员的8个习惯
- 总结面试找工作时遇到的一些问题
- 程序员很穷
- 黑马程序员-集合框架(二)
- 黑马程序员--java技术blog---第一篇:其他对象
- 黑马程序员—————Java基础语法(2)----语句、函数和数组
- 【.Net码农】关于使用FileUpload控件报 Could not find a part of the path "X/1.jpg"
- 黑马程序员-Java基础:面向对象
- 22. 程序员生存定律-公司选择上的方法论
- 程序员如何持续提升自己的开发技能
- 21. 程序员生存定律-选公司前要干的事:分类
- 为什么程序员的业余项目大多都死了?
- 程序员很穷
- 线程面试题
- 《招聘一个靠谱的iOS》面试题参考答案(上)
- 黑马程序员—————Java基础语法(1)----关键字、标示符、注释、常量、进制、变量、运算符
- 程序员未来发展三大方向
- 关于程序员工作 交接的一些注意事项
- 为什么程序员的业余项目大多都死了?
- 黑马程序员——ios学习笔记 OC 内存管理