How can I implement a quick sort in Delphi without getting Access violation errors for large numbers of records?

后端 未结 1 1797
生来不讨喜
生来不讨喜 2021-01-29 15:11

Here is my current code:

function StudentQuickSort(StudentList:TStudentArray;ArrayLength:integer):TStudentArray;
var
  Pivot:TstudentArray;
  LesserList:TStudent         


        
1条回答
  •  -上瘾入骨i
    2021-01-29 15:51

    Your code cannot be salvaged. You are going about solving this problem in the wrong way and I advise you to abandon your existing code. Here is how I believe sorting should be done.

    Note that I am assuming that you don't have generics available to you. In modern Delphi versions you can use TArray.Sort from Generics.Collections to sort. If you have access to that, you should use it

    First of all the key is to separate the sorting from the array being sorted. To achieve that define the following types:

    type
      TCompareIndicesFunction = function(Index1, Index2: Integer): Integer of object;
      TExchangeIndicesProcedure = procedure(Index1, Index2: Integer) of object;
    

    The point is that all the common algorithms that can sort an array need only to be able to compare two items, and exchange two items. These procedural types enable separation of the sorting algorithm from the underlying array storage and types.

    With these definitions in place, we are ready to write our general purpose sorting algorithms. For quicksort it looks like this:

    procedure QuickSort(Count: Integer; Compare: TCompareIndicesFunction; 
      Exchange: TExchangeIndicesProcedure);
    
      procedure Sort(L, R: Integer);
      var
        I, J, P: Integer;
      begin
        repeat
          I := L;
          J := R;
          P := (L+R) div 2;
          repeat
            while Compare(I, P)<0 do inc(I); 
            while Compare(J, P)>0 do dec(J); 
            if I<=J then 
            begin
              if I<>J then 
              begin
                Exchange(I, J);
                //may have moved the pivot so we must remember which element it is
                if P=I then
                  P := J
                else if P=J then
                  P := I;
              end;
              inc(I);
              dec(J);
            end;
          until I>J;
          if L=R;
      end;
    
    begin
      if Count>0 then
        Sort(0, Count-1);
    end;
    

    In order to use this you need to wrap your array in a class which exposes compare and exchange methods.

    0 讨论(0)
提交回复
热议问题