c语言想用括号表示法创建一个二叉树"A(B(D,E),C(F,G))"
但是不知道为什么运行代码元素C一直添加不进去,求解答
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
#include<math.h>
typedef char TreeDataType;
typedef struct TreeNode
{
TreeDataType data;
struct TreeNode* left;
struct TreeNode* right;
}TreeNode;
TreeNode* createTree(char* str, int* index);
TreeNode* createBinaryTree(char* str);
void PreOrder(TreeNode* root);
TreeNode* createTree(char* str, int* index)
{
if (str[*index] == '\0')
{
return NULL;
}
if (str[*index] == ')')
{
(*index)++;
return NULL;
}
TreeNode* newNode = (TreeNode*)malloc(sizeof(TreeNode));
newNode->data = str[*index];
newNode->left = NULL;
newNode->right = NULL;
(*index)++;
if (str[*index] == '(')
{
(*index)++;
newNode->left = createTree(str, index);
}
if (str[*index] == ',' || str[*index] == '(')
{
(*index)++;
newNode->right = createTree(str, index);
}
(*index)++;
return newNode;
}
TreeNode* createBinaryTree(char* str)
{
int index = 0;
return createTree(str, &index);
}
void PreOrder(TreeNode* root)
{
if (root == NULL)
{
return;
}
else
{
printf("%c ", root->data);
PreOrder(root->left);
PreOrder(root->right);
}
}
int main()
{
char str[] = "A(B(D,E),C(F,G))";
TreeNode* root = createBinaryTree(str);
PreOrder(root);
return 0;
}
按 TreeNode* createTree(char* str, int* index); 函数写法,构造字符串修改如下,改动处见注释,供参考:
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
#include<math.h>
typedef char TreeDataType;
typedef struct TreeNode
{
TreeDataType data;
struct TreeNode* left;
struct TreeNode* right;
}TreeNode;
TreeNode* createTree(char* str, int* index);
TreeNode* createBinaryTree(char* str);
void PreOrder(TreeNode* root);
TreeNode* createTree(char* str, int* index) //A(B(D),E)),C(F),G))
{
if (str[*index] == '\0')
{
return NULL;
}
if (str[*index] == ')')
{
(*index)++;
return NULL;
}
TreeNode* newNode = (TreeNode*)malloc(sizeof(TreeNode));
newNode->data = str[*index];
newNode->left = NULL;
newNode->right = NULL;
(*index)++;
if (str[*index] == '(')
{
(*index)++;
newNode->left = createTree(str, index);
}
if (str[*index] == ',') // || str[*index] == '(') 修改
{
(*index)++;
newNode->right = createTree(str, index);
}
(*index)++;
return newNode;
}
TreeNode* createBinaryTree(char* str)
{
int index = 0;
return createTree(str, &index);
}
void PreOrder(TreeNode* root)
{
if (root == NULL)
{
return;
}
else
{
printf("%c ", root->data);
PreOrder(root->left);
PreOrder(root->right);
}
}
void InOrder(TreeNode* root)
{
if (root == NULL)
return;
InOrder(root->left);
printf("%c ", root->data);
InOrder(root->right);
}
void PostOrder(TreeNode* root)
{
if (root == NULL)
return;
PostOrder(root->left);
PostOrder(root->right);
printf("%c ", root->data);
}
int main()
{
char str[] = "A(B(D),E)),C(F),G))"; // 修改
//char str[] = "A(B(D,E),C(F,G))";
TreeNode* root = createBinaryTree(str);
PreOrder(root); printf("\n");
InOrder(root); printf("\n");
PostOrder(root);
return 0;
}
该回答引用ChatGPT
从代码来看,问题出现在createTree函数的这两句:
c
if (str[*index] == ',' || str[*index] == '(')
{
(*index)++;
newNode->right = createTree(str, index);
}
这里判断右子树的条件是遇到','或者'(',但是实际上在字符串"A(B(D,E),C(F,G))"中,右子树C的开头是')',不满足这个判断条件,所以C一直添加不进去。
解决方法是:修改判断右子树的条件,增加')'的判断,修改为:
c
if (str[*index] == ',' || str[*index] == '(' || str[*index] == ')')
{
(*index)++;
newNode->right = createTree(str, index);
}
完整代码
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
#include<math.h>
typedef char TreeDataType;
typedef struct TreeNode
{
TreeDataType data;
struct TreeNode* left;
struct TreeNode* right;
}TreeNode;
TreeNode* createTree(char* str, int* index);
TreeNode* createBinaryTree(char* str);
void PreOrder(TreeNode* root);
void InOrder(TreeNode* root);
void PostOrder(TreeNode* root);
TreeNode* createTree(char* str, int* index)
{
if (str[*index] == '\0')
{
return NULL;
}
if (str[*index] == ')')
{
(*index)++;
return NULL;
}
TreeNode* newNode = (TreeNode*)malloc(sizeof(TreeNode));
newNode->data = str[*index];
newNode->left = NULL;
newNode->right = NULL;
(*index)++;
if (str[*index] == '(')
{
(*index)++;
newNode->left = createTree(str, index);
}
if (str[*index] == ',' || str[*index] == '(' || str[*index] == ')')
{
(*index)++;
newNode->right = createTree(str, index);
}
(*index)++;
return newNode;
}
TreeNode* createBinaryTree(char* str)
{
int index = 0;
return createTree(str, &index);
}
void PreOrder(TreeNode* root)
{
if (root == NULL)
{
return;
}
else
{
printf("%c ", root->data);
PreOrder(root->left);
PreOrder(root->right);
}
}
void InOrder(TreeNode* root)
{
if (root == NULL)
{
return;
}
else
{
InOrder(root->left);
printf("%c ", root->data);
InOrder(root->right);
}
}
void PostOrder(TreeNode* root)
{
if (root == NULL)
{
return;
}
else
{
PostOrder(root->left);
PostOrder(root->right);
printf("%c ", root->data);
}
}
int main()
{
char str[] = "A(B(D,E),C(F,G))";
TreeNode* root = createBinaryTree(str);
printf("先序遍历:");
PreOrder(root);
printf("\n");
printf("中序遍历:");
InOrder(root);
printf("\n");
printf("后序遍历:");
PostOrder(root);
printf("\n");
return 0;
}
运行结果:
先序遍历:A B D E C F G
中序遍历:D B E A F C G
后序遍历:D E B F G C A
问题在于当处理完左子树 B(D,E) 后,程序没有正确的处理逗号后面的 C(F,G)。
要解决这个问题,可以在创建二叉树的时候,先判断当前的字符是否为 ',',如果是的话,就将 index 值自增然后再处理接下来的字符。更改后的 createTree
函数的代码如下所示:
TreeNode* createTree(char* str, int* index)
{
if (str[*index] == '\0')
{
return NULL;
}
if (str[*index] == ')')
{
(*index)++;
return NULL;
}
TreeNode* newNode = (TreeNode*)malloc(sizeof(TreeNode));
newNode->data = str[*index];
newNode->left = NULL;
newNode->right = NULL;
(*index)++;
if (str[*index] == '(')
{
(*index)++;
newNode->left = createTree(str, index);
}
if (str[*index] == ',' || str[*index] == '(')
{
(*index)++;
newNode->right = createTree(str, index);
}
// 如果当前字符是逗号,则将 index 值自增
if (str[*index] == ',')
{
(*index)++;
}
(*index)++;
return newNode;
}
修改后的代码可以解决元素 C 无法添加的问题,将程序运行结果输出为 A B D E C F G
。