トピック
バイナリツリーの構築とトラバース
トピックの要件
例
答え
方法 1、
まずバイナリ ツリーを構築し、それを順番に走査します。
実装のアイデア
指定された文字列に従ってバイナリ ツリーを作成し、最初に文字列内の文字を順番に参照します。「#」ではない文字が見つかった場合は、ノードの値をこの文字に割り当て、次に 2 つの新しいノードを作成します。はそれぞれノードの左の子と右の子であり、メソッドを再帰的に呼び出して左の子と右の子に同じ操作を実行させます。# 文字が見つかった場合は、ノード ヒープの最上位の値を # に割り当て、関数を直接終了します。つまり、ノードの左右の子ノードは作成されません。
時間の複雑さと空間の複雑さ
コード
#include <stdio.h>
#include <stdlib.h>
typedef char BTDataType;
//定义二叉树的结点
typedef struct BinaryTreeNode
{
BTDataType data;
struct BinaryTreeNode* left;
struct BinaryTreeNode* right;
}BTNode;
void CreateBinaryTree(BTNode* root, char** arr)
{
//如果**arr为'\0',则说明字符串已经结束
if (*(*arr) == '\0')
{
return;
}
//如果**arr不为#,就将该结点的值为**arr,同时让(*arr)++
//此时arr里面存的还是*arr的地址,但是(*arr)++后,*arr中存的地址已经为字符串中下一个字符的地址。
if (*(*arr) != '#')
{
root->data = *(*arr);
(*arr)++;
}
//如果**arr为#,就将该结点的值为#,然后同样将*arr中存的地址向后移一位。
else
{
root->data=*(*arr);
(*arr)++;
return;
}
//如果该结点不为空结点,就创建两个结点,来当作该结点的左右孩子。
BTNode* left = (BTNode*)malloc(sizeof(BTNode));
BTNode* right = (BTNode*)malloc(sizeof(BTNode));
root->left = left;
root->right = right;
//然后递归使该结点的左右孩子完成上述同样操作。
CreateBinaryTree(root->left, arr);
CreateBinaryTree(root->right, arr);
}
void InOrder(BTNode* root)
{
//如果root结点的值为#,就说明该结点为空结点,不需要打印,直接退出函数
if (root->data=='#')
{
return;
}
//先遍历该结点的左子树
InOrder(root->left);
//然后再打印该节点的值
printf("%c ", root->data);
//然后再遍历该结点的右子树
InOrder(root->right);
}
int main() {
char arr[100] = {
0 };
scanf("%s", arr);
//创建二叉树的根节点
BTNode* bt = (BTNode*)malloc(sizeof(BTNode));
//将字符串中第一个字符的地址赋值给pa
char* pa = &arr[0];
//将指针pa的地址赋给ppa,即ppa为二级指针,通过*ppa就可以得到pa,即得到字符串中第一个字符的地址。
//当*ppa+1时,即*ppa+1指向字符串的第二个字符的地址,所以可以通过*ppa++来访问字符串的每个字符
char** ppa = &pa;
//将二叉树根节点和ppa当作实参
CreateBinaryTree(bt, ppa);
InOrder(bt);
return 0;
}
方法 2、
最初の方法よりも簡潔でわかりやすい
実装のアイデア
最初の方法と同様に、バイナリ ツリーは最初に指定された事前順序走査の順序で作成され、その後、順序どおりの走査が実行されます。
時間の複雑さと空間の複雑さ
コード
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef char BTDataType;
//定义二叉树的结点
typedef struct BinaryTreeNode
{
BTDataType data;
struct BinaryTreeNode* left;
struct BinaryTreeNode* right;
}BTNode;
//创建一个二叉树结点并返回
BTNode* BuyBTNode(BTDataType x)
{
BTNode* newNode = (BTNode*)malloc(sizeof(BTNode));
newNode->data=x;
newNode->left=NULL;
newNode->right=NULL;
return newNode;
}
BTNode* CreateBinaryTree(char* arr,int* count)
{
//如果现在访问的字符为#,则说明该结点为NULL,让(*count)++,即访问下一个字符,然后返回NULL
if(arr[*count]=='#')
{
(*count)++;
return NULL;
}
//如果现在访问的字符不为#,将该字符存入到新创建的结点中,
BTNode* root = BuyBTNode(arr[(*count)++]);
//然后再将该结点的左孩子和右孩子递归调用该函数
//如果该结点有左孩子,则会返回创建的新结点
//如果该结点没有左孩子,则会返回NULL
root->left = CreateBinaryTree(arr, count);
root->right = CreateBinaryTree(arr, count);
//然后将根结点返回
return root;
}
void InOrder(BTNode* root)
{
if(root==NULL)
{
return ;
}
InOrder(root->left);
printf("%c ",root->data);
InOrder(root->right);
}
int main()
{
char arr[100]={
0};
scanf("%s",arr);
int count = 0;
//CreateBinaryTree函数会返回创建的二叉树的根节点
BTNode* bt = CreateBinaryTree(arr, &count);
InOrder(bt);
}