C语言归并排序递归实现中如何正确获取当前调用实例ID
问题根因
你现有实现的核心问题是所有递归调用共享同一个全局recursion变量:子递归执行时会持续修改这个全局变量的值,当子递归返回上层调用时,全局变量已经被子调用累加为更大的数值,上层调用后续打印日志时读取的是被篡改后的全局值,自然无法显示自身原本的调用ID。
修复方法
核心思路是把「全局ID生成计数器」和「当前调用实例的ID存储」解耦:
- 保留一个全局变量仅做ID自增计数,专门用来生成全局唯一的递增ID
- 每次进入
if (left < right)分支、分配到新ID后,立刻将ID存入当前函数的局部变量。C语言的局部变量存储在独立的调用栈帧上,每个递归调用实例都有自己的局部变量副本,子递归对全局计数器的修改完全不会影响当前栈帧内存储的自身ID,后续本实例的所有日志都读取这个局部变量即可。
修改后的可直接运行代码如下:
// 全局变量仅作为ID生成计数器,不存储当前调用实例的ID int recursion_id_counter = 0; void merge_sort_recursion(int arr[], int left, int right) { if (left < right) { // 分配新ID后立刻存入当前实例的局部变量,与全局计数器解耦 int current_id = ++recursion_id_counter; int mid = left + (right - left) / 2; printf("[%d] 🔴 NEW RECURSION ID\n", current_id); printf(" variables:\tleft: %d mid: %d right: %d\n", left, mid, right); printf("[%d] recursive LEFT \t\n", current_id); merge_sort_recursion(arr, left, mid); // 左递归返回后,current_id仍为当前实例的ID,不受子调用影响 printf("[%d] recursive RIGHT \t\n", current_id); merge_sort_recursion(arr, mid + 1, right); printf("[%d] recursive MERGE \t\n", current_id); merge_sorted_arrays(arr, left, mid, right); } }
实现原理
- 全局计数器
recursion_id_counter的唯一作用是生成不重复的递增ID,仅在进入新的有效递归分支(需要继续拆分排序区间)时自增,保证所有调用实例ID唯一 - 局部变量
current_id是每个递归调用实例私有的:函数被调用时系统会在栈上为该变量单独分配存储空间,存入当前分配的ID后,无论嵌套多少层子递归修改全局计数器,当前栈帧内的current_id值都不会被改动 - 子递归执行完成返回当前层后,代码读取的仍是当前层栈帧内存储的
current_id,打印右递归、合并操作日志时自然会显示当前层的正确ID,运行输出和你预期的结果完全一致。
内容的提问来源于stack exchange,提问作者Newbie
相关产品推荐
相关产品推荐

