(一) 实现功能:
1:初始化 2:显示(Map.txt) 3:先序遍历(递归法) 4中序遍历(递归法) 5:后序遍历 (递归法) 6:统计叶子结点数目 7:二叉树深度 8:左右子树交换 9:生成二叉排序树 a:查找排序树中的结点 b:删除排序树中的结点 c:先序遍历(非递归法) d:层次遍历 e:凹入法表示二叉树 f:广义表表示二叉树
(二) 二叉树操作
1、创建。
2、用递归方法分别先序、中序、后序遍历以Tree为根指针的二叉树。
3、编写递归算法,计算二叉树中叶子结点的数目。
4、编写递归算法,计算二叉树的深度。
5、编写递归算法,将二叉树中所有结点的左、右子树相互交换。
6、使用数组elem中的随机数序列(以0表示结束,不包括0),生成以Tree为根指针的二叉排序树。
7、在以Tree为根指针的二叉排序树中查找结点。
8、从以Tree为根指针的二叉排序树中删除结点(适用各种位置的结点)。
9、用非递归算法,先序遍历以Tree为根指针的二叉树。
提示:用数组 BiTNode *stack[max] 构成堆栈,利用这个堆栈实现功能。
10、对以Tree为根指针的二叉树,从根结点开始,逐层从左到右输出各结点的数据。
提示:用数组 BiTNode *queue[max] 构成队列,利用这个队列实现功能
11、用凹入表示法的表示以Tree为根指针的二叉树,例如:
// 324
// 123
// 746
// 690
// 567
12、用广义表表示以Tree为根指针的二叉树,例如
//(324(123(746,690),567))
提高题:
13*、根据Huffman编码原理,使用数组elem中的随机数序列(以0表示结束,不包括0)作为结点的权重,生成赫夫曼树,以及赫夫曼编码,计算平均带权径长度。
14*、(1)随机生成二叉树。(2)生成并保存先(后)序、中序输出序列。(3)按照保存的一对输出序列恢复出二叉树。(4)生成先(后)序输出序列。
二叉树操作菜单如下:
Tips:
程序缺陷:赫夫曼树功能未实现
凹入表示法可以同叶子节点一起输出
功能2只能在32位电脑正常显示,64位可能会有偏差,可使用word查看
一些个人感想:
在写二叉树时,对树林转换成哈夫曼树时,返回树结点的地址时会刷新整棵树的地址,导致错误,思考后认为可以加一个父节点,解决地址混乱问题,但由于时间有限,未来得及实现。在编写删除二叉排序树的结点时,原想采用调用函数重新生成一颗排序树,但发现在某些条件下,左右子树会发生偏移,思考良久,决定按照书上思想,用寻找右子树的最小元素进行代替的策略,完成此函数功能。
程序所包含文件格式 (注意包含文件所在位置,以免报错!)
#include"BinT.h"//读取BinT.h文件
BinT.h文件完整如下:
//屏幕提示后,从键盘输入个数和随机数种子,在数组elem中生成指定个数的数据,供其他程序使用,0表示数据结束
void init0(int list[])
{
int i, n;
while (1)
{
cout << "输入数据个数(0-" << max - 1 << "):" << flush;
cin >> n;
if (n >= 0 && n <= max - 1)
break;
cout << endl;
}
while (1)
{
cout << "输入随机数种子(0-32767):" << flush;
cin >> i;
if (i >= 0 && i <= 32767)
break;
cout << endl;
}
srand(i); //指定随机数种子,相同的种子将产生相同的数据序列
rand();
for (i = 0; i < n; i++)
{
list[i] = rand() % 999 + 1;
}
list[n] = 0;
}
void getWidth(BiTNode *Tree, int depth, int shift, char map[max * 2][max * 2])
{
int i;
if (Tree->left != NULL)
{
getWidth(Tree->left, depth + 1, shift, map);
Tree->tem1 = Tree->left->tem1 + Tree->left->tem2 + 1;
for (i = (Tree->left->tem1 + shift) * 2; i < shift * 2; i = i + 2)
{
map[depth * 2 + 1][i] = '-';
map[depth * 2 + 1][i + 1] = '-';
}
}
else
Tree->tem1 = 0;
if (Tree->right != NULL)
{
getWidth(Tree->right, depth + 1, shift + Tree->tem1 + 1, map);
Tree->tem2 = Tree->right->tem1 + Tree->right->tem2 + 1;
}
else
Tree->tem2 = 0;
for (i = shift * 2; i < (Tree->tem1 + shift) * 2; i++)
map[depth * 2][i] = ' ';
map[depth * 2][(Tree->tem1 + shift) * 2] = (char)(Tree->data / 1000 + 48);
map[depth * 2][(Tree->tem1 + shift) * 2 + 1] = (char)(Tree->data / 100 % 10 + 48);
map[depth * 2][(Tree->tem1 + shift) * 2 + 2] = (char)(Tree->data / 10 % 10 + 48);
map[depth * 2][(Tree->tem1 + shift) * 2 + 3] = (char)(Tree->data % 10 + 48);
if (Tree->data < 1000)
{
map[depth * 2][(Tree->tem1 + shift) * 2] = ' ';
if (Tree->data < 100)
{
map[depth * 2][(Tree->tem1 + shift) * 2 + 1] = map[depth * 2][(Tree->tem1 + shift) * 2 + 2];
map[depth * 2][(Tree->tem1 + shift) * 2 + 2] = map[depth * 2][(Tree->tem1 + shift) * 2 + 3];
map[depth * 2][(Tree->tem1 + shift) * 2 + 3] = ' ';
if (Tree->data < 10)
map[depth * 2][(Tree->tem1 + shift) * 2 + 1] = ' ';
}
}
if (Tree->left != NULL)
{
map[depth * 2 + 1][(Tree->left->tem1 + shift) * 2 + 1] = (char)0xa9;
map[depth * 2 + 1][(Tree->left->tem1 + shift) * 2 + 2] = (char)0xb0;
map[depth * 2 + 1][(Tree->tem1 + shift) * 2 + 1] = (char)0xa9;
map[depth * 2 + 1][(Tree->tem1 + shift) * 2 + 2] = (char)0xbc;
for (i = (Tree->left->tem1 + shift) * 2 + 3; i < (Tree->tem1 + shift) * 2; i = i + 2)
{
map[depth * 2 + 1][i] = (char)0xa9;
map[depth * 2 + 1][i + 1] = (char)0xa4;
}
}
if (Tree->right != NULL)
{
map[depth * 2 + 1][(Tree->tem1 + shift) * 2 + 1] = (char)0xa9;
map[depth * 2 + 1][(Tree->tem1 + shift) * 2 + 2] = (char)0xb8;
map[depth * 2 + 1][(Tree->tem1 + Tree->right->tem1 + shift) * 2 + 3] = (char)0xa9;
map[depth * 2 + 1][(Tree->tem1 + Tree->right->tem1 + shift) * 2 + 4] = (char)0xb4;
for (i = (Tree->tem1 + shift) * 2 + 3; i < (Tree->tem1 + Tree->right->tem1 + shift) * 2 + 2; i = i + 2)
{
map[depth * 2 + 1][i] = (char)0xa9;
map[depth * 2 + 1][i + 1] = (char)0xa4;
}
}
if (Tree->left != NULL && Tree->right != NULL)
{
map[depth * 2 + 1][(Tree->tem1 + shift) * 2 + 1] = (char)0xa9;
map[depth * 2 + 1][(Tree->tem1 + shift) * 2 + 2] = (char)0xd8;
}
}
//生成文件Map.txt,显示以Tree为根指针的二叉树
void showBinTree(BiTNode *Tree)
{
char map[max * 2][max * 2];
FILE *f;
int i, j, k;
f = fopen("Map.txt", "w");
if (Tree == NULL)
{
fprintf(f, "空树");
fclose(f);
return;
}
for (i = 0; i < max * 2; i++)
for (j = 0; j < max * 2; j++)
map[i][j] = ' ';
getWidth(Tree, 0, 0, map);
for (i = 0; i < max * 2; i++)
{
k = max * 2 - 1;
while (k >= 0 && map[i][k] == ' ')
k--;
for (j = 0; j <= k; j++)
fprintf(f, "%c", map[i][j]);
fprintf(f, "\n");
// if (k<0)
// break;
}
fclose(f);
}
//供init1O调用的释放函数
void release(BiTNode *Tree)
{
if (Tree == NULL)
return;
release(Tree->left);
release(Tree->right);
free(Tree);
}
//供init1调用的生成函数
BiTNode *Generate(int n)
{
int nl;
if (n == 0)
return NULL;
BiTNode *P = new BiTNode;
P->data = rand() % 999 + 1;
nl = rand() % (n);
P->left = Generate(nl);
P->right = Generate(n - 1 - nl);
return P;
}
//屏幕提示后,从键盘输入个数和随机数种子,以Tree为根指针,生成指定结点个数的二叉树,供其他程序使用,同时生成文件Map.txt,显示这课二叉树
BiTNode *init1()
{
int i, n;
while (1)
{
cout << "输入数据个数(0-" << max - 1 << "):" << flush;
cin >> n;
if (n >= 0 && n <= max - 1)
break;
cout << endl;
}
while (1)
{
cout << "输入随机数种子(0-32767):" << flush;
cin >> i;
if (i >= 0 && i <= 32767)
break;
cout << endl;
}
srand(i); //指定随机数种子,相同的种子将产生相同的数据序列
rand();
// release(Tree);
return Generate(n);
}
//公用的等待函数
void wait()
{
cout << "\n\n请按任意键继续" << flush;
getch();
}
//选择排序
void simpleSort(int list[])
{
int i,j,k,temp;
for(i=0;list[i]!=0;i++)
{
k=i;
for(j=i+1;list[j]!=0;j++)
if(list[j]<list[k])
k=j;
if(k!=i)
{
temp=list[i];
list[i]=list[j];
list[j]=temp;
}
}
}
//插入指定结点
BiTNode *insertChild(BiTNode *Tree,int child)
{
if(Tree==NULL)
{
BiTNode *Tree=new BiTNode;
Tree->data=child;
Tree->left=NULL;
Tree->right=NULL;
return Tree;
}
else if(child>Tree->data)
Tree->right=insertChild(Tree->right,child);
else
Tree->left=insertChild(Tree->left,child);
return Tree;
}
//查找指定结点
BiTNode *search(BiTNode *Tree,int elem)
{
if(Tree==NULL)
return NULL;
if(elem==Tree->data)
return Tree;
else if(elem>Tree->data)
return search(Tree->right,elem);
else
return search(Tree->left,elem);
}
//删除最小结点
BiTNode *FindMin(BiTNode *Tree)
{
if(!Tree)
return NULL;
else if(!Tree->left)
return Tree;
else
return FindMin(Tree->left);
}
//删除指定结点
BiTNode *Delete(BiTNode *Tree,int delElem)
{
BiTNode *temp;
if(!Tree)
return NULL;
else
{
if(delElem<Tree->data)
Tree->left=Delete(Tree->left,delElem);
else if(delElem>Tree->data)
Tree->right=Delete(Tree->right,delElem);
else
{
if(Tree->left&&Tree->right)
{
temp=FindMin(Tree->right);
Tree->data=temp->data;
Tree->right=Delete(Tree->right,Tree->data);
}
else
{
temp=Tree;
if(!Tree->left)
Tree=Tree->right;
else
Tree=Tree->left;
free(temp);
}
}
}
return Tree;
}
BiTNode *minElem(BiTNode *Elem[],int length)
{
BiTNode *min=new BiTNode;
min=Elem[0];
for(int i=0;i<length;i++)
{
if(Elem[i]->data<min->data)
min=Elem[i];
}
return min;
}
void deleteMin(int length,int minElem)
{
for(int i=0;i<length;i++)
{
if(minElem==Elem[i]->data)
{
for(int j=i;j<length-1;j++)
elem[j]=elem[j+1];
return;
}
}
}
//根据中序和后序数组中的n个结点建树
BiTNode *buildTree(int in[],int post[],int n)
{
BiTNode *tree;
int i;
if(!n)
return NULL;//空树
tree=new BiTNode;
tree->data=post[n-1]; //根结点是后序最后一个
tree->left=tree->right=NULL;
for(i=0;i<n;i++) //在中序里找根结点
{
if(in[i]==post[n-1])
break;
}
tree->left=buildTree(in,post,i);
tree->right=buildTree(in+i+1,post+i,n-i-1);
return tree;
}
//先序-文件
void PreOrderTraversePrintf(BiTNode *Tree,FILE *&f)
{
if(Tree==NULL)
return;
fprintf(f, "%-5d ", Tree->data);
PreOrderTraversePrintf(Tree->left,f);
PreOrderTraversePrintf(Tree->right,f);
}
//中序-文件
void InOrderTraversePrintf(BiTNode *Tree,FILE *&f)
{
if(Tree==NULL)
return;
InOrderTraversePrintf(Tree->left,f);
fprintf(f,"%-5d ",Tree->data);
InOrderTraversePrintf(Tree->right,f);
}
//后序-文件
void PostOrderTraversePrintf(BiTNode *Tree,FILE *&f)
{
if(Tree==NULL)
return;
PostOrderTraversePrintf(Tree->left,f);
PostOrderTraversePrintf(Tree->right,f);
fprintf(f,"%-5d ",Tree->data);
}
void GetWidth(BiTNode *Tree, int depth, int shift, char map[max*2][max*2])
{
int i;
if (Tree->left != NULL)
{
GetWidth(Tree->left, depth+1, shift, map);
Tree->tem1 = Tree->left->tem1 + Tree->left->tem2 + 1;
for (i=(Tree->left->tem1+shift)*2; i<shift*2; i=i+2)
{
map[depth*2+1][i]='-';
map[depth*2+1][i+1]='-';
}
}
else Tree->tem1 = 0;
if (Tree->right != NULL)
{
GetWidth(Tree->right, depth+1, shift+Tree->tem1+1, map);
Tree->tem2 = Tree->right->tem1 + Tree->right->tem2 + 1;
}
else Tree->tem2 = 0;
for (i=shift*2; i<(Tree->tem1+shift)*2; i++)
map[depth*2][i]=' ';
map[depth*2][(Tree->tem1+shift)*2]=(char)(Tree->data / 1000 +48);
map[depth*2][(Tree->tem1+shift)*2+1]=(char)(Tree->data / 100 % 10 +48);
map[depth*2][(Tree->tem1+shift)*2+2]=(char)(Tree->data / 10 % 10 +48);
map[depth*2][(Tree->tem1+shift)*2+3]=(char)(Tree->data %10 +48);
if (Tree->data<1000)
{
map[depth*2][(Tree->tem1+shift)*2]=' ';
if (Tree->data<100)
{
map[depth*2][(Tree->tem1+shift)*2+1]=map[depth*2][(Tree->tem1+shift)*2+2];
map[depth*2][(Tree->tem1+shift)*2+2]=map[depth*2][(Tree->tem1+shift)*2+3];
map[depth*2][(Tree->tem1+shift)*2+3]=' ';
if (Tree->data<10)
map[depth*2][(Tree->tem1+shift)*2+1]=' ';
}
}
if (Tree->left != NULL)
{
map[depth*2+1][(Tree->left->tem1+shift)*2+1]=(char)0xa9;
map[depth*2+1][(Tree->left->tem1+shift)*2+2]=(char)0xb0;
map[depth*2+1][(Tree->tem1+shift)*2+1]=(char)0xa9;
map[depth*2+1][(Tree->tem1+shift)*2+2]=(char)0xbc;
for (i=(Tree->left->tem1+shift)*2+3; i<(Tree->tem1+shift)*2; i=i+2)
{
map[depth*2+1][i]=(char)0xa9;
map[depth*2+1][i+1]=(char)0xa4;
}
}
if (Tree->right != NULL)
{
map[depth*2+1][(Tree->tem1+shift)*2+1]=(char)0xa9;
map[depth*2+1][(Tree->tem1+shift)*2+2]=(char)0xb8;
map[depth*2+1][(Tree->tem1+Tree->right->tem1+shift)*2+3]=(char)0xa9;
map[depth*2+1][(Tree->tem1+Tree->right->tem1+shift)*2+4]=(char)0xb4;
for (i=(Tree->tem1+shift)*2+3; i<(Tree->tem1+Tree->right->tem1+shift)*2+2; i=i+2)
{
map[depth*2+1][i]=(char)0xa9;
map[depth*2+1][i+1]=(char)0xa4;
}
}
if (Tree->left != NULL && Tree->right != NULL)
{
map[depth*2+1][(Tree->tem1+shift)*2+1]=(char)0xa9;
map[depth*2+1][(Tree->tem1+shift)*2+2]=(char)0xd8;
}
}
void ShowBinTree(BiTNode *Tree)
{
char map[max * 2][max * 2];
FILE *f;
int i, j, k;
//f = fopen("Map.txt", "w");
if (Tree == NULL)
{
printf("空树");
//fclose(f);
return;
}
for (i = 0; i < max * 2; i++)
for (j = 0; j < max * 2; j++)
map[i][j] = ' ';
GetWidth(Tree, 0, 0, map);
for (i = 0; i < max * 2; i++)
{
k = max * 2 - 1;
while (k >= 0 && map[i][k] == ' ')
k--;
for (j = 0; j <= k; j++)
printf("%c", map[i][j]);
printf("\n");
// if (k<0)
// break;
}
//fclose(f);
}
二叉树完整代码如下:
/*
源文件名:P5.cpp
功能:二叉树操作
*/
#include <iostream>
#include <iomanip>
#include <conio.h>
#include <stdio.h>
#include <process.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <Windows.h>
#include <math.h>
using namespace std;
struct BiTNode //二叉树结点类型
{
int data; //数据
int tem1,tem2; //辅助数据(实习题不用)
BiTNode *left; //左子树指针
BiTNode *right; //右子树指针
};
BiTNode *Tree; //本程序操作的二叉树根指针
#define max 100
int elem[max]; //存放原始数据
int leafSum=0;//叶子节点数
BiTNode *Elem[max];
int length;//数组长度
int pre[max],in[max],post[max];//先、中、后遍历生成数组
#include"BinT.h"//读取BinT.h文件
//从键盘输入个数和随机数种子,在数组elem中生成指定个数的数据,供其他程序使用,0表示数据结束
void init0(int list[]);
//在本程序所在的位置生成文本文件Map.txt,其中显示以Tree为根指针的二叉树
void showBinTree(BiTNode *Tree);
//从键盘输入个数和随机数种子,以Tree为根指针,生成指定结点个数的二叉树,供其他程序使用。同时生成文件Map.txt,显示这课二叉树
BiTNode *init1();
//公用的等待函数
void wait();
//选择排序
void simpleSort(int list[]);
//插入指定结点
BiTNode *insertChild(BiTNode *Tree,int child);
//查找指定结点
BiTNode *search(BiTNode *Tree,int elem);
//删除指定结点
BiTNode *Delete(BiTNode *Tree,int delElem);
//删除最小结点
BiTNode *FindMin(BiTNode *Tree);
//展示函数
void ShowBinTree(BiTNode *Tree);
//先序-文件
void PreOrderTraversePrintf(BiTNode *Tree,FILE *&f);
//中序-文件
void InOrderTraversePrintf(BiTNode *Tree,FILE *&f);
//后序-文件
void PostOrderTraversePrintf(BiTNode *Tree,FILE *&f);
//根据中序和后序数组中的n个结点建树
BiTNode *buildTree(int in[],int post[],int n);
void PreOrderTraverse(BiTNode *Tree);//先序
void InOrderTraverse(BiTNode *Tree);//中序
void PostOrderTraverse(BiTNode *Tree);//后序
void leafCount(BiTNode *Tree);//叶子节点
int treeDeep(BiTNode *Tree);//深度
void changeTree(BiTNode *tree);//左右子树交换
void createBinaryTree();//生成二叉排序树
void searchElem(BiTNode *Tree);//在以Tree为根指针的二叉排序树中查找结点
void deleteNode();//从以Tree为根指针的二叉排序树中删除结点(适用各种位置的结点)
void PreOrderTraverse2(BiTNode *Tree,int flag);//先序-非递归
void InOrderTraverse2(BiTNode *Tree,int flag);//中序-非递归
void PostOrderTraverse2(BiTNode *Tree,int flag);//后序-非递归
void levelOrderTraverse(BiTNode *Tree);//层次遍历
void showTreeByTab(BiTNode *Tree,int count);//用缩入格式的多行文本表示以Tree为根指针的二叉树
void showTreeBylist(BiTNode *Tree);//用广义表表示以Tree为根指针的二叉树
void Huffman();//哈夫曼树
void binaryTree();//生成随机二叉树,保存到文件,再恢复
//主函数,显示功能菜单(包括生成二叉树、显示二叉树),键盘选择后执行对应功能
int main()
{
char choice;
while (1)
{
system("cls");
printf("\n\n\n\n");
printf("\t\t 二叉树的操作 \n");
printf("\t\t======================================");
printf("\n\n");
printf("\t\t 1:初始化 \n");
printf("\t\t 2:显示(Map.txt) \n");
printf("\t\t 3:先序遍历(递归法) \n");
printf("\t\t 4:中序遍历(递归法) \n");
printf("\t\t 5:后序遍历(递归法) \n");
printf("\t\t 6:统计叶子节点数目 \n");
printf("\t\t 7:二叉树深度 \n");
printf("\t\t 8:左右子树交换 \n");
printf("\n");
printf("\t\t 9:生成二叉排序树 \n");
printf("\t\t a:查找排序树中的结点 \n");
printf("\t\t b:删除排序树中的结点 \n");
printf("\n");
printf("\t\t c:先序遍历(非递归法)及中后非递归遍历 \n");
printf("\t\t d:层次遍历 \n");
printf("\t\t e:凹入法表示二叉树 \n");
printf("\t\t f:广义表表示二叉树 \n");
printf("\t\t g:程序内显示二叉树 \n");
printf("\t\t h:(未完成)使用数组elem中的随机数序列生成赫夫曼树,以及赫夫曼编码,计算平均带权径长度\n");
printf("\t\t i:生成随机二叉树,保存到文件,再恢复\n");
printf("\n");
printf("\t\t 0:退出 \n");
printf("\n");
printf("\n");
printf("\t\t请选择:");
choice = getch();
system("cls");
switch(choice)
{
case '1':
Tree=init1();
wait();
break;
case '2':
showBinTree(Tree);
printf("保存成功!\n");
wait();
break;
case '3':
printf("先序遍历结果:\n\t\t");
PreOrderTraverse(Tree);
wait();
break;
case '4':
printf("中序遍历结果:\n\t\t");
InOrderTraverse(Tree);
wait();
break;
case '5':
printf("后序遍历结果:\n\t\t");
PostOrderTraverse(Tree);
wait();
break;
case '6':
leafCount(Tree);
printf("叶子节点数目为:%d\n",leafSum);
leafSum=0;
wait();
break;
case '7':
printf("二叉树的深度为:%d\n",treeDeep(Tree));
wait();
break;
case '8':
changeTree(Tree);
printf("交换成功!\n");
wait();
break;
case '9':
createBinaryTree();
wait();
break;
case 'a':
searchElem(Tree);
wait();
break;
case 'b':
deleteNode();
wait();
break;
case 'c':
printf("先序遍历结果(非递归):\n\t\t");
PreOrderTraverse2(Tree,1);
printf("\n中序遍历结果(非递归):\n\t\t");
InOrderTraverse2(Tree,1);
printf("\n后序遍历结果(非递归):\n\t\t");
PostOrderTraverse2(Tree,1);
wait();
break;
case 'd':
printf("层次遍历结果:\n\t\t");
levelOrderTraverse(Tree);
wait();
break;
case 'e':
showTreeByTab(Tree,0);
wait();
break;
case 'f':
showTreeBylist(Tree);
wait();
break;
case 'g':
ShowBinTree(Tree);
wait();
break;
case 'h':
Huffman();
wait();
break;
case 'i':
binaryTree();
wait();
break;
case '0':
exit(0);
}
}
return 0;
}
//先序、中序、后序遍历以Tree为根指针的二叉树 递归法
//先序
void PreOrderTraverse(BiTNode *Tree)
{
if(Tree==NULL)
return;
printf("%-5d ",Tree->data);
PreOrderTraverse(Tree->left);
PreOrderTraverse(Tree->right);
}
//中序
void InOrderTraverse(BiTNode *Tree)
{
if(Tree==NULL)
return;
InOrderTraverse(Tree->left);
printf("%-5d",Tree->data);
InOrderTraverse(Tree->right);
}
//后序
void PostOrderTraverse(BiTNode *Tree)
{
if(Tree==NULL)
return;
PostOrderTraverse(Tree->left);
PostOrderTraverse(Tree->right);
printf("%-5d",Tree->data);
}
//统计叶子节点数目
void leafCount(BiTNode *Tree)//先序
{if (Tree == NULL)
return;
if (Tree->left == NULL && Tree->right == NULL)
{
leafSum++;
return;
}
leafCount(Tree->left);
leafCount(Tree->right);
}
//二叉树深度
int treeDeep(BiTNode *Tree)
{
int leftDeep,rightDeep;
if(Tree==NULL)
return 0;
leftDeep=treeDeep(Tree->left);
rightDeep=treeDeep(Tree->right);
if(leftDeep<rightDeep)
return rightDeep+1;
else
return leftDeep+1;
}
//左右子树交换
void changeTree(BiTNode *Tree)
{
BiTNode *temp;
if(Tree!=NULL)
{
temp=Tree->left;
Tree->left=Tree->right;
Tree->right=temp;
changeTree(Tree->left);
changeTree(Tree->right);
}
}
//使用数组elem中的随机数序列(以0表示结束,不包括0),生成以Tree为根指针的二叉排序树
/*
二叉排序树:
若它的左子树不为空,则左子树上所有结点的值均小于它的根结点的值;
若它的右子树不为空,则右子树上所有结点的值均大于它的根结点的值;
它的左、右子树分别为二叉排序树。
*/
void createBinaryTree()//生成二叉排序树
{
init0(elem);
Tree=NULL;
for(int i=0;elem[i]!=0;i++)
Tree=insertChild(Tree,elem[i]);
}
//在以Tree为根指针的二叉排序树中查找结点
void searchElem(BiTNode *Tree)
{
int elem;
BiTNode *tree;
printf("请输入要查找结点:");
scanf("%-5d",&elem);
if(Tree==NULL)
{
printf("查找失败,此树为空!");
}
else
tree=search(Tree,elem);
if(tree==NULL)
{
printf("查找失败,无此元素!");
return;
}
printf("此树为\n");
InOrderTraverse(Tree);
printf("\n查找成功!\n");
printf("元素为:%d\n",elem);
}
//从以Tree为根指针的二叉排序树中删除结点(适用各种位置的结点)
void deleteNode()
{
if(Tree==NULL)
{
printf("查找失败,此树为空!");
return;
}
int elem;
BiTNode *tree;
printf("请输入要删除结点:");
scanf("%d",&elem);
tree=search(Tree,elem);
if(tree==NULL)
{
printf("查找失败,无此元素!");
return;
}
else
{
printf("删除前:\n");
InOrderTraverse(Tree);
Tree=Delete(Tree,elem);
printf("\n删除结点成功!\n");
printf("删除后:\n");
InOrderTraverse(Tree);
}
}
//https://www.cnblogs.com/greedyco/p/7182555.html
//用非递归算法,先序遍历以Tree为根指针的二叉树。
//提示:用数组 BiTNode *stack[max] 构成堆栈,利用这个堆栈实现功能。
//后进先出
void PreOrderTraverse2(BiTNode *Tree,int flag) //flag=1:打印 flag=2:进数组
{
BiTNode *stack[max];
int top=-1;
BiTNode *p;
if(flag==2)
length=-1;
if(Tree!=NULL)
{
top++;
stack[top]=Tree;//先将根结点压栈
while(top>-1) //栈不为空时循环
{
p=stack[top]; // 栈顶元素出栈
top--;
if(flag==1)
printf("%-5d",p->data); // 访问栈顶元素
else
{
length++;
pre[length]=p->data;//数组记录
}
if(p->right!=NULL) // 如果右孩子不为空,则进栈
{
top++;
stack[top]=p->right;
}
if(p->left!=NULL) // 如果左孩子不为空,则进栈
{
top++;
stack[top]=p->left;
}
}
}
else
printf("此树为空!\n");
}
//中序-非递归(左根右)
void InOrderTraverse2(BiTNode *Tree,int flag) //flag=1:打印 flag=2:进数组
{
if(flag==2)
length=-1;
BiTNode *stack[max];
BiTNode *p;
int top = -1;
if (Tree != NULL)
{
p = Tree;
while (top > -1 || p != NULL)
{
while (p != NULL) // while循环将根结点的最左结点全部压栈
{
top++;
stack[top] = p;
p = p->left;
}
if (top > -1) // 当结点p没有最左结点时出栈
{
p = stack[top];
if(flag==1)
printf("%-5d", p->data); // 访问结点p
else
{
length++;
in[length]=p->data;//数组记录
}
top--;
p = p->right; // 转向处理右孩子结点
}
}
}
}
//后序-非递归(左右根)
void PostOrderTraverse2(BiTNode *Tree,int flag) //flag=1:打印 flag=2:进数组
{
if(flag==2)
length=-1;
BiTNode *stack[max];
BiTNode *p;
int top = -1;
bool visited = false;
BiTNode *pre = NULL;
if (Tree != NULL)
{
// 1)初始化,根入栈
stack[++top] = Tree;
// 2)循环执行,直至栈空
while (top != -1)
{
//读取栈顶结点,不出栈
p = stack[top];
if (p->left == NULL || visited)
{
visited = false;
//栈顶结点有右子树 且 右子树未被访问:右子树入栈
if (p->right != NULL && p->right != pre)
{
stack[++top] = p->right;
//栈顶结点无右子树、栈顶结点有右子树 且 右子树已被访问:
//该结点出栈并访问之
}
else if (p->right == NULL || (p->right != NULL && p->right == pre))
{
//出栈栈顶元素,并访问
top--;
if(flag==1)
printf("%-5d", p->data);
else
{
length++;
post[length]=p->data;//数组记录
}
//更新pre
pre = p;
visited = true;
}
}
else
{ //有左孩子,左孩子入栈
stack[++top] = p->left;
}
}
}
}
//对以Tree为根指针的二叉树,从根结点开始,逐层从左到右输出各结点的数据。
//提示:用数组 BiTNode *queue[max] 构成队列,利用这个队列实现功能。
//先进先出
void levelOrderTraverse(BiTNode *Tree)
{
BiTNode *queue[max];
BiTNode *p;
int front=0,rear=0;//front和rear表示队首和队尾的指针
if(Tree!=NULL) //若树为空
{
rear++;
queue[rear]=Tree;
while(front!=rear) //当队列非空
{
front++;
p=queue[front];//队首元素出队列,并访问这个节点
printf("%-5d",p->data);
if(p->left!=NULL) //若左子树非空,则入队列
{
rear++;
queue[rear]=p->left;
}
if(p->right!=NULL) //若右子树非空,则入队列
{
rear++;
queue[rear]=p->right;
}
}
}
else
printf("此树为空!\n");
}
//*用缩入格式的多行文本表示以Tree为根指针的二叉树,例如:
// 324
// 123
// 746
// 690
// 567
void showTreeByTab(BiTNode *Tree,int count)
{
for(int j=0;j<count;j++)
printf("\t");
if(Tree==NULL)
{
printf("空\n");
return;
}
printf("%d\n",Tree->data);
if(Tree->right==NULL&&Tree->left==NULL)//叶子节点
return;
//左
showTreeByTab(Tree->left,count+1);
//右
showTreeByTab(Tree->right,count+1);
}
//用广义表表示以Tree为根指针的二叉树,例如
// (324(123(746,690),567))
//*用广义表表示以Tree为根指针的二叉树,例如
// (324(123(746()())(690()()))(567()()))
void showTreeBylist(BiTNode *Tree)
{
if(Tree!=NULL)
{
printf("%d",Tree->data);
if(Tree->left!=NULL||Tree->right!=NULL)
{
printf("(");
showTreeBylist(Tree->left);
printf(",");
showTreeBylist(Tree->right);
printf(")");
}
}
}
/*
根据Huffman编码原理,使用数组elem中的随机数序列(以0表示结束,不包括0)
作为结点的权重,生成赫夫曼树,以及赫夫曼编码,计算平均带权径长度。
*/
void Huffman()
{
// BiTNode
// //int i;
// for(i=0;elem[i]!=0;i++)
// {
// }
printf("Now Programming. . .\n");
}
/*
1、随机生成二叉树。
2、生成并保存先(后)序、中序输出序列。
3、按照保存的一对输出序列恢复出二叉树。
4、生成先(后)序、中序输出序列。
5、比较两对输出序列。
*/
void binaryTree()
{
Tree=NULL;
Tree=init1();
FILE *f=NULL;
f = fopen("Tree.txt", "w");
fprintf(f, "先序:");
PreOrderTraversePrintf(Tree,f);
fprintf(f, "\n中序:");
InOrderTraversePrintf(Tree,f);
fprintf(f, "\n后序:");
PostOrderTraversePrintf(Tree,f);
fprintf(f, "\n______________________________________________________________________\n");
InOrderTraverse2(Tree,2);
PostOrderTraverse2(Tree,2);
int n=length+1;
Tree=buildTree(in,post,n);
fprintf(f, "新树:");
fprintf(f, "\n中序:");
InOrderTraversePrintf(Tree,f);
fprintf(f, "\n后序:");
PostOrderTraversePrintf(Tree,f);
fclose(f);
printf("\n保存成功!已按中序和后序生成新二叉树,生成文件为:Tree.txt。\n");
}