Sortowania pseudokody Cormena

0

W pseudokodach sortowania u Cormena jest kilka rzeczy które mi się nie podobają

Sortowanie przez scalanie

  1. Używa wartowników
    Nie wydaje mi się aby były konieczne a utrudniają napisanie działającego programu
    bo co jeśli wartością w tablicy(na liście) będzie wartość maksymalna (sortowanie rosnące) lub minimalna (sortowanie malejące)
    albo gdybyśmy chcieli sortować coś innego niż liczby
  2. Używa dwóch tablic pomocniczych zamiast jednej
    Jeżeli używamy tablic dynamicznych to może nie ma aż takiego znaczenia ale jeśli mamy tablicę o stałym rozmiarze
  3. Używa rekurencji przez co dla pewnych danych występuje przepełnienie stosu

Kodu nie podam
Mam w Pascalu w C a nawet ostatnio przepisałem na wasz ulubiony Python

Pseudokod znajduje się w angielskich wersjach książek takich jak
Introduction to algorithms
Algorithms unlocked

  1. Jak pozbyć się tych wartowników
  2. Po co mu dwie tablice pomocnicze zamiast jednej przy okazji można by się zastanowić jak ograniczyć koszt pamięciowy
  3. Jak przepisać ten kod na kod iteracyjny

Sortowanie stogowe

W sortowaniu stogowym natomiast używa rekurencji ogonowej
Widziałem próby usunięcia tej rekurencji przez złamanie pętli zastępującej tę rekurencję
Czy ma ktoś bardziej elegancki pomysł na usunięcie tej rekurencji z sortowania stogowego

0
def merge(A,p,q,r):
    L=[];
    R=[];
    for i in range(p,q+1):
          L.append(A[i]);
    for i in range(q+1,r+1):
          R.append(A[i]);
    L.append(1.7e38);
    R.append(1.7e38);
    i=0;
    j=0;
    for k in range(p,r+1):
          if(L[i]<=R[j]):
                 A[k]=L[i];
                 i+=1;
          else:
              A[k]=R[j];
              j+=1;

def mergesort(A,p,r):
    if(p<r):
           q=(p+r)/2;
           mergesort(A,p,q);
           mergesort(A,q+1,r);
           merge(A,p,q,r);

tab=[]
import random
for i in range(10):
      tab.append((1-2*random.randint(0,1))*10*random.random());

tab;
mergesort(tab,0,len(tab)-1);
0

Z tym formatowaniem kodu to takie może być ?

program sort;
uses crt;
const maxT=1000;
      maxR=1.7e38;
type tablica=array[1..maxT] of real;

procedure scal(var A:tablica;p,q,r:integer);
          var n1,n2,i,j,k:integer;
              B,C:tablica;
begin
     n1:=q-p+1;
     n2:=r-q;
     for i:=p to q do
         B[i-p+1]:=A[i];
     for i:=q+1 to r do
         C[i-q]:=A[i];
     B[n1+1]:=maxR;
     C[n2+1]:=maxR;
     i:=1;
     j:=1;
     for k:=p to r do
         if (B[i]<=C[j]) then
         begin
              A[k]:=B[i];
              i:=i+1;
         end
         else
             begin
                  A[k]:=C[j];
                  j:=j+1;
             end;
end;

procedure sortuj(var A:tablica;p,r:integer);
          var q:integer;
begin
     if (p<r) then
     begin
          q:=(p+r) div 2;
          sortuj(A,p,q);
          sortuj(A,q+1,r);
          scal(A,p,q,r);
     end;
end;

var A:tablica;
    k,n,p,q:integer;
    esc:char;

begin
     clrscr;
     repeat
           randomize;
           write('Podaj n=');
           readln(n);
           for k:=1 to n do
           begin
                p:=(1-2*random(2))*random(10);
                q:=1+random(10);
                A[k]:=p/q;
           end;
           for k:=1 to n do
               write(A[k]:1:10,' ');
           writeln;
           writeln;
           sortuj(A,1,n);
           for k:=1 to n do
               write(A[k]:1:10,' ');
           writeln;
           writeln;
           esc:=readkey;
     until esc=#27;
end.

Poniższy kod sformatowany z użyciem wtyczki AStyle

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<conio.h>

#define inf 1.7e308

void merge(double*,int,int,int);
void mergesort(double*,int,int);

int main()
{
    char esc;
    int n,k,p,q;
    double* A;
    do
    {
        printf("Pdaj n=");
        scanf("%d",&n);
        A=(double*)malloc((n+1)*sizeof(double));
        srand(time(NULL));
        for(k=1; k<=n; k++)
        {
            p=(1-2*(rand()%2))*rand()%10;
            q=1+rand()%10;
            A[k]=(double)p/q;
        }
        for(k=1; k<=n; k++)
            printf("%.12lf ",A[k]);
        printf("\n\n");
        mergesort(A,1,n);
        for(k=1; k<=n; k++)
            printf("%.12lf ",A[k]);
        printf("\n\n");
        free(A);
        esc=getch();
    }
    while(esc!=27);
    return 0;
}

void merge(double* A,int p,int q,int r)
{
    int n1,n2,i,j,k;
    double*L;
    double*R;
    n1=q-p+1;
    n2=r-q;
    L=(double*)malloc((n1+2)*sizeof(double));
    R=(double*)malloc((n2+2)*sizeof(double));
    for(i=p; i<=q; i++)
        L[i-p+1]=A[i];
    for(i=q+1; i<=r; i++)
        R[i-q]=A[i];
    L[n1+1]=inf;
    R[n2+1]=inf;
    i=1;
    j=1;
    for(k=p; k<=r; k++)
        if(L[i]<=R[j])
        {
            A[k]=L[i];
            i++;
        }
        else
        {
            A[k]=R[j];
            j++;
        }
    free(L);
    free(R);
}

void mergesort(double* A,int p,int r)
{
    int q;
    if(p<r)
    {
        q=(p+r)/2;
        mergesort(A,p,q);
        mergesort(A,q+1,r);
        merge(A,p,q,r);
    }
}

Sortowanie przez scalanie

Wartowników usunąłem rozbijając pętlę for w której następuje
przepisanie danych z tablicy pomocniczej do sortowanej tablicy na trzy pętle while
Przepisywanie danych z tablicy można zrealizować jedną pętlą for
a następnie zmienną j przesunąć o n1

Nadal ciekaw jestem jak usunąć rekurencję

1 użytkowników online, w tym zalogowanych: 0, gości: 1