1、链表结构代码
typedef struct Node
{
char data; //数据域
struct Node* Lchild, * Rchild; //左右孩子指针
}BTNode,*BTree;
2、创建二叉树
int CreateBTree(BTree* T)
{
char ch;
scanf("%c", &ch);
if (ch == '#')
*T = NULL;
else
{
*T = (BTree)malloc(sizeof(BTNode)); //动态申请内存
if (*T == NULL)
{
printf("内存申请失败\n");
return 0;
}
(*T)->data = ch; //生成根结点
CreateBTree(&(*T)->Lchild); //构造左子树
CreateBTree(&(*T)->Rchild); //构造右子树
}
return 1;
}
如需要创建图1的二叉树,就需要输入图二扩展二叉树的前序遍历:AB##C##;
3、销毁
void DestroyBTree(BTree* T)
{
if (*T) //双亲结点不为空
{
if ((*T)->Lchild) //左孩子不为空
DestroyBTree(&(*T)->Lchild); //销毁左孩子
if ((*T)->Rchild) //右孩子不为空
DestroyBTree(&(*T)->Rchild); //销毁右孩子
free(*T); //销毁双亲结点
*T = NULL; //双亲结点指空
}
}
4、先(前)序遍历
void PreOrderTraverse(BTree T)
{
if (T)
{
printf("%-5c", T->data); //输出双亲结点
PreOrderTraverse(T->Lchild); //遍历左孩子
PreOrderTraverse(T->Rchild); //遍历右孩子
}
}
5、中序遍历
void InOrderTraverse(BTree T)
{
if (T)
{
InOrderTraverse(T->Lchild); //遍历左孩子
printf("%-5c", T->data); //输出双亲结点
InOrderTraverse(T->Rchild); //遍历右孩子
}
}
6、后序遍历
void PostOrderTraverse(BTree T)
{
if (T)
{
PostOrderTraverse(T->Lchild); //遍历左孩子
PostOrderTraverse(T->Rchild); //遍历右孩子
printf("%-5c", T->data); //输出双亲结点
}
}
7、删除左子树
void DeLeftChild(BTree* T)
{
if (*T) //双亲结点非空
DestroyBTree(&((*T)->Lchild)); //销毁左子树
}
8、删除右子树
void DeRightChild(BTree* T)
{
if (*T)
DestroyBTree(&(*T)->Rchild);
}
9、二叉树的深度
int MaxDepth(BTree T) {
if (T == NULL) {
return 0; //返回值传给maxLeft或者maxRight
}
else {
int maxLeft = MaxDepth(T->Lchild); //maxLeft最终值是0
int maxRight = MaxDepth(T->Rchild); //maxRight最终值也是0
if (maxLeft > maxRight) {
return 1 + maxLeft; //返回双亲结点加上最深子树的深度
}
else {
return 1 + maxRight;
}
}
}
10、所有结点个数
int NodeCount(BTree T)
{
if (T == NULL)
return 0;
else
return NodeCount(T->Lchild) + NodeCount(T->Rchild) + 1; //返回双亲结点加上左子树和右子树的结点
}
11、度为1的结点个数
int Out1_Count(BTree T)
{
if (T == NULL) //空树
return 0;
if ((T->Lchild == NULL && T->Rchild != NULL) || (T->Lchild != NULL && T->Rchild == NULL)) //左右孩子有且只有一个
return Out1_Count(T->Lchild) + Out1_Count(T->Rchild) + 1; //返回双亲加上子树中度为1的结点
else
return Out1_Count(T->Lchild) + Out1_Count(T->Rchild); //左右孩子都存在,双亲结点出度为二,返回子树
}
12、叶子结点个数
int LeafCount(BTree T)
{
if (T == NULL) //空树
return 0;
else if (T->Lchild ==NULL && T->Rchild == NULL) //非空树,但是无孩子
return 1;
else
return LeafCount(T->Lchild) + LeafCount(T->Rchild); //有左右孩子
}
13、交换二叉树的左右孩子
int ExchangeTree(BTree* T)
{
BTree temp;
if (*T == NULL) //空树
return 0;
else
{
temp = (*T)->Lchild; //1;swap 三步曲
(*T)->Lchild = (*T)->Rchild; //2
(*T)->Rchild = temp; //3
ExchangeTree(&(*T)->Lchild); //交换左子树
ExchangeTree(&(*T)->Rchild); //交换右子树
}
return 1;
}
测试
编译环境vc6.0
测试案例:AB#D##C##
所有代码如下:
/*
纯c语言,广泛使用二级指针,广泛使用递归思想
创建二叉树:以先序遍历创建二叉树,以"#"表示空结点
*/
#include <stdio.h>
#include <stdlib.h>
//*******************1、链表结点结构的定义*****************
typedef struct Node
{
char data; //数据域
struct Node* Lchild, * Rchild; //左右孩子指针
}BTNode,*BTree;
//******************2、按先序遍历创建二叉树*******************
int CreateBTree(BTree* T)
{
char ch;
scanf("%c", &ch);
if (ch == '#')
*T = NULL;
else
{
*T = (BTree)malloc(sizeof(BTNode)); //动态申请内存
if (*T == NULL)
{
printf("内存申请失败\n");
return 0;
}
(*T)->data = ch; //生成根结点
CreateBTree(&(*T)->Lchild); //构造左子树
CreateBTree(&(*T)->Rchild); //构造右子树
}
return 1;
}
//*************************3、销毁*****************
void DestroyBTree(BTree* T)
{
if (*T) //双亲结点不为空
{
if ((*T)->Lchild) //左孩子不为空
DestroyBTree(&(*T)->Lchild); //销毁左孩子
if ((*T)->Rchild) //右孩子不为空
DestroyBTree(&(*T)->Rchild); //销毁右孩子
free(*T); //销毁双亲结点
*T = NULL; //双亲结点指空
}
}
//******************4、先序遍历 根左右******************
void PreOrderTraverse(BTree T)
{
if (T)
{
printf("%-5c", T->data); //输出双亲结点
PreOrderTraverse(T->Lchild); //遍历左孩子
PreOrderTraverse(T->Rchild); //遍历右孩子
}
}
//******************5、中序遍历 左根右******************
void InOrderTraverse(BTree T)
{
if (T)
{
InOrderTraverse(T->Lchild); //遍历左孩子
printf("%-5c", T->data); //输出双亲结点
InOrderTraverse(T->Rchild); //遍历右孩子
}
}
//******************6、后续遍历 左右根******************
void PostOrderTraverse(BTree T)
{
if (T)
{
PostOrderTraverse(T->Lchild); //遍历左孩子
PostOrderTraverse(T->Rchild); //遍历右孩子
printf("%-5c", T->data); //输出双亲结点
}
}
//******************7、删除左子树******************
void DeLeftChild(BTree* T)
{
if (*T) //双亲结点非空
DestroyBTree(&((*T)->Lchild)); //销毁左子树
}
//******************8、删除右子树******************
void DeRightChild(BTree* T)
{
if (*T)
DestroyBTree(&(*T)->Rchild);
}
//*****************9、二叉树的深度*******************
int MaxDepth(BTree T) {
if (T == NULL) {
return 0; //返回值传给maxLeft或者maxRight
}
else {
int maxLeft = MaxDepth(T->Lchild); //maxLeft最终值是0
int maxRight = MaxDepth(T->Rchild); //maxRight最终值也是0
if (maxLeft > maxRight) {
return 1 + maxLeft; //返回双亲结点加上最深子树的深度
}
else {
return 1 + maxRight;
}
}
}
//*******************10、二叉树结点个数*****************
int NodeCount(BTree T)
{
if (T == NULL)
return 0;
else
return NodeCount(T->Lchild) + NodeCount(T->Rchild) + 1; //返回双亲结点加上左子树和右子树的结点
}
//*******************11、二叉树度为1的结点个数*****************
int Out1_Count(BTree T)
{
if (T == NULL) //空树
return 0;
if ((T->Lchild == NULL && T->Rchild != NULL) || (T->Lchild != NULL && T->Rchild == NULL)) //左右孩子有且只有一个
return Out1_Count(T->Lchild) + Out1_Count(T->Rchild) + 1; //返回双亲加上子树中度为1的结点
else
return Out1_Count(T->Lchild) + Out1_Count(T->Rchild); //左右孩子都存在,双亲结点出度为二,返回子树
}
//******************12、二叉树叶子结点个数******************
int LeafCount(BTree T)
{
if (T == NULL) //空树
return 0;
else if (T->Lchild ==NULL && T->Rchild == NULL) //非空树,但是无孩子
return 1;
else
return LeafCount(T->Lchild) + LeafCount(T->Rchild); //有左右孩子
}
//*****************13、交换二叉树的左右孩子*******************
int ExchangeTree(BTree* T)
{
BTree temp;
if (*T == NULL) //空树
return 0;
else
{
temp = (*T)->Lchild; //1;swap 三步曲
(*T)->Lchild = (*T)->Rchild; //2
(*T)->Rchild = temp; //3
ExchangeTree(&(*T)->Lchild); //交换左子树
ExchangeTree(&(*T)->Rchild); //交换右子树
}
return 1;
}
int main()
{
BTree T;
printf("输入待创建二叉树的先序序列:\n");
CreateBTree(&T);
printf("先序遍历\n");
PreOrderTraverse(T);
printf("\n中序遍历\n");
InOrderTraverse(T);
printf("\n后续遍历\n");
PostOrderTraverse(T);
printf("\n二叉树的深度为:%d",MaxDepth(T));
printf("\n结点个数为:%d", NodeCount(T));
printf("\n度为1的结点个数:%d", Out1_Count(T));
printf("\n叶子结点个数:%d", LeafCount(T));
DeLeftChild(&T);
printf("\n删除左子树后二叉树的结点个数为:%d\n", NodeCount(T));
return 0;
}
测试结果: