leopold.bloom
Goto Top

Mein Quicksort funktioniert nicht - Bitte um Hilfe bei der Fehlersuche

Hallo liebe Leute,

ich will mich gar nicht darüber streiten ob selbstgestrickte Arrays in Batches Sinn machen oder nicht. Letztlich ist es in anderen Programmiersprachen auch nicht anders. Es ist reservierter Speicher, dem ich Namen gebe. Sonst nichts. Eine lib stellt die Arrayfunktionen zur Verfügung. Bei mir inzwischen auch. Ich finde es praktisch, weil für mein Gefühl der Code aufgeräumter aussieht. Und es ist für mich einfacher, es vielleicht auch in eine andere Programmiersprache zu portieren oder Progs aus anderen Programmiersprachen als Batch zu realisieren. Egal. Darum geht es mir jetzt nicht.

Ich habe einen Pseudocode Quicksort umgesetzt und er funktioniert nicht. Ich finde den Fehler nicht. Vielleicht kann mir jemand auf die Sprünge helfen. Mein Bubblesort funktioniert einwandfrei. In beide Richtungen. Es liegt also nicht an den Arrayfunktionen. Kann Quicksort eigentlich auch absteigend sortieren? So ganz klar ist mir der Algorithmus noch nicht. Das Prinzip schon. Aber irgendwas fehlt mir noch.

:qsort

Rem Ein Arrey wird übergeben und 2 Indizes
    
	SET QUICK.ARRAY=%1
	SET LOW.INDEX=%2
	SET HIGH.INDEX=%3

	SET /a i=%LOW.INDEX% 
	SET /a j=%HIGH.INDEX%

Rem Arraymitte errechnen

	SET /a HELP=%LOW.INDEX%+%HIGH.INDEX%
	SET /a P=%HELP%/2

Rem das PIVOT Element wird festgelegt. Mitte Array
 
	setlocal enabledelayedexpansion
	   call lib getval %QUICK.ARRAY% %P% PIVOT
	endlocal & SET PIVOT=%PIVOT%

Rem das Tauschelement von links wird gesucht

	:LINKS_NEXT
	setlocal enabledelayedexpansion
		call lib getval %QUICK.ARRAY% %i% WERT_LINKS
	endlocal & SET WERT_LINKS=%WERT_LINKS%	
	IF %WERT_LINKS% LSS %PIVOT% (
		set /a i+=1
		goto LINKS_NEXT
	) 

Rem das Tauschelement von rechts wird gesucht

	:RECHTS_NEXT
	setlocal enabledelayedexpansion
		call lib getval %QUICK.ARRAY% %j% WERT_RECHTS
	endlocal & SET WERT_RECHTS=%WERT_RECHTS%
	IF %WERT_RECHTS% GTR %PIVOT% (
		set /a j-=1
		goto RECHTS_NEXT
	)

Rem solange der Index von links kleinergleich Index von rechts
Rem werden die Elemente getauscht
 
	IF %i% LEQ %j% (
		setlocal enabledelayedexpansion
		call lib getval !QUICK.ARRAY! %i% Z1
		call lib getval %QUICK.ARRAY% %j% Z2
		
Rem Ausgabe zu Kontrollzwecken

		echo vorher
		ECHO %QUICK.ARRAY%[%i%]=!Z1!
		ECHO %QUICK.ARRAY%[%j%]=!Z2!

Rem die Elemente werden getauscht
		
		SET %QUICK.ARRAY%[%i%]=!Z2!
		SET %QUICK.ARRAY%[%j%]=!Z1!
				
Rem Ausgabe zu Kontrollzwecken

                call lib getval !QUICK.ARRAY! %i% Z1
		call lib getval %QUICK.ARRAY% %j% Z2 
		
		ECHO nachher
		ECHO %QUICK.ARRAY%[%i%]=!Z1!
		ECHO %QUICK.ARRAY%[%j%]=!Z2!


Rem Ausgabe gesamtes Array um zu sehen ob der Tausch funktioniert  
Rem hat		
		FOR /L %%l IN (0, 1, 8 ) Do (
		call lib getval %QUICK.ARRAY% %%l Z0
		Echo !QUICK.ARRAY![%%l] !Z0!
		)
		PAUSE 			
		endlocal

Rem die Indizes werden hoch bzw. runter gezählt
		
		set /a i+=1
		set /a j-=1
	)

Rem falls der linke Index am rechten vorbei ist Abbruch	
	
if %i% gtr %j% goto WEITER
	goto :LINKS_NEXT
		
:WEITER

Rem Die Rekursion

IF %LOW.INDEX% LSS %j% call :qsort %QUICK.ARRAY% %LOW.INDEX% %j%
IF %i% LSS %HIGH.INDEX% call :qsort %j% %QUICK.ARRAY% %HIGH.INDEX% 

Rem Zum Schluss Ausgabe des sortierten Arrays auf dem Bildschirm

setlocal enabledelayedexpansion
FOR /L %%l IN (0, 1, 8 ) Do (
	call lib getval %QUICK.ARRAY% %%l Z0
	Echo !QUICK.ARRAY![%%l] !Z0!
)
endlocal	

ECHO FERTIG	
goto :eof

Irgendwas fehlt mir - aber was? Das Pivotelement wird richtig gesetzt, die ersten Tauschaktionen laufen richtig. Aber dann wird nicht weitersortiert. Die Gotos habe ich eingebaut, nachdem ich verzweifelt versucht habe eine Endlosschleife zu konstruieren.

set /a j=0
for /L %%i in (0) do if not defined done (
    set j+=1 
    echo Hallo %j% 
  if %j%==10 set done=break
)

geht nicht. der Job bleibt bei meinem CMD stehen. Bei


 for /L %%i in (0,0,0) do if not defined done ( 

auch. Das hier geht auch nicht

set /a j=0
set /a x=1
for /L %%i in (0,1,%x%) do if not defined done (
    set j+=1
    set x+=1  
    echo Hallo %j% 
  if %j%==10 set done=break
)

Ich habe hier gelegentlich auch

 for /L %i in (0,1,%x%) do 

gesehen. Da bekomme ich auch eine Fehlermeldung. Die Zählvariable muss zwei Prozentzeichen haben und ich kann ihr auch keinen Wert zuweisen.

Also doch zwei Fragen.

1. Was ist bei meinem qsort falsch?
2. Gibt es eine andere Möglichkeit, eine Endlosschleife zu bauen?

Vielen Dank für Euer Interesse

LG

Leo

Content-Key: 190354

Url: https://administrator.de/contentid/190354

Printed on: April 16, 2024 at 19:04 o'clock

Member: jeb-the-batcher
jeb-the-batcher Aug 29, 2012 at 13:26:52 (UTC)
Goto Top
Hallo Leo,

dann möchte ich mich mal über Endlosschleifen auslassen.
Wie der Name schon sagt sind diese endlos, und Batch nimmt es hier sehr genau mit dem Endlos.
Mit einem goto oder exit /b kann zwar das weitere Ausführen der Scheife beendet werden, aber nicht die Schleife selbst!

Siehe ein kleines Beispiel
@echo off
setlocal EnableDelayedExpansion
set /a cnt=0
for /L %%n in (0) DO (
  set /a cnt+=1
  echo !cnt!
  if !cnt!==5 goto :myExit
)
:myExit

Wie wir sehen werden die Zahlen von 1 bis 5 ausgegeben, aber danach hängt die Batch.
Interessant wird es wenn man ECHO ON zu beginn schaltet, dann sieht man das der Abbruch leider die Schleife nicht abbricht, sie wird weiter aufgelöst aber nicht mehr ausgeführt.
Dies gilt übrigens nur für FOR /L, bei den anderen FOR Schleifen ist ein vorzeitiger Abbruch möglich.

Allerdings soll nicht verschwiegen werden, es ist auch mit FOR /L möglich, man braucht nur mit EXIT die Schleife zu beenden.
Dadruch sind aber etwas komplexere Konstrukte notwendig, wenn man danach noch weiterarbeiten möchte.
Dazu gibt es einen schönen Thread auf Dostips.com The ultimate while loop

Zu deiner ersten Frage: Was ist bei meinem qsort falsch?
Ja, das wüsste ich auch gerne, aber da wird wohl noch jemand eine gute Lösung finden face-wink ...

Gruß
jeb