为何我的minimax算法无法正确找出二叉树中的最大值?
问题分析与修复
你的代码核心错误出在minimax函数的返回逻辑上:当比较左右子树的最大值后,你错误地返回了当前节点的左/右子节点,而非左右子树中实际包含最大值的节点。此外还有一处明显笔误,导致逻辑完全偏离预期。
具体错误点
- 返回对象错误:比如判断
minimax(root->left)->value > minimax(root->right)->value时,你返回的是root->left,但root->left的最大值可能存在于它的深层子节点中(比如你的树里,n7的左子节点n8值为999,是整个树的最大值,但如果返回n7就完全错了),正确做法应该返回minimax(root->left)这个递归结果。 - 笔误导致逻辑错误:第二个条件判断中,你写的是
return root->left,但这里逻辑是右子树最大值更大,应该返回右子树的递归结果。 - 重复递归调用:多次重复调用
minimax(root->left)和minimax(root->right),既降低效率,还可能引发不必要的重复计算,应该先将结果缓存到变量中。
修正后的代码
#include <stdio.h> #include <stdlib.h> // Struct for every node: typedef struct treenode { int value; struct treenode *left; struct treenode *right; } treenode; // Prototypes: treenode *createNode(int value); treenode *minimax(treenode *root); int main() { // Create the nodes: treenode *n1 = createNode(0); treenode *n2 = createNode(2); treenode *n3 = createNode(3); treenode *n4 = createNode(200); treenode *n5 = createNode(5); treenode *n6 = createNode(102); treenode *n7 = createNode(101); treenode *n8 = createNode(999); treenode *n9 = createNode(888); // Link them together: n1->left = n2; n1->right = n3; n3->left = n4; n3->right = n5; n5->left = n6; n5->right = n7; n7->left = n8; n7->right = n9; // Print the output of minimax(): printf("%d", minimax(n1)->value); // Free the nodes: free(n1); free(n2); free(n3); free(n4); free(n5); free(n6); free(n7); free(n8); free(n9); return 0; } // Creates a new node in the tree, that isn't linked to anything: treenode *createNode(int value) { treenode *result = malloc(sizeof(treenode)); if (result != NULL) { result->left = NULL; result->right = NULL; result->value = value; } return result; } // The minimax() function is recursive: treenode *minimax(treenode *root) { // 空节点处理(防御性编程,避免空指针访问) if (root == NULL) return NULL; // 如果是叶子节点,返回自身 if (root->left == NULL && root->right == NULL) return root; // 缓存左右子树的最大值节点,避免重复递归 treenode *left_max = minimax(root->left); treenode *right_max = minimax(root->right); // 只有左子树的情况 if (left_max != NULL && right_max == NULL) return left_max; // 只有右子树的情况 if (right_max != NULL && left_max == NULL) return right_max; // 比较左右子树的最大值,返回对应节点 if (left_max->value > right_max->value) return left_max; else return right_max; // 若需要相等时返回左节点,可修改为else返回left_max }
修复说明
- 新增空节点判断,避免递归过程中出现空指针访问问题。
- 用
left_max和right_max缓存递归结果,减少重复计算,同时让逻辑更清晰。 - 修正返回逻辑:直接返回左右子树中包含最大值的节点,而非当前节点的子节点。
- 简化条件判断,合并相等情况的处理(若需要相等时返回左节点,调整最后一个分支即可)。
运行修正后的代码,会正确输出999。
内容的提问来源于stack exchange,提问作者PilkeySEK
相关产品推荐
相关产品推荐

