1.主な関数呼び出し
a。配列を使用してすべてのノードをバイナリツリーに格納し、それらをプレオーダートラバーサルメソッドに格納します(バイナリツリーは、以下で作成するときにプレオーダーメソッドで作成する必要があり、配列のストレージメソッドは作成時と同じ)空のノットポイントは#で表されます。main関数では、ルートノードを格納するためのポインタを定義するだけで済みます。ルートノードによると、二分木のすべてのノードにアクセスできます。
//主函数
int main(){
BTDataType str[]="ABD##E#H##CF##G##";
int num=0;
int k=0;
char x,Empty;
BTNode* root;
root=CreateBinaryTree(str,strlen(str),&num);
printf("层序遍历为:");
BinaryTreeLevelOrder(root);
printf("结点个数为:%d\n",BinaryTreeSize(root));
printf("叶子结点个数为:%d\n",BinaryTreeLeafSize(root));
printf("请输入k=");
scanf("%d",&k);
printf("第%d层节点的个数为:%d\n",k,BinaryTreeLevelKSize(root,k));
Empty=getchar();
printf("请输入x=");
scanf("%c",&x);
printf("以%c为根的树中总共有%d个节点\n",x,BinaryTreeSize(BinaryTreeFind(root,x)));
printf("二叉树的深度为:%d\n",BinaryTreeDepth(root));
printf("%d\n",BinaryTreeComplete(root));
BinaryTreeDestory(&root);
return 0;
}
2.二分木を作成します
a。1つ目は、二分木の確立です。再帰的な方法を使用して二分木を作成します。
構造タイプ:
typedef struct BinaryTreeNode{
BTDataType _data;//数据域
struct BinaryTreeNode* _left;//存储左孩子
struct BinaryTreeNode* _right;//存储右孩子
}BTNode;
プレオーダートラバーサルを使用してバイナリツリーを作成します。
b。ここで3つのパラメーターを見てみましょう。最初のパラメーターはバイナリツリーのノードを格納する配列であり、2番目のパラメーターは配列の長さであり、3番目のパラメーターは配列が終了したかどうかを判断するために使用されます。通常の変数を使用して再帰的に入力する第1層にある場合、変更も判断もできないため、変数のアドレスを渡して配列が終了したかどうかを判断します。
//通过前序遍历创建二叉树
BTNode* CreateBinaryTree(BTDataType* str,int n,int* pi){
if('#' == str[*pi]){//判出条件
return NULL;
}
if(*pi < n){//判断数组是否走完
BTNode* cur=(BTNode*)malloc(sizeof(BTNode));//为节点申请空间
cur->_data=str[*pi];//赋值
cur->_left=NULL;
cur->_right=NULL;
(*pi)++;
if(*pi < n){
cur->_left=CreateBinaryTree(str,n,pi);//创建左孩子
}
(*pi)++;
if(*pi < n){
cur->_right=CreateBinaryTree(str,n,pi);//创建右孩子
}
return cur;
}
return NULL;
}
3.二分木を破壊します
1. main関数でバイナリツリーを作成するときは、ポインタ変数を使用してルートノードを格納します。実際にはポインタを操作するため、バイナリツリーを破棄するときにポインタが指すスペースを解放するだけで済みます。関数内の変数であるため、そのアドレスを関数に渡す必要があります。したがって、ポインター変数のアドレスを関数に渡す必要があるため、ここでは第2レベルのポインターを使用します。
//二叉树的销毁
void BinaryTreeDestory(BTNode** root){
if(NULL==*root){
return;
}
free(*root);
*root=NULL;
}
4.二分木でノードの数を見つけます
a。再帰を使用して、バイナリツリー内のノードの数を計算します。空のノードに移動すると、0が返されます。空のノードでない場合は、左側の子ノードの数と右側の子ノードの数が返されます。独自のノードを追加します。
//二叉树的结点个数
int BinaryTreeSize(BTNode* root){
if(NULL==root){
return 0;
}
return BinaryTreeSize(root->_left)+BinaryTreeSize(root->_right)+1;
}
5.二分木のリーフノードの数を見つけます
a。再帰的にバイナリツリーのリーフノードの数を計算します。空のノードに移動すると、0が返されます。空でないノードであり、その左右の子ノードが空の場合、 nodeはリーフノードであり、直接1を返します。空でないノードであるがリーフノードではない場合は、左側のサブツリーのリーフノードの数と右側のサブツリーのリーフノードの数を返します。
//二叉树叶子结点个数
int BinaryTreeLeafSize(BTNode* root){
if(NULL==root){
return 0;
}
if(NULL==root->_left && NULL==root->_right){
return 1;
}
return BinaryTreeLeafSize(root->_left)+BinaryTreeLeafSize(root->_right);
}
6.二分木のk番目のレベルでノードの数を見つけます
a。再帰的方法を使用して、バイナリツリーのk番目の層のノード数を見つけます。したがって、パラメーターを渡すと、追加のパラメーターkがあり、空のノードに到達すると、0が返され、それを渡します。子ノードに移動するたびに、パラメータkが1つ減ると、kが0であることが検出されると、k番目の層が移動したことを意味します。このとき、ノードが空でない場合は、直接1を返します。ノードが空でもk番目のレイヤーでもない場合、ノードの左側のサブツリーのレベルkのノード数と、ノードの右側のサブツリーのレベルkのノード数を直接返します。
//二叉树第k层结点的个数
int BinaryTreeLevelKSize(BTNode* root,int k){
if(NULL==root){
return 0;
}
if(0==k){
return 1;
}
return BinaryTreeLevelKSize(root->_left,k-1)+BinaryTreeLevelKSize(root->_right,k-1);
}
7.二分木で値がxであるノードを見つけます
a。再帰的方法を使用して、値がxであるノードを見つけ、空のノードをトラバースすると空を返します。空のノードでない場合は、ノードの値がxであるかどうかを判断し、xである場合は、ノードを返します。直接(つまり、アルゴリズムは事前順序でトラバースされるため、xの値を持つ最初のノードのみが見つかります)、ノードが空のノードでもxの値を持つノードでもない場合は、直接左右のサブツリーで空でないノードを返します。ノード。
//二叉树查找值为x的节点
BTNode* BinaryTreeFind(BTNode* root,BTDataType x){
if(NULL==root){
return NULL;
}
if(x==root->_data){
return root;
}
BTNode* first=BinaryTreeFind(root->_left,x);
BTNode* second=BinaryTreeFind(root->_right,x);
if(NULL==first){
return second;
}
return first;
}
8.二分木の深さを見つけます
a。二分木の深さを再帰的に計算します。空のノードに移動すると、0が返されます。ノードが空のノードでない場合は、左側のサブツリーと右側のサブツリーの大きい方に独自のレベルを加えたものが返されます。
//求二叉树的深度
int BinaryTreeDepth(BTNode* root){
if(NULL==root){
return 0;
}
int Dep_1=BinaryTreeDepth(root->_left);
int Dep_2=BinaryTreeDepth(root->_right);
if(Dep_1>Dep_2){
return Dep_1+1;
}
return Dep_2+1;
}
9.二分木の注文前、注文後のトラバーサル
二分木(C言語)のプレオーダートラバーサル-プログラマーが求めた
二分木(C言語)のポストオーダートラバーサル-プログラマーが求めた
10.二分木のレベル順トラバーサル
a。再帰的な方法を使用して、二分木のレベル順序をトラバースします。このアルゴリズムは、k番目のレベルの要素数を見つけるのと似ています。パラメーターを渡すときは、追加のパラメーターiを渡してレベル数を判断します。ノードの子ノードの各トラバースポイントがクリックされると、iが1減算されます。iが0の場合、レイヤーは対応するレイヤーにトラバースされ、直接印刷されます。したがって、最初に二分木の高さnを見つけます。次に、ループを使用して0からnまでのパラメーターを渡し、最初の関数を呼び出します。各レイヤーのデータを印刷できます。
//二叉树的层序遍历
void BinaryTreeLevelOrder_1(BTNode* root,int i){
if(NULL==root){
return;
}
if(0==i){
printf("%c",root->_data);
return;
}
BinaryTreeLevelOrder_1(root->_left,i-1);
BinaryTreeLevelOrder_1(root->_right,i-1);
}
void BinaryTreeLevelOrder(BTNode* root){
if(NULL==root){
return;
}
int Dep_=BinaryTreeDepth(root);
int i;
for(i=0;i<Dep_;i++){
BinaryTreeLevelOrder_1(root,i);
}
printf("\n");
}
11.二分木が完全な二分木であるかどうかを判断します
a。バイナリツリーのノードは、レイヤー順トラバーサルによって保存されます。空のノードが検出されると、直接#として保存されます。保存後、配列はトラバースされて数が計算されます。#が検出されると、ノードの数が二分木の数と同じである場合、二分木は完全な二分木として1を返します(完全な二分木は遭遇しないことを知っておく必要があります)レイヤー順序トラバーサルを使用するときに最後のノードにトラバースする前に空のノード。このノードが検出された場合、ツリーは完全ではありません。バイナリツリー)、異なる場合、バイナリツリーは完全なバイナリツリーではなく、0を返します。
//判断二叉树是否是完全二叉树
void BinaryTreeComplete_1(BTNode* root,int i,BTDataType* arry,int* num){
if(NULL==root){
arry[(*num)++]='#';
return;
}
if(0==i){
arry[(*num)++]=root->_data;
return;
}
BinaryTreeComplete_1(root->_left,i-1,arry,num);
BinaryTreeComplete_1(root->_right,i-1,arry,num);
}
int BinaryTreeComplete(BTNode* root){
if(NULL==root){
printf("该节点为空!\n");
return -1;
}
BTDataType* arry=(BTDataType*)malloc(sizeof(BTDataType)*2*BinaryTreeSize(root));
if(NULL==arry){
printf("申请失败!\n");
return -1;
}
int i=0;
int count=0;
int num=0;
for(i=0;i<BinaryTreeDepth(root);i++){
BinaryTreeComplete_1(root,i,arry,&num);
}
while(arry[count] != '#'){
count++;
}
if(BinaryTreeSize(root)==count){
return 1;
}
return 0;
}