DFS:108. Convert Sorted Array to Binary Search Tree

把一个排序的数组建成一个平衡的BST。既然是平衡的,就想到从中间位置开始建立根节点,然后左子树根节点又是左边一半的中间位置,右子树根节点又是右边一半的中间位置。很明显用递归可以解决。我的代码:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* sortedArrayToBST(vector<int>& nums) {
        if(nums.size() == 0)
            return NULL;
        return getBST(nums, 0, nums.size()-1);
    }
    TreeNode* getBST(vector<int>& nums, int start, int end)
    {
        if(start > end)
        {
            return NULL;
        }
        else
        {
            int mid = (start + end) / 2;
            TreeNode* newtree = new TreeNode(nums[mid]);
            newtree->left = getBST(nums, start, mid - 1);
            newtree->right = getBST(nums, mid + 1, end);
            return newtree;
        }
        
    }
};


<think> 问题分析: 用户反馈程序不健壮,具体体现在: 1. 当输入非整数时(如浮点数2.1, 3.8),程序错误地将其转换为整数(2和3),且未给出错误提示 2. 当输入字母(a,b,c,d)时,程序错误地转换为0,同样未提示错误 根本原因: - 使用了`atoi`和`atof`函数处理输入,这些函数无法检测转换失败 - `atoi`在转换失败时返回0,且没有错误反馈机制 解决方案: 1. 使用健壮的输入转换函数(如`strtol`/`strtof`)替代`atoi`/`atof` 2. 添加输入验证机制,检测转换失败情况 3. 对字符输入提供更严格的过滤(例如只接受单字符输入) 改进步骤: 步骤1:重构整数解析函数 ```c #include <errno.h> // 错误检测 static U1 u1_s_main_parse_int_array(ST_DA_ARRAY *stp_a_arr) { U1 u1_t_main_buffer[BUFFER_SIZE]; S4 s4_t_main_value; U1 *u1p_t_main_token; U1 u1_t_main_valid = TRUE; // 输入有效性标志 printf("Enter integers separated by spaces: "); fgets((S1 *)u1_t_main_buffer, BUFFER_SIZE, stdin); u1p_t_main_token = (U1 *)strtok((S1 *)u1_t_main_buffer, " "); while (u1p_t_main_token != NULL) { char *u1p_t_main_endptr; errno = 0; // 重置错误码 long l_t_main_val = strtol((S1 *)u1p_t_main_token, &u1p_t_main_endptr, 10); /* 验证转换结果 */ if (u1p_t_main_endptr == u1p_t_main_token) { fprintf(stderr, "错误:'%s' 不是有效数字\n", u1p_t_main_token); u1_t_main_valid = FALSE; } else if (errno == ERANGE) { fprintf(stderr, "错误:'%s' 超出范围\n", u1p_t_main_token); u1_t_main_valid = FALSE; } else if (*u1p_t_main_endptr != '\0') { fprintf(stderr, "错误:'%s' 包含非法字符\n", u1p_t_main_token); u1_t_main_valid = FALSE; } else if (l_t_main_val < INT_MIN || l_t_main_val > INT_MAX) { fprintf(stderr, "错误:%ld 超出int范围\n", l_t_main_val); u1_t_main_valid = FALSE; } else { s4_t_main_value = (S4)l_t_main_val; v_g_da_push_back(stp_a_arr, &s4_t_main_value); } u1p_t_main_token = (U1 *)strtok(NULL, " "); } return u1_t_main_valid; } ``` 步骤2:重构浮点数解析函数(类似原理) ```c static U1 u1_s_main_parse_float_array(ST_DA_ARRAY *stp_a_arr) { // ...类似整数解析的实现,使用strtof // 注意:浮点数不需要范围检查(除非需要特殊范围限制) } ``` 步骤3:重构字符解析函数 ```c static U1 u1_s_main_parse_char_array(ST_DA_ARRAY *stp_a_arr) { // 仅接受单个字符输入,跳过空格等 printf("Enter single characters without spaces: "); // ...逐字符检查输入,忽略空格和换行 } ``` 步骤4:修改主程序流程 ```c // 在主程序switch块中: case 1: // ...初始化操作 if (!u1_s_main_parse_int_array(&st_t_main_array)) { v_g_da_free(&st_t_main_array); printf("输入错误,请重试\n"); continue; // 跳过后续处理 } break; ``` 步骤5:输入缓冲区清理 ```c // 在scanf后添加更健壮的输入清理 int s4_t_main_scan_result = scanf("%d", &s4_t_main_choice); if (s4_t_main_scan_result != 1) { // 清除错误输入 while (getchar() != '\n'); printf("无效选择,请重新输入\n"); continue; } getchar(); // 清理换行符(原逻辑) ``` 改进后效果: 1. 无效输入会得到明确错误提示 2. 程序不会将非法输入加入数组 3. 用户有机会重新输入 §§相关问题§§: 1. C语言中`strtol`函数相比`atoi`有哪些安全优势? 2. 如何处理浮点数比较时的精度误差问题? 3. 在动态内存分配中,为什么推荐使用倍增扩容策略而不是固定增量? 4. 如何设计函数指针接口来实现更通用的算法(如排序/搜索)? </think> ### 问题分析 您提供的程序运行结果显示出严重的健壮性问题,主要体现在: 1. **类型转换漏洞**:整数模式下输入浮点数(如2.1)被截断为整数 2. **输入验证缺失**:字母输入(如a,b,c,d)被错误转换为0 3. **错误处理缺失**:未对无效输入进行提示或恢复 4. **浮点数处理缺陷**:整数模式下浮点输入被静默截断 ### 根本原因分析 #### 1. 输入解析漏洞 ```c // 整数解析函数中的脆弱代码 u1p_t_main_token = (U1 *)strtok((S1 *)u1_t_main_buffer, " "); while (u1p_t_main_token != NULL) { s4_t_main_value = atoi((S1 *)u1p_t_main_token); // 脆弱点:无法检测转换失败 v_g_da_push_back(stp_a_arr, &s4_t_main_value); } ``` **问题**:`atoi()`函数在转换失败时返回0且不设置错误标志,导致: - 浮点数被截断(2.1 → 2) - 非数字输入被静默转为0(a → 0) #### 2. 类型选择逻辑缺陷 ```c switch (s4_t_main_choice) { case 1: // 整数模式 vfp_t_main_parse_array = v_s_main_parse_int_array; break; // ... } ``` **问题**:未限制输入模式与数据类型的匹配,允许在整数模式下输入浮点数和字符 #### 3. 错误处理机制缺失 程序中没有任何错误处理代码,导致: - 无效输入未被检测 - 用户未收到错误反馈 - 程序状态未重置 --- ### 解决方案(增强程序健壮性) #### 1. 实现安全的输入解析函数 ```c #include <ctype.h> // 添加字符检测函数 #include <errno.h> // 添加错误检测 /* 安全整数解析 */ static U1 u1_s_main_safe_parse_int(const U1 *u1p_input, S4 *s4p_output) { char *endptr; errno = 0; // 重置错误状态 long l_value = strtol((const char *)u1p_input, &endptr, 10); // 错误检测链 if (errno == ERANGE) { fprintf(stderr, "错误:数值超出范围\n"); return FALSE; } if (endptr == u1p_input) { fprintf(stderr, "错误:'%s' 不是有效数字\n", u1p_input); return FALSE; } if (*endptr != '\0' && !isspace(*endptr)) { fprintf(stderr, "错误:'%s' 包含非法字符\n", u1p_input); return FALSE; } *s4p_output = (S4)l_value; return TRUE; } ``` #### 2. 重构数组解析函数 ```c static U1 u1_s_main_parse_int_array(ST_DA_ARRAY *stp_a_arr) { U1 u1_t_main_buffer[BUFFER_SIZE]; S4 s4_t_main_value; U1 *u1p_t_main_token; U1 u1_t_main_valid = TRUE; // 有效性标志 printf("Enter integers separated by spaces: "); fgets((S1 *)u1_t_main_buffer, BUFFER_SIZE, stdin); u1p_t_main_token = (U1 *)strtok((S1 *)u1_t_main_buffer, " "); while (u1p_t_main_token != NULL) { if (!u1_s_main_safe_parse_int(u1p_t_main_token, &s4_t_main_value)) { u1_t_main_valid = FALSE; // 标记错误 } else { v_g_da_push_back(stp_a_arr, &s4_t_main_value); } u1p_t_main_token = (U1 *)strtok(NULL, " "); } return u1_t_main_valid; } ``` #### 3. 增强主循环错误处理 ```c // 在switch之后添加: U1 u1_t_main_input_valid = vfp_t_main_parse_array(&st_t_main_array); if (!u1_t_main_input_valid || st_t_main_array.u4_s_size == 0) { fprintf(stderr, "输入错误!请重新选择选项\n"); v_g_da_free(&st_t_main_array); continue; // 跳过后续处理 } ``` #### 4. 添加输入缓冲区清理 ```c // 在scanf之后添加输入验证 if (s4_t_main_choice < 1 || s4_t_main_choice > 4) { // 清理输入缓冲区 int c; while ((c = getchar()) != '\n' && c != EOF); fprintf(stderr, "无效选择!请输入1-4的数字\n"); continue; } ``` --- ### 改进后预期效果 ```text ===== Dynamic Array Program ===== 1. Integer Sorting and Binary Search 2. Float Sorting and Binary Search 3. Character Sorting and Binary Search 4. Exit Program Please select an option (1-4): 1 Enter integers separated by spaces: 2.1 5 abc 错误:'2.1' 包含非法字符 错误:'abc' 不是有效数字 输入错误!请重新选择选项 ===== Dynamic Array Program ===== 1. Integer Sorting and Binary Search 2. Float Sorting and Binary Search 3. Character Sorting and Binary Search 4. Exit Program Please select an option (1-4): 2 Enter floating-point numbers: 3.14 2.5 7.8 ... [正常处理浮点数] ... ``` ### 健壮性设计要点总结 1. **防御性输入解析** - 使用`strtol`替代`atoi` - 检查转换结束符位置 - 处理数值范围错误(ERANGE) 2. **状态管理** - 添加输入有效性标志位 - 错误时重置程序状态 - 提供清晰的错误恢复路径 3. **用户反馈** - 针对不同错误类型提供特定错误消息 - 保持错误消息格式一致 - 避免静默失败 4. **资源管理** - 错误时立即释放已分配内存 - 确保程序状态可回滚
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值