You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

COBOL冒泡排序仅对表末尾元素排序问题排查

问题分析与修正

你遇到的问题核心有两个,导致排序只完成了第一轮就停止了:

1. 内层循环的CNT2没有在外层循环迭代时重置

第一次内层循环结束后,CNT2已经被加到了6。之后每次进入外层循环时,PERFORM UNTIL CNT2>5的条件直接成立,内层循环完全不执行,自然不会继续排序剩下的元素。

2. 外层循环终止条件不合理

对于包含5个元素的数组,冒泡排序只需要4次外层循环(每轮把一个最大元素移到末尾,4轮后所有元素有序),而你的代码写的是PERFORM UNTIL CNT>6,会导致多余的循环迭代。

另外,你的当前逻辑其实更偏向选择排序(拿当前元素和后面所有元素比较交换),而非标准的冒泡排序(相邻元素两两比较,逐步把大元素“冒泡”到末尾)。如果目标是实现冒泡排序,我们可以调整逻辑;如果想保留类似选择排序的写法,也需要修正CNT2的重置问题。


修正后的冒泡排序代码

下面是符合标准冒泡排序逻辑的修正版本,我会标注关键修改点:

IDENTIFICATION DIVISION.
PROGRAM-ID. BubbleSort.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 TVAR PIC 9(4).
01 CNT PIC 9(1) VALUE 1.
01 CNT2 PIC 9(1) VALUE 1.
01 ARR.
05 ARRELEMENT PIC 9(4) OCCURS 5 TIMES.
01 TABLELENGTH PIC 9(1) VALUE 5.
01 SWAPPED-FLAG PIC X(1) VALUE 'N'.  // 新增:标记本轮是否有交换,优化冒泡排序
PROCEDURE DIVISION.
DISPLAY "Enter 5 numbers: ".
PERFORM INPUT-PARA VARYING CNT FROM 1 BY 1 UNTIL CNT>5.
DISPLAY "Pre Bubble-Sort: ".
PERFORM PRINT-PARA VARYING CNT FROM 1 BY 1 UNTIL CNT>5.
PERFORM BBLSORT-PARA.
DISPLAY "Post Bubble-Sort: ".
PERFORM PRINT-PARA VARYING CNT FROM 1 BY 1 UNTIL CNT>5.
STOP RUN.

INPUT-PARA.
ACCEPT ARRELEMENT(CNT).

PRINT-PARA.
DISPLAY "Table element: " ARRELEMENT(CNT).

BBLSORT-PARA.
    INITIALIZE CNT SWAPPED-FLAG.
    PERFORM UNTIL CNT >= TABLELENGTH OR SWAPPED-FLAG = 'N'
        MOVE 'N' TO SWAPPED-FLAG.  // 初始化为无交换
        PERFORM VARYING CNT2 FROM 1 BY 1 UNTIL CNT2 > TABLELENGTH - CNT
            IF ARRELEMENT(CNT2) > ARRELEMENT(CNT2 + 1) THEN
                DISPLAY ARRELEMENT(CNT2) " IS > " ARRELEMENT(CNT2 + 1)
                MOVE ARRELEMENT(CNT2) TO TVAR
                MOVE ARRELEMENT(CNT2 + 1) TO ARRELEMENT(CNT2)
                MOVE TVAR TO ARRELEMENT(CNT2 + 1)
                MOVE 'Y' TO SWAPPED-FLAG.  // 标记有交换
            END-IF
        END-PERFORM
        ADD 1 TO CNT GIVING CNT
    END-PERFORM.

END PROGRAM BubbleSort.

关键修改说明:

  • 新增SWAPPED-FLAG:如果某一轮没有发生任何交换,说明数组已经有序,可以提前终止排序,优化效率。
  • 外层循环条件改为UNTIL CNT >= TABLELENGTH OR SWAPPED-FLAG = 'N':既保证最多执行4次循环,又能提前结束。
  • 内层循环改为VARYING CNT2 FROM 1 BY 1 UNTIL CNT2 > TABLELENGTH - CNT:每完成一轮外层循环,末尾的CNT个元素已经有序,不需要再比较,减少不必要的迭代。
  • 内层循环比较相邻元素(CNT2和CNT2+1):这是标准冒泡排序的核心逻辑,每次把当前未排序部分的最大元素“冒泡”到末尾。

如果你想保留原逻辑(类似选择排序)

如果你的初衷是写选择排序(拿当前元素和后面所有元素比较,把最小元素放到当前位置),只需要修正CNT2的重置问题即可:

BBLSORT-PARA.
    INITIALIZE CNT.
    PERFORM UNTIL CNT >= TABLELENGTH
        MOVE CNT + 1 TO CNT2.  // 外层循环每次重置CNT2为当前位置的下一位
        PERFORM UNTIL CNT2 > TABLELENGTH
            IF ARRELEMENT(CNT) > ARRELEMENT(CNT2) THEN
                DISPLAY ARRELEMENT(CNT) " IS > " ARRELEMENT(CNT2)
                MOVE ARRELEMENT(CNT) TO TVAR
                MOVE ARRELEMENT(CNT2) TO ARRELEMENT(CNT)
                MOVE TVAR TO ARRELEMENT(CNT2)
            END-IF
            ADD 1 TO CNT2 GIVING CNT2
        END-PERFORM
        ADD 1 TO CNT GIVING CNT
    END-PERFORM.

这样修改后,输入5、4、3、2、1就能得到正确的升序结果1、2、3、4、5了。


内容的提问来源于stack exchange,提问作者Glycemic Beg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 15:57:29