如何用C语言实现从栈中移除奇数?
栈中移除奇数的实现修正
你的代码核心问题出在oddnumbers函数的逻辑上,执行pop操作后aux指针未同步更新,导致后续访问已释放内存或指针错位,最终程序行为异常。下面给出两种可行的修正方案:
方案一:使用临时栈(直观易理解)
利用栈的后进先出特性,先将原栈中的偶数暂存到临时栈,再将临时栈的元素导回原栈,既保留原栈顺序,又移除所有奇数。
void oddnumbers(stack* p) { stack* temp_stack = create(); // 遍历原栈,弹出元素并筛选偶数存入临时栈 while (!empty(p)) { int val = pop(p); if (val % 2 == 0) { push(temp_stack, val); } } // 将临时栈的元素导回原栈,恢复原顺序 while (!empty(temp_stack)) { push(p, pop(temp_stack)); } freestack(temp_stack); // 释放临时栈内存 }
方案二:直接操作原栈链表(无额外空间)
通过跟踪当前节点和前一个节点,直接在原链表上删除奇数节点,无需额外栈空间,效率更高:
void oddnumbers(stack* p) { node *current = p->top; node *prev = NULL; while (current != NULL) { if (current->info % 2 != 0) { // 检测到奇数节点 node *temp = current; if (prev == NULL) { // 当前节点是栈顶 p->top = current->prox; } else { // 当前节点是中间节点 prev->prox = current->prox; } current = current->prox; free(temp); // 释放奇数节点内存 } else { // 偶数节点,移动指针继续遍历 prev = current; current = current->prox; } } }
原代码错误分析
原oddnumbers函数的问题:
- 执行
pop(p)后,栈顶指针p->top已更新,但aux仍指向被释放的原栈顶节点,后续访问aux->info或aux->prox属于非法内存操作,会导致程序崩溃或输出异常。 - 循环依赖
!empty(p),但aux的移动和栈顶变化完全脱节,无法正确遍历所有节点。
替换上述任意一种方案后,你的测试用例(push元素为72、31、98、21、45、10)最终会输出剩余偶数:10、98、72。
内容的提问来源于stack exchange,提问作者Kaua Marques
相关产品推荐
相关产品推荐

