() 1、计算指定结点*p所在的层次
#include <stdio.h>
/*
思想:
在先序遍历的基础上增加一个判断,判断两结点是否相等
步骤:
(1)if树为空,return 0;
(2)if两结点相等,return 1;
(3)递归地在左子树中查找,返回l
(4)递归地在右子树中查找,返回r
(5)如果在树中找到p(通过判断l和r,只要有一个返回1则证明找到),
那么比较左子树返回的l和右子树返回的r,返回较大者+1
*/
int getLevel(BiTree T,BSTNode *p){
if(T==NULL)
return 0;
if(T->data==p->data)
return 1;
int l=getLevel(T->lchild);
int r=getLevel(T->rchild);
if(l||r){
if(l>r)
return l+1;
else
return r+1;
}
}
2、以先序序列输出一颗二叉树中所有结点的数据值及结点所在的层次
#include <stdio.h>
/*
思想:
在先序遍历的基础上,增加了深度的参数
*/
void preOrder(BiTree T,int deep){
if(T){
printf("data:%s,deep:%d",T->data,deep);
preOrder(T->lchild,deep+1);
preOrder(T->rchild,deep+1);
}
}
3.1、统计二叉树中度为1的结点个数
#include <stdio.h>
/*
思想:
度为1的结点即左子树和右子树只有一个非空!!
*/
int preOrder(BiTree T){
if(T==NULL)
return 0;
else if(T->lchild!=NULL&&T->rchild==NULL||T->rchild!=NULL&&T->lchild==NULL)
return preOrder(T->lchild)+preOrder(T->rchild)+1;
else
return preOrder(T->lchild)+preOrder(T->rchild)
}
3.2 统计二叉树的非叶子结点
int preOrder(BiTree T){
if(T==NULL)
return 0;
if(T->lchild==NULL&&T->rchild==NULL)
return 0;
return preOrder(T->lchild)+preOrder(T->rchild)+1;
}
4、统计二叉树度为0的结点个数
#include <stdio.h>
int preOrder(BiTree T){
if(T==NULL)
return 0;
else if(T->lchild==NULL&&T->rchild==NULL)
return 1;
else
return preOrder(T->lchild)+preOrder(T->rchild);
}
(2)要么定义一个全局变量n
int n=0;
void preOrder(BiTree T){
if(T){
if(T->lchild==NULL&&T->rchild==NULL)
n++;
preOrder(T->lchild);
preOrder(T->rchild);
}
}
5、假设二叉树采用二叉链表存储结构,设计一个算法求二叉树的高度
#include <stdio.h>
/*
* 递归嘛,考虑两个条件:递归体和递归出口
步骤:
(1)如果树为空,那么返回0;
(2)如果树不为空,
递归该结点的左子树 --- 递归体
递归该结点的右子树 --- 递归体
返回子树最大高度+1(加1是因为还有根结点) --- 递归出口
*/
int BtDepth(BiTree T){
if(T==NULL)
return 0;
int ldep=BtDepth(T->lchild);
int rdep=BtDepth(T->rchild);
if(ldep>rdep)
return ldep+1;
else
return rdep+1;
}
6、统计二叉树的宽度
(1)递归
#include <stdio.h>
#define maxSize 5
/*
思想:
先求每一层宽度,并保存在数组a中;然后再比较数组a中的最大值即为宽度。
求每一层的宽度函数参数为(树,数组,深度)
- 数组是用来存储同一层的结点数(也就是每一层的宽度),
- 深度是用来代表递归的是哪一层(所以初始应该为1,从第一层开始)
*/
//求每一层的宽度
void levelWidth(BiTree T,int *a,int deep){
if(T){
a[deep]++;
levelWidth(T->lchild, a, deep+1);
levelWidth(T->rchild, a, deep+1)
}
}
//求树的宽度
int width(BiTree T){
int a[maxSize+1] , deep=1; //maxSize代表的就是树的深度(然后从1开始存储,所以需要加1)
for(int i = 0; i< maxSize+1; i++)
a[i] = 0;
levelWidth(T, a, deep);//求每一层的宽度并保存在数组a中
int maxWidth = 0;//保存树的宽度
for(int i = 0; i < maxSize + 1; i++){
if(maxWidth < a[i])
maxWidth = a[i];
}
return a[i];
}
7、从二叉树删除所有叶结点
#include <stdio.h>
/*
思想:
从上往下遍历,在先序遍历的基础上删除叶结点
步骤:
(1)若树为空,返回
(2)判断该节点的左孩子是否为叶结点,若是则将该结点的左孩子置空
(3)判断该节点的右孩子是否为叶结点,若是则将该结点的右孩子置空
(4)递归地删除左子树的叶结点
(5)递归地删除左子树的叶结点
*/
void Del(BiTree T){
BiTree p=T;
if(p==NULL){
return;
}else{
if(p->lnode->lnode==NULL&&p->lnode->rnode==NULL){
free(p->lnode);
T->lnode=NULL; //父结点的左孩子指针置空
}
if(p->rnode->lnode==NULL&&p->rnode->rnode==NULL){
free(p->rnode);
T->rnode=NULL; //父结点的右孩子指针置空
}
}
Del(T->lnode);
Del(T->rnode);
}
8、计算二叉树中各结点中的最大元素值
(1)定义一个全局变量记录最大值
int maxs=0;
void preOrder(BiTree T){
if(T){
if(T->ele>maxs)
maxs=T->ele;
preOrder(T->lnode);
preOrder(T->rnode);
}
}
(2)没有定义全局变量
int preOrder(BiTree T){
if(T){
int max1=preOrder(T->lnode);
int max2=preOrder(T->rnode);
int max = max1 > max2? max1 : max2;
return T->ele > max? T->ele : max;
}
}
9、交换二叉树中每个结点的两个子女
#include <stdio.h>
/*
步骤:
(1)先把结点b的左孩子的左右子树进行交换,
(2)再对结点b的右孩子的左右子树进行交换
(3)最后交换结点b的左右孩子
当结点为空时递归结束!!
思想:
乍一看是不是很眼熟,没错,其实就是递归版的后序遍历!!再后序遍历的基础上增加了交换结点而已。
*/
void swap(BiTree T){
if(T){
swap(T->lchild);//递归地交换左子树
swap(T->rchild);//递归地交换右子树
//下面就是交换左右孩子
BiTree temp=T->lchild;
T->lchild=T->rchild;
T->rchild=temp;
}
}