1+ #include < stdlib.h>
2+ #include < SDL3/SDL.h>
3+
4+ #include < QuickSort.hpp>
5+ #include < List.hpp>
6+ #include < Rect.hpp>
7+ #include < Sort.hpp>
8+ #include < Utils.hpp>
9+
10+ namespace QuickSort {
11+
12+ rgb_color GetRectangleColor (bool isOrdered, bool isPivot, bool isSelected) {
13+ return
14+ isOrdered ? rect_green_color :
15+ isPivot ? rect_red_color :
16+ isSelected ? rect_blue_color : rect_base_color;
17+ }
18+
19+ int GetPartitionCount (Rectangle* array, int low, int high, int * stepCount) {
20+ int pivot_value = array[high].value ;
21+
22+ // INDEX OF THE SMALLER ELEMENT
23+ // INDICATES THE RIGHT POSITION OF THE PIVOT (SO FAR)
24+ int i = low - 1 ;
25+
26+ // TRAVERSE MOVING ALL SMALLER ELEMENTS TO THE LEFT SIDE
27+ for (int j = low; j <= high - 1 ; j++) {
28+
29+ // INCREMENT STEP COUNTER
30+ (*stepCount)++;
31+
32+ if (array[j].value < pivot_value) {
33+ i++;
34+ Swap (array, i, j);
35+
36+ // INCREMENT STEP COUNTER
37+ (*stepCount)++;
38+ }
39+ }
40+
41+ // MOVE PIVOT AFTER SMALLER ELEMENTS,
42+ // THEN RETURN NEW PIVOT INDEX
43+ Swap (array, i + 1 , high);
44+ return i + 1 ;
45+ }
46+
47+ void GetQuickSortCount (Rectangle* array, int low, int high, int * stepCount) {
48+ if (low < high) {
49+ // PARTITION RETURNS THE PIVOT INDEX
50+ int pivot_index = GetPartitionCount (array, low, high, stepCount);
51+
52+ // RECURSIVE CALLS FOR SMALLER, GREATER, OR EQUAL ELEMENTS
53+ GetQuickSortCount (array, low, pivot_index - 1 , stepCount);
54+ GetQuickSortCount (array, pivot_index + 1 , high, stepCount);
55+ }
56+ }
57+
58+ int GetStepCount (Rectangle* items) {
59+ int * stepCount = (int *) calloc (1 , sizeof (int ));
60+
61+ // COPY ARRAY TO AVOID CHANGING UNDERLYING DATA
62+ Rectangle* array = CopyArray (items);
63+
64+ GetQuickSortCount (array, 0 , LIST_SIZE - 1 , stepCount);
65+
66+ // INCREMENT STEP COUNTER (ORDERED LIST)
67+ (*stepCount)++;
68+
69+ free (array);
70+ return stepCount[0 ];
71+ }
72+
73+ int Partition (Rectangle* array, int low, int high, int * currentStep, SortSequence sort) {
74+ // THIS IS THE LOMUTO PARTITION ALGORITHM
75+ int offset;
76+
77+ // USING HIGH AS THE PIVOT INDEX (RANDOM WOULD BE OPTIMIZED)
78+ int pivot_index = high;
79+ int pivot_value = array[pivot_index].value ;
80+
81+ // INDEX OF THE SMALLER ELEMENT
82+ // INDICATES THE RIGHT POSITION OF THE PIVOT (SO FAR)
83+ int i = low - 1 ;
84+
85+ // TRAVERSE MOVING ALL SMALLER ELEMENTS TO THE LEFT SIDE
86+ for (int j = low; j <= high - 1 ; j++) {
87+
88+ // RECORD THE SORTING STEP (SNAPSHOT OF THE ARRAY)
89+ for (int index = 0 ; index < LIST_SIZE; index++) {
90+ offset = (currentStep[0 ] * LIST_SIZE) + index;
91+ sort.steps [offset].value = array[index].value ;
92+
93+ // SET RECTANGLE COLOR VALUE
94+ bool isOrdered = index < low;
95+ bool isPivot = index == pivot_index;
96+ bool isSelected = index == i || index == j;
97+ sort.steps [offset].rect_color = GetRectangleColor (isOrdered, isPivot, isSelected);
98+ }
99+ (*currentStep)++;
100+
101+ if (array[j].value < pivot_value) {
102+ i++;
103+ Swap (array, i, j);
104+
105+ // RECORD THE SORTING STEP (SNAPSHOT OF THE ARRAY)
106+ for (int index = 0 ; index < LIST_SIZE; index++) {
107+ offset = (currentStep[0 ] * LIST_SIZE) + index;
108+ sort.steps [offset].value = array[index].value ;
109+
110+ // SET RECTANGLE COLOR VALUE
111+ bool isOrdered = index < low;
112+ bool isPivot = index == pivot_index;
113+ bool isSelected = index == i || index == j;
114+ sort.steps [offset].rect_color = GetRectangleColor (isOrdered, isPivot, isSelected);
115+ }
116+ (*currentStep)++;
117+ }
118+ }
119+
120+ // MOVE PIVOT AFTER SMALLER ELEMENTS,
121+ // THEN RETURN NEW PIVOT INDEX
122+ Swap (array, i + 1 , high);
123+ return i + 1 ;
124+ }
125+
126+ void QuickSort (Rectangle* array, int low, int high, int * currentStep, SortSequence sort) {
127+ if (low < high) {
128+ // PARTITION RETURNS THE PIVOT INDEX
129+ int pivot_index = Partition (array, low, high, currentStep, sort);
130+
131+ // RECURSIVE CALLS FOR SMALLER, GREATER, OR EQUAL ELEMENTS
132+ QuickSort (array, low, pivot_index - 1 , currentStep, sort);
133+ QuickSort (array, pivot_index + 1 , high, currentStep, sort);
134+ }
135+ }
136+
137+ SortSequence GetSequence (Rectangle* items) {
138+ Rectangle* array = CopyArray (items);
139+
140+ // RUN THE SORT TO CALCULATE THE TOTAL NUMBER OF STEPS
141+ int stepCount = GetStepCount (items);
142+
143+ SortSequence sort = create_sort_sequence (stepCount);
144+ sort.steps = (SortStep*) malloc (LIST_SIZE * stepCount * sizeof (SortStep));
145+
146+ int * currentStep = (int *) calloc (1 , sizeof (int ));
147+
148+ QuickSort (array, 0 , LIST_SIZE - 1 , currentStep, sort);
149+
150+ // RECORD FINAL STEP (ORDERED LIST)
151+ int offset;
152+ for (int i = 0 ; i < LIST_SIZE; i++) {
153+ offset = (currentStep[0 ] * LIST_SIZE) + i;
154+ sort.steps [offset].value = array[i].value ;
155+ sort.steps [offset].rect_color = rect_green_color;
156+ }
157+
158+ free (array);
159+ return sort;
160+ }
161+
162+ }
0 commit comments