[Prog] Portofolio Opdracht 2: Insertionsort met pointers

Forum van 1ste Bachelor Informatica.

Moderator: Praesidium

User avatar
Nickman
Posts: 391
Contact:

[Prog] Portofolio Opdracht 2: Insertionsort met pointers

Post#1 » Thu Nov 24, 2005 12:47 pm

Hier is mijn versie van de insertion sort:

Insertion.Mod

Code: Select all

MODULE Insertion;
(*
	Doel: Een array met getallen sorteren volgens het insertion algoritme gebruikmakend van pointers
	Auteur: Nick De Frangh
	Datum: 22-11-05
*)
	IMPORT
		In, OutExt;
	
	TYPE
		Getallenrij = POINTER TO Getal;
		Getal =
			RECORD
				prev: Getallenrij;
				getal : REAL;
				next: Getallenrij;
			END;
	
	PROCEDURE LeesRij(VAR Lijst: Getallenrij);
	(* 
      Omschrijving : Lees een rij getallen in
      Parameters : 
         Lijst : De lijst waarin de getallen zullen worden ingelezen
      Returntype : - 
      Algoritme : - 
   *)
		VAR
			Tempgetal: REAL;
			Tempnode: Getallenrij;
			First: Getallenrij;
   BEGIN
		In.Open();
		In.Real(Tempgetal);
		First := Lijst;
		IF In.Done THEN
			NEW(Tempnode);
			Tempnode^.getal := Tempgetal;
			Tempnode^.next := NIL;
			Tempnode^.prev := NIL;
			
			First^.next := NIL;
			First^.prev := NIL;
			First^.getal := Tempgetal;
		ELSE
			Lijst := NIL;
		END;
		In.Real(Tempgetal);
		WHILE (In.Done) DO
			NEW(Tempnode);
			Tempnode^.getal := Tempgetal;
			Tempnode^.next := NIL;
			Tempnode^.prev := NIL;
			
			WHILE (First^.next # NIL) DO
				First := First^.next;
			END;
			First^.next := Tempnode;
			Tempnode^.prev := First;
			Tempnode^.next := NIL;
			
			In.Real(Tempgetal);
		END; 		
	END LeesRij;
   
   PROCEDURE DrukRij(Lijst: Getallenrij);
   (* 
      Omschrijving : Print een rij getallen af
      Parameters : 
         Lijst : De gesorteerde lijst die afgedrukt zal worden
      Returntype : - 
      Algoritme : - 
   *)
   	VAR
   		First : Getallenrij;
   BEGIN
   	First := Lijst;
   	OutExt.Color(3);
   	OutExt.String("De Geordende lijst volgens insertion sort is: ");
   	OutExt.Ln;
   	OutExt.String("---------------------------------------------");
   	OutExt.Ln;
   	OutExt.Color(8);
   	WHILE Lijst # NIL DO
   		OutExt.RealFix(Lijst^.getal, 3, 2);
   		OutExt.Ln;
   		Lijst := Lijst^.next;
   	END;	
   END DrukRij;
   
   PROCEDURE Insert(VAR Lijst: Getallenrij;
   								Node1: Getallenrij;
   							    Node2: Getallenrij);
   (* 
      Omschrijving : De insertion zelf uitvoeren
      Parameters : 
      	Lijst : De lijst die gesorteerd wordt
      	Node1: Het getal dat ingevoegd moet worden
      	Node2: Het getal waarvoor het getal van Node1 moet worden geplaatst
      Returntype : - 
      Algoritme : - 
   *)
   	VAR
   		Tempnode: Getallenrij;
   		First: Getallenrij;
   BEGIN
   	NEW(Tempnode);											(* maak een node aan met de getalwaarde van de node die ingevoegd moet worden *)
   	Tempnode^.prev := NIL;
   	Tempnode^.next := NIL;
   	Tempnode^.getal := Node1^.getal;
   	
   	First := Lijst;													(* ga opzoek naar de node waarvoor de Tempnode moet worden ingevoegd *)
   	WHILE First # Node2 DO
   		First := First^.next;
   	END;
   	IF First = Lijst THEN											(* het getal moet op de eerste plaats gezet worden *)
   		First^.prev := Tempnode;
   		Tempnode^.next := First;
   		Lijst := Tempnode;
   	ELSE																(* het getal moet ergens anders ingevoegd worden *)
  	 	First^.prev^.next := Tempnode;
 	  	Tempnode^.prev := First^.prev;
 	  	First^.prev := Tempnode;
 	  	Tempnode^.next := First;
 	  END;	

 	  First := Lijst;														(* ga opzoek naar de node die ingevoerd moest worden en laat deze overslaan *)
 	  WHILE First^.next # Node1 DO
 	  	First := First^.next;
	   END;
	   IF First^.next^.next = NIL THEN						(* controleer of Node1 de laatste node is of niet *)
	   	First^.next^.prev := NIL;
	   	First^.next := NIL;
	   ELSE																	(* Als Node1 niet de laatste node is *)
	   	First^.next^.next^.prev := Node1^.prev;
	   	First^.next := Node1^.next;
	   END;  	
   END Insert;
   
   PROCEDURE Insertion*;
   (* 
      Omschrijving : De insertion sort procedure starten
      Parameters : -
      Returntype : - 
      Algoritme : Insertion Sort
   *)
   	VAR
   		Lijst: Getallenrij;
   		Tempnode1, Tempnode2: Getallenrij;
   		insert: BOOLEAN;
   		First: Getallenrij;
   BEGIN
   	NEW(Lijst);
   	Lijst^.next := NIL;
   	LeesRij(Lijst);
   	
   	IF (Lijst = NIL) THEN
   		OutExt.Color(1);
   		OutExt.String ("De lijst is leeg");
   	ELSIF (Lijst^.next = NIL) THEN
   		DrukRij(Lijst);
   	ELSE
   		Tempnode1 := Lijst^.next;
   		WHILE (Tempnode1 # NIL) DO
   			First := Lijst;
   			Tempnode2 := Lijst;
   			insert := FALSE;
   			REPEAT
   				IF (Tempnode2^.getal > Tempnode1^.getal) THEN
   					Insert(Lijst, Tempnode1, Tempnode2);
   					insert := TRUE;
       			END;
   				Tempnode2 := Tempnode2^.next;
   			UNTIL (Tempnode2 = Tempnode1) OR (insert);
   			Tempnode1 := Tempnode1^.next;
   		END; 	  		  		
   		DrukRij(Lijst);
   	END;
   	
   END Insertion;
   
BEGIN
OutExt.Open();
OutExt.Clear; 
END Insertion.
Insertion.Tool

Code: Select all

(*
	Auteur: Nick De Frangh
	Date: 24-11-05
	Werkwijze:
		Ik heb mijn vorige insertion sort module gebruikt en deze volledig opnieuw geschreven door gebruik te maken van pointers.
		Ik heb voor de implementatie van de pointers een dubbel gelinkte niet circulaire lijst gebruikt aangezien deze volgens mij het
		makkelijkst was om te implementeren.
		De insertion sort werkt op dezelfde manier als in de vorige module:
			Ik neem aan dat mijn eerste getal het voorlopig kleinste is
			Dan vergelijk ik alle volgende getallen met hun voorgangers
			Kom ik een getal tegen dat groter is dan mijn huidige getal, dan voeg ik mijn huidige getal in voor het getal dat net groter is.
			Ik loop zo heel de lijst af tot ik aan het einde ben gekomen.
	Algoritme: Insertion Sort
*)

Builder.Compile \ws
	OutExt.Mod
	Insertion.Mod
	~
	
Builder.Compile \f*

System.Free
	Insertion.Mod
	OutExt.Mod
	~

OutExt.Clear


Insertion.Insertion 1.2 45.3 0.33 5.21 8.2 -3.5 2.35 7.88 5.12 6.23 2.36 55.8 -5.66 0.0 6.66 3.2 1.5 5.5~
Insertion.Insertion ~
Insertion.Insertion 1~
Insertion.Insertion 2 1 2 3~
Insertion.Insertion 1 3 6 9 4 5~
Insertion.Insertion 1.5 2.3 1.5 1.6 1.7 1.5 1.3 2.4 0 1 0~
Insertion.Insertion 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0~
Insertion.Insertion 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15~

User avatar
Shinta
WOZ
Posts: 1122

Idiotproof solution :wink:

Post#2 » Mon Nov 28, 2005 8:17 pm

InsertionPointers.Mod

Code: Select all

MODULE InsertionPointers;
(*
	Doel : Portfolio opdracht III (Sorteeralgoritmes & dynamisch geheugenbeheer) : 
				Vorm de module "Insertion" van opdracht II om zodat in plaats van een array van getallen een gelinkte lijst wordt gebruikt.
	Auteur : Kristof Overdulve
	Datum : 28/11/2005
*)

	IMPORT 
		In, OutExt;
		
	TYPE
		pNode* = POINTER TO Node;
		Node* = 
			RECORD
				prev : pNode;
				getal : REAL;
				next : pNode;
			END;
	
	VAR
		head : pNode;
		
		
	PROCEDURE LeesRij(VAR lijst : pNode);
	(*
		Omschrijving : Leest een aantal getallen in en cre‘rt een lijst.
		Parameters : 
			lijst : pNode : pointer naar een record van het type Node.
		Returntype : -
		Algoritme : Circulair dubbelgelinkte lijsten implementeren.
	*)
		
		VAR
			getal : REAL;
			newNode : pNode;
						
	BEGIN
		In.Open;
		(* Leest het eerste getal in *)
		In.Real(getal);
		(* Controleert of er wel inputwaarden te vinden zijn *)
		IF (~In.Done) THEN 
			OutExt.String("WARNING : Controleer of U correcte inputwaarden hebt gespecifieerd!");
			OutExt.Ln;
			(* Cre‘rt een TRAP venster *)
			HALT(90);
		ELSE
			(* Initialiseert de lijst *)
			lijst^.getal := getal;
			lijst^.prev := lijst;
			lijst^.next := lijst;
			head := lijst;
		END;
			
		(* Voegt de overige getallen toe aan de lijst *)
		REPEAT
			lijst := lijst^.next;
			In.Real(getal);
			(* Verhindert dat een nieuwe node wordt toegekend aan de lijst zonder een nieuwe waarde in te hebben gelezen *)
			IF (In.Done) THEN
				(* Initialiseert de toe te voegen node *)
				NEW(newNode);
				newNode^.getal := getal;
				(* Voegt de nieuwe node toe aan de lijst *)
				newNode^.next := head;
				newNode^.prev := lijst;
				lijst^.next^.prev := newNode;
				lijst^.next := newNode;
			END;
		UNTIL (~In.Done);
	END LeesRij;
	
	
	PROCEDURE Sort(VAR lijst : pNode);
	(*
		Omschrijving : Sorteert de lijst.
		Parameters : 
			node : pNode : pointer naar een record van het type Node
		Returntype : -
		Algoritme : Circulair dubbelgelinkte lijsten & Insertion sorteeralgoritme.
	*)
	
		VAR
			temp :pNode;
			node : pNode;

	BEGIN
		(* Zorgt ervoor dat de pointer naar het eerste element uit de lijst wijst *)
		lijst := head;
		(* node is de pointer die element per element de lijst afgaat om getallen te wisselen zonder de hoofdpointer, die van lijst te veranderen *)
		NEW(node);
		
		(* Loopt de hele lijst  af tot het voorlaatste element*)
		REPEAT
			node := lijst;
			NEW(temp);
			(* Voegt temp toe aan de lijst op de juiste plaats *)
			temp^.getal := lijst^.getal;

			WHILE ((node # head) & (node^.prev^.getal > temp^.getal)) DO
				(* Schuift alle elementen eentje op *)
				node := node^.prev;
			END;
			
			(* temp is de variabele die de waarde van het getal waarnaar de pointer op dat moment wijst tijdelijk bevat *)
			temp^.next := node;
			temp^.prev := node^.prev;
			node^.prev^.next := temp;
			node^.prev := temp;
			(* Als temp het kleinste getal tot dan toe is dan moet het vooraan komen te staan *)
			IF (node = head) THEN
				head := temp;
			END;
			
			(* Verwijdert temp uit de foutieve plaats *)
			lijst^.next^.prev := lijst^.prev;
			lijst^.prev^.next := lijst^.next;
			
			(* Gaat naar het volgende element in de lijst *)
			lijst := lijst^.next;
		UNTIL (lijst^.next = head^.next);
	END Sort;
				
	
	PROCEDURE DrukRij(lijst : pNode);
	(*
		Omschrijving : Drukt de gesorteerde lijst af.
		Parameters : 
			node : pNode : pointer naar een record van het type Node
		Returntype : -
		Algoritme : Circulair dubbelgelinkte lijsten.
	*)
	
	BEGIN
		OutExt.String("De geordende lijst is: ");
		OutExt.Ln;
		(* Zorgt ervoor dat bij een eerste verwijzing naar het volgende element het eerste element van de lijst wordt bedoeld *)
		lijst := head^.prev;
		(* Herhaalt het afdrukproces totdat het laatste element van de lijst wordt bereikt *)
		REPEAT
			lijst := lijst^.next;
			(* Drukt getal getal af met drie getallen achter de komma *)
			OutExt.RealFix(lijst^.getal, 0, 3);
			OutExt.Ln;
		UNTIL (lijst^.next = head);
	END DrukRij;			
		
	
	PROCEDURE Insertion*;
	(*
		Omschrijving : Dit is de hoofdprocedure van de module.
		Parameters : -
		Returntype : -
		Algoritme : -
	*)
	
		VAR
			lijst : pNode;
	
	BEGIN
		OutExt.Open;
		OutExt.Clear;
		(* Cre‘ert de lijst *)
		NEW(lijst);
		LeesRij(lijst);
		Sort(lijst);
		DrukRij(lijst);
	END Insertion;
	
BEGIN
END InsertionPointers.
InsertionPointers.Tool

Code: Select all

-InsertionPointers.Tool
(*
	Author : Kristof Overdulve
	Date : 28/11/2005
	Werkwijze : Voordat ik aan deze opdracht begon heb ik eerst reeks 4 gemaakt zodat ik gemakkelijker de Insertion van opdracht II en Reeks 4 kon combineren 
						en optimaliseren voor deze opdracht. Eerst lees ik alle getallen in een dubbelgelinkte circulaire lijst in en nadien pas ik het Insertion 
						sorteeralgoritme op deze lijst toe d.m.v. enkele tijdelijke pointers die kunnen schuiven over de elementen van de lijst zonder de hoofdpointer, die
						naar het te sorteren element uit de lijst te wijzigen. Nadien wordt alles afgedrukt in een standaard afdrukprocedure.
*)

	Builder.Compile \ws
		OutExt.Mod
		InsertionPointers.Mod
	~
	
	Builder.Compile \f *
	
	System.Free
		InsertionPointers;
		OutExt.Mod
	~
	
	InsertionPointers.Insertion 8 2 5 4~	(* Test de gewone gevallen *)
	InsertionPointers.Insertion 8.005 5.254 3.458 7.624 9.211 15.0012 32.01 1.5389~   (* Test de kommagetallen *)
	InsertionPointers.Insertion "Test 1 2 3"~	(* Test het gedrag bij een foutieve invoer *)
	InsertionPointers.Insertion~	(* Test het gedrag bij de afwezigheid van invoer *)
	InsertionPointers.Insertion 2~
	
Last edited by Shinta on Wed Nov 30, 2005 6:35 pm, edited 1 time in total.
Remember remember the fifth of November
Gunpowder, treason and plot.
I see no reason why gunpowder, treason
Should ever be forgot...

User avatar
Nickman
Posts: 391
Contact:

Post#3 » Mon Nov 28, 2005 8:20 pm

Zoals ik het kan zien gebruik jij niet echt de eingeschappen van pointers om te inserten maar laat je zoals in een array gewoon al de andere een plaatsje opschuiven niet? :)

User avatar
Shinta
WOZ
Posts: 1122

Post#4 » Mon Nov 28, 2005 11:08 pm

ja ... en dan ? kzie geen arrays staan :wink:

User avatar
Nickman
Posts: 391
Contact:

Post#5 » Tue Nov 29, 2005 7:25 am

Nene, da's waar natuurlijk :).
Het is juist, daa rniet van, maar het viel mij op dat jou stukje heel wat korter was :D.
Dus ben ik even gaan kijken ;)

User avatar
Shinta
WOZ
Posts: 1122

Post#6 » Wed Nov 30, 2005 6:35 pm

vwala, nu isset zoals het "moet", en nog altijd een stuk korter als jou nick ;)

User avatar
Nickman
Posts: 391
Contact:

Post#7 » Thu Dec 01, 2005 5:56 pm

Heb nog is effe gekeken naar u code en volgens mij is ze vooral korter omdat je ten eerste een circulaire lijst gebruikt en ook omdat jij je insertion in één procedure doet.
Ik laat in één procedure (mijn hoofdprocedure) alles nakijken en vanaf er insertion moet gebeuren roep ik een andere procedure aan...

Maar het doet alletwee wa thet moet doen he ;)

User avatar
Shinta
WOZ
Posts: 1122

Post#8 » Thu Dec 01, 2005 8:23 pm

true, lengte van de code maakt eigenlijk niets uit, de efficientie en het geheugenverbruik wel.

User avatar
Nickman
Posts: 391
Contact:

Post#9 » Fri Dec 02, 2005 12:37 am

Moeten is vergelijken met een gigantisch aantal he :D

User avatar
Norfolk
WOZ
Posts: 780
Contact:

Post#10 » Fri Dec 02, 2005 3:21 pm

ja we kunnen hier ook 10 miljoen getallen insteken en dan de tijd meten

User avatar
Wim
Posts: 16

Post#11 » Sat Dec 03, 2005 3:19 pm

Naar mijn gevoel hebde golle het allebei veel ingewikkelder gemaakt dan het eiglijk is, door me nen dubbel gelinkte lijst te werke.
Ik heb me nen enkel gelinkte lijst gewerkt, en da ga minstens eve goe.
ipv pointers tusse 2 andere pointers in te voege heb kik de pointers gwn naar andere getalle late wijze, wa volges mij veel simpeler is.

User avatar
EagleEye812
Posts: 406

Post#12 » Sat Dec 03, 2005 3:32 pm

Da's flauw he, met dynamische lijsten kunde tenminste echt elementen invoegen tussen twee andere :D

Ik heb de mijne gemaakt met een dubbel gelinkte, niet circulaire lijst want ik zag het nut ni echt van em circulair te maken :) en ik heb der altij problemen mee met circulaire lijsten :P

Nu moet ik gewoon mijn code nog een beetje netjes maken en zo (hij werkt al 100% perfect :) )

User avatar
Nickman
Posts: 391
Contact:

Post#13 » Sat Dec 03, 2005 3:50 pm

Ik had het eerst ook zo gemaakt Wim, maar ik had wa problemen dan me mijn code :p.
Dus heb ik het toch maar anders gedaan :D
En het hangt af van u methode of ge nen dubbel gelinkte nodig hebt of niet...

User avatar
Norfolk
WOZ
Posts: 780
Contact:

Post#14 » Sat Dec 03, 2005 6:02 pm

Nickman wrote:Ik had het eerst ook zo gemaakt Wim, maar ik had wa problemen dan me mijn code :p.
Dus heb ik het toch maar anders gedaan :D
En het hangt af van u methode of ge nen dubbel gelinkte nodig hebt of niet...
dubbel gelinkt lijkt me wel het beste, maar is niet nodig.
circulair is helemaal onnodig want ge maakt een lijst en er moet een begin en een einde zijn van die lijst...

User avatar
Shinta
WOZ
Posts: 1122

Post#15 » Sat Dec 03, 2005 6:44 pm

Wim wrote:Naar mijn gevoel hebde golle het allebei veel ingewikkelder gemaakt dan het eiglijk is, door me nen dubbel gelinkte lijst te werke.
Ik heb me nen enkel gelinkte lijst gewerkt, en da ga minstens eve goe.
ipv pointers tusse 2 andere pointers in te voege heb kik de pointers gwn naar andere getalle late wijze, wa volges mij veel simpeler is.
ik heb da ook eerst gedaan om in plaats van mijn pointers echt te sorteren enzo enkel de getallen te verwisselen maar toen zeiden die tweej assistente datta ni mocht dus ...
Remember remember the fifth of November
Gunpowder, treason and plot.
I see no reason why gunpowder, treason
Should ever be forgot...

Return to “1ste Bachelor”

Who is online

Users browsing this forum: No registered users and 57 guests