Delphi 快速排序

RAD Studio 10.3.3 测试√


快速排序思路:

1、快速排序是一种递归的写法
2、其中需要在待排序的数组中找到一个 基准值(可以是待排序数组中任意一个数,一般为了方便就取数组从左往右数的第一个数)
3、根据选定的 基准值 对数组中的其他数进行遍历比较,小于等于基准数的放在基准数的左边,大于基准数的放在基准数的右边
4、这里的遍历不是从头到尾的遍历,而是用两个变量,分别代表从左往右从右往左 的数组下标,依次往数组中心位置移动
5、先向前(从右往左)移动找到 小于等于 这个 基准值 的数,然后再向后(从左往右)找到 大于 这个 基准值 的数,然后将这个两个下标指向的数进行调换位置
6、在遍历寻找的过程中,一单两个下标相遇(指向同一个数),就可以结束遍历,将结束后将 基准值 填入到对应的位置
7、将分出来的基准数左边数组和基准数右边数组,分别再次进行上述的比较,知道左右两边的数组个数不足2个即为结束


快速排序思路 结果+代码:

结果:

在这里插入图片描述

代码:

var
  mArr: TArray<Integer>;
  a, i, j: Integer;
  mTempi: Integer;
begin
  GenerateRandomArray(mArr, 100, 5, True);
  Memo_Log.Lines.Add('============');
  ArrToMemo(mArr);

  // 数组的开始下标
  i := 0;
  // 数组的最后一位下标
  j := Length(mArr) - 1;
  a := mArr[i];
  Memo_Log.Lines.Add('本轮基准值=' + IntToStr(a));

 // 这里其实也需要判断一下数组的是否有2个及以上个数
  while j > i do
  begin
    // 首先从[j]开始向前(从右往左)找到一个 <= a 的数,将其放在[i]中
    while j > i do
    begin
      if mArr[j] <= a then
      begin
        mArr[i] := mArr[j];
        // 这里 i 进行 +1 是表示 mArr[i] 已经满足 <= a 本轮不用再次比较
        i := i + 1;
        ArrToMemo(mArr);
        Break;
      end;

      // 这里 j 进行 -1 是表示 mArr[j] 满足 > a 本轮不用再次比较
      j := j - 1;
    end;

    // 然后从[i]开始向后(从左往右)找到一个 > a 的数,将其放在[j]中
    while i < j do
    begin
      if mArr[i] > a then
      begin
        mArr[j] := mArr[i];
        // 这里 j 进行 -1 是表示 mArr[j] 已经满足 > a 本轮不用再次比较
        j := j - 1;
        ArrToMemo(mArr);
        Break;
      end;

      // 这里 i 进行 -1 是表示 mArr[i] 满足 <= a 本轮不用再次比较
      i := i + 1;
    end;

    // 上面的连个遍历就类似,找到一个 <= a 的数 和一个 > a 的数将它们进行调换位置,然后继续同上往中间找
    // 但其实写法是按照基准值提出来,作为一个空的坑位,然后有满足条件的就将这个数填入基准值的原始坑位,
    // 然后满足条件的那个原来的坑位又空出来了,就这样一直找一直填坑
  end;
  // 到这里出来的时候就是 i = j(相遇) 的时候,将基准值填入到空余的坑位
  mArr[i] := a;

  Memo_Log.Lines.Add('↓↓↓↓第一轮结果↓↓↓↓');
  ArrToMemo(mArr);

  // 这里是因为没有用递归,需要记录一下上一轮基准值最终坑位的下标,方便进行分开左右两边的数组
  mTempi := i;

  // 开始第二轮
  Memo_Log.Lines.Add('↓↓↓↓开始第二轮 左边的↓↓↓↓');

  // 第二轮左边数组开始的下标
  i := 0;
  // 第二轮左边数组结束的下标
  j := mTempi - 1;
  // 数组中个数不足2个不用排
  if j > i then
  begin
    a := mArr[i];
    Memo_Log.Lines.Add('本轮基准值=' + IntToStr(a));

    while j > i do
    begin
      // 首先从[j]开始向前(从右往左)找到一个 <= a 的数,将其放在[i]中
      while j > i do
      begin
        if mArr[j] <= a then
        begin
          mArr[i] := mArr[j];
          i := i + 1;
          ArrToMemo(mArr);
          Break;
        end;

        j := j - 1;
      end;

      // 然后从[i]开始向后(从左往右)找到一个 > a 的数,将其放在[j]中
      while i < j do
      begin
        if mArr[i] > a then
        begin
          mArr[j] := mArr[i];
          j := j - 1;
          ArrToMemo(mArr);
          Break;
        end;

        i := i + 1;
      end;
    end;
    // 到这里出来的时候就是 i = j 的时候
    mArr[i] := a;
    Memo_Log.Lines.Add('↓↓↓↓第二轮 左边的结果↓↓↓↓');
    ArrToMemo(mArr);
  end
  else
  begin
    Memo_Log.Lines.Add('第二轮 左边的数组长度不到2');
  end;


  // 开始第二轮
  Memo_Log.Lines.Add('↓↓↓↓开始第二轮 右边的↓↓↓↓');

  // 第二轮右边数组开始的下标
  i := mTempi + 1;
  // 第二轮右边数组结束的下标
  j := Length(mArr) - 1;
  if j > i then
  begin
    a := mArr[i];
    Memo_Log.Lines.Add('本轮基准值=' + IntToStr(a));

    while j > i do
    begin
      // 首先从[j]开始向前(从右往左)找到一个 <= a 的数,将其放在[i]中
      while j > i do
      begin
        if mArr[j] <= a then
        begin
          mArr[i] := mArr[j];
          i := i + 1;
          ArrToMemo(mArr);
          Break;
        end;

        j := j - 1;
      end;

      // 然后从[i]开始向后(从左往右)找到一个 > a 的数,将其放在[j]中
      while i < j do
      begin
        if mArr[i] > a then
        begin
          mArr[j] := mArr[i];
          j := j - 1;
          ArrToMemo(mArr);
          Break;
        end;

        i := i + 1;
      end;
    end;
    // 到这里出来的时候就是 i = j 的时候
    mArr[i] := a;
    Memo_Log.Lines.Add('↓↓↓↓第二轮 右边的结果↓↓↓↓');
    ArrToMemo(mArr);
  end
  else
  begin
    Memo_Log.Lines.Add('第二轮 右边的数组长度不到2');
  end;

  // ......按照这种情况循环,一直到左右两边的数不足2个结束
end;

快速排序 结果+代码:

结果:

在这里插入图片描述

代码:

procedure TForm_Main.KuaiSuSort(var avArr: TArray<Integer>; avLeft, avRight: Integer);
var
  i, j, a: Integer;
begin
  if avLeft < avRight then
  begin
    a := avArr[avLeft];
    i := avLeft;
    j := avRight;

    while i < j do
    begin
      while j > i do
      begin
        if avArr[j] <= a then
        begin
          avArr[i] := avArr[j];
          i := i + 1;
          Break;
        end;

        j := j - 1;
      end;

      while i < j do
      begin
        if avArr[i] > a then
        begin
          avArr[j] := avArr[i];
          j := j - 1;
          Break;
        end;

        i := i + 1;
      end;
    end;
    avArr[i] := a;

    KuaiSuSort(avArr, avLeft, i - 1);
    KuaiSuSort(avArr, i + 1, avRight);
  end;
end;
var
  mArr: TArray<Integer>;
begin
  GenerateRandomArray(mArr, 100, 10, True);
  Memo_Log.Lines.Add('排序前');
  ArrToMemo(mArr);

  KuaiSuSort(mArr, 0, Length(mArr) - 1);

  Memo_Log.Lines.Add('排序后');
  ArrToMemo(mArr);
end;

一点点笔记,以便以后翻阅。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小印丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值