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

归并排序数组合并流程困惑及给定Pascal代码填空求助

归并排序数组合并逻辑解析及代码填空指导

正在学习归并排序的数组合并流程,需严格遵循给定的Pascal代码(该代码支持升序/降序排序)。目前已理解代码除填空外的大部分内容,包括Merge过程的初始合并逻辑,但对其中一个子数组遍历完成后剩余元素的处理逻辑,以及后续的代码填空部分完全困惑,请求解析该部分逻辑并指导完成填空。

待填空的原始代码

const
    max = 200000;
    MaxDisp = 20;
type
    list = array[1..max] of real;
var
  a: list;
  na: longint;
  is_asc:boolean;
procedure GenList(var L: list; n: longint);
  var
    i: longint;
  begin
    randomize;
    for i := 1 to n do begin
      L[i] := random;
    end;
  end;
procedure DispList(L: list; n: longint);
  var
    i: longint;
  begin
    for i := 1 to MaxDisp do begin
      if i <= n then begin
        writeln(i:10, ' - ', L[i]:0:10);
      end;
    end;
    if n > MaxDisp then begin
      writeln(n - MaxDisp, ' more ...');
    end;
  end;
procedure sort(var L: list; n: longint;is_asc:boolean);
    procedure Merge(L1,L2,R1,R2:longint);
    var
      M:list;//this is C
      i1,i2,i,j,num:longint;
    begin
        i1:=L1;
        i2:=L2;
        j:=1;
        while (i1<=R1) and (i2<=R2) do begin
            if (is_asc and (L[i1] <= L[i2])) or (not is_asc and (L[i1] >= L[i2])) then begin
                M[j]:=L[i1];
                j:=j+1;
                i1:=i1+1;
            end
            else begin
                M[j]:=L[i2];
                j:=j+1;
                i2:=i2+1;
            end;
        end;
        if(i1>R1) and (i2<=R2) then
            for i:=i2 to R2 do begin
                M[j]:=L[i];
                j:=j+1;
            end
        else if (i2>R2) and (i1<=R1) then
            for i:=i1 to R1 do begin
                M[j]:=L[i];
                j:=j+1;
            end;
        num:=R2 - L1 + 1;
        i:=L1;
        for j:=1 to num do begin
            L[i]:=M[j];
            i:=i+1;
        end
    end;
    procedure MSort(LL,RR:longint);
    var mid:integer;
    begin
        if LL<RR then begin
            mid:=(LL+RR) div 2;
            MSort(LL,mid);
            MSort(mid+1,RR);
            Merge(LL,mid,mid+1,RR);
        end
    end;
begin
    MSort(1,n);
end;
function is_sorted(L: list; n:longint;is_asc:boolean): boolean;
  var
    i: longint;
    flag: boolean;
  begin
    flag := true;
    i := 1;
    while flag and (i < n) do begin
      flag := ((L[i]<=L[i+1]) and (is_asc)) or (not(is_asc) and (L[i]>=L[i+1]));
      i := i + 1;
    end;
    is_sorted := flag;
  end;

begin
  na := MaxDisp;
  GenList(a, na);
  writeln(na, ' random items:');
  DispList(a, na);
  writeln('Press <Enter> to sort the list in ascending order ...');
  readln;
  is_asc := true;
  sort(a, na,is_asc);
  DispList(a, na);
  writeln('Sorted in ascending order: ', is_sorted(a, na,is_asc));
  write('Press <Enter> to continue ...');
  readln;
end.   

关键逻辑解析

剩余元素处理逻辑

归并排序的Merge过程负责将两个已排序的子数组(L[L1..R1]和L[L2..R2])合并到临时数组M中:

  1. 初始循环:同时遍历两个子数组,根据升序/降序规则选择较小(或较大)的元素放入M,直到其中一个子数组遍历完毕。
  2. 剩余元素处理:
    • 若第一个子数组(L1..R1)已遍历完,第二个子数组(L2..R2)剩余的元素本身就是有序的(因为子数组已经过排序),直接全部追加到M的末尾即可。
    • 反之,若第二个子数组已遍历完,将第一个子数组的剩余元素直接追加到M末尾。
      这一步不需要再做比较,因为剩余元素的顺序已经符合排序要求,且都大于(升序)或小于(降序)已经合并到M中的元素。

代码填空说明

  1. 冗余代码删除:原while循环内的j:=________;是多余的,因为每次循环中已经执行了j:=j+1,直接删除该行。
  2. 第一个剩余元素循环:for i:=i2 to R2 do —— 遍历第二个子数组的剩余元素;M[j]:=L[i]; j:=j+1; —— 将元素放入M并移动指针。
  3. 第二个剩余元素循环:for i:=i1 to R1 do —— 遍历第一个子数组的剩余元素;M[j]:=L[i]; j:=j+1; —— 同上。
  4. 总元素数计算:num:=R2 - L1 + 1 —— 合并的元素范围是从L1到R2,总数量为末尾索引减起始索引加1。
  5. 原数组复制:i:=L1 —— 从原数组的起始位置开始覆盖;L[i]:=M[j]; i:=i+1; —— 将临时数组M的有序元素复制回原数组L的对应位置。
  6. 额外修正:原代码的排序条件逻辑错误,将(is_asc and (L[i1]<L[i2])) or not is_asc and (L[i1]<L[i2])修正为(is_asc and (L[i1] <= L[i2])) or (not is_asc and (L[i1] >= L[i2])),否则升序/降序判断失效;同时补充num的变量声明,以及主程序中is_asc的赋值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 13:55:19