Count Sort Funktion geht zu früh aus der Schleife?

3 Antworten

Vom Fragesteller als hilfreich ausgezeichnet

Fangen wir mal vorne an:

void count(int input_array[], int len, int count_array[]) 
{
   /*	for (i=0; i < len; i++) 
	{
		count_array[i] = 0;
    } */
    count_array=memset(count_array,0,sizeof(int)*len));
}

Bei der nächsten Schleife ist allerdings schon ein Fehler, wenn len die Länge des Zählarray ist, respektive der größte Wert.

for (j=0; j<len;j++) /* Muß über die Länge des Eingabearray iterieren */
	{
		count_array[input_array[j]]++;
    }

Fange also erstmal damit an, diesen Teil zu korrigieren.

Beachte: Ich habe versehentlich Java als Programmiersprache angenommen, das Prinzip ist aber dasselbe. Du musst wissen, wie lang Dein zu sortierendes Array ist und Du musst die Länge des Zählarrays aus dem Maximum der Werte im zu sortierenden Array bestimmen.

----

Also ich glaube, Du hast hier einen generellen Denkfehler. Abgesehen von dem offensichtlichen Fehler, dass Len in den meisten Fällen nicht der Länge von output_array entspricht.

Das zweite Array "count_array" soll doch für jeden möglichen Wert in der 1. Liste sagen, wie oft er vorkommt, richtig? Somit musst Du doch erstmal das Maximum aller Werte in der ersten Liste ermitteln. Du sagst, das steht in Len - was keinen Sinn ergibt, denn die Länge eines Arrays kann man mit einer Property ganz einfach ermitteln.

Der erste Schritt muss also sein, die Länge des Arrays zu ermitteln, in das Du zählst. Das geht mit

int maxValue = 0;
for (int i = 0; i < output_array.length; i++)
  if (maxValue < output_array[i]) maxValue = output_array[i];

Jetzt steht in maxValue die größte Zahl in Deinem Ausgangsrray - egal, wie lang das ist.

Jetzt machst Du das Array, in dem Du zählst. Weil Arrays ab 0 indiziert werden, brauchst Du einen Wert mehr im Array:

int[] count_array = new int[maxValue + 1];

Jetzt läuft doch die erste Funktion auf folgendes raus:

void count(int input_array[], int count_array[]) 
{
	for (i=0; i < count_array.length; i++) 
		count_array[i] = 0;
	for (j=0; j < input_array.length; j++) 
	    count_array[input_array[j]]++;
}

Für die zweite Funktion gilt dasselbe - achte auf die Indizes und die Semantik der Arrays.

Der Rückweg sieht nun wiefolgt aus:

void write_output_array(int output_array[], int count_array[]) 
{
    k=0;
    for (j = 0; j < count_array.length; j++) 
	{
		for (i=0; i < count_array[j]; i++) 
		{
			output_array[k++] = j;
		}
	}
}
Destranix  22.11.2021, 17:25
for (i = 0; i < count_array[i]; i++) 
    {
        if (count_array[i] > 0)
        {
	      output_array[k] = i;
		  k++;
        }
    }

Das sollte nicht funktionieren. Da fehlt der äußere Loop.

Den Check auf größer 0 braucht es nicht, das erledigt die Loop-Bedingung.

(Zudem wäre es angebracht, gleich guten Programmierstil zu lehren und in den anderen Codeblöcken geschweifte Klammern um die Blöcke zu setzen)

0
ohwehohach  22.11.2021, 17:27
@Destranix

EDIT: Ach waddema - ich glaub, ich hab einen Fehler in meiner Denkweise des Algorithmus...

Und ob es nun guter oder schlechter Stil ist, einzeilige "Blöcke" in geschweifte Klammern zu setzen oder nicht, ist eine philosophische Frage, über die man seit Generationen streiten kann ;-)

0
Destranix  22.11.2021, 17:30
@ohwehohach

Ich habe deinen Code verstanden. Er geht schief.

Denk dir mal ein Szenario, bei dem an Stelle 0 im Zählarray eine 0 steht. Dann bricht der Loop sofort ab.

0
ohwehohach  22.11.2021, 17:31
@Destranix

Ja, da hätte ein "count_array[i].length" stehen müssen im for. So war das gedacht. Aber dennoch stimmt die Logik glaube ich nicht ganz.

1
Destranix  22.11.2021, 17:33
@ohwehohach

Ja. Im prinzip passte die Methode, wie sie der Fragensteller zu Anfang hatte.

Einziger Fehler war die falsche Größe des count_arrays soweit ich das sehe.
(Und ein paar Dinge bezüglich Geschwindigkeit udn Speicherverbrauch)

0
ohwehohach  22.11.2021, 17:35
@Destranix

Richtig. Der Rückweg war schon ok, nur, dass als Len kein eigener Parameter sein muss, weil er sich durch Array.length ja ergibt.

Jetzt müsste mein Code auch stimmen ;-)

1
ohwehohach  22.11.2021, 17:38
@Destranix

Stimmt. In den Kommentaren steht C - daher wird das eh nicht funktionieren (weil ich Java geschrieben habe...), aber das Prinzip sollte klar werden. Wenn er in C arbeitet, braucht er eventuell sogar zwei Längenparameter. Einen für das Eingangsarray und einen für das Zählarray.

1

Dein Problem:

1.) Der count_array muss die Größe von Maximalwert bis Minimalwert haben, nicht len. In deinem falle also 1 bis 59, bzw. 0 bis 59, wenn du dir das Indexverschieben sparen möchtest.