Algorithms_in_C 1.0.0
Set of algorithms implemented in C.
Loading...
Searching...
No Matches
patience_sort.c File Reference

Patience Sort More...

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
Include dependency graph for patience_sort.c:

Functions

void patienceSort (int *array, int length)
 for assertions for IO operations for memory management
 
void printArray (int *array, int length)
 Helper function to print an array.
 
void testArray (int *array, int length)
 Testing Helper function.
 
static void test ()
 Self-test implementations.
 
int main ()
 Main function.
 

Detailed Description

Patience Sort

From Wikipedia: In computer science, patience sorting is a sorting algorithm inspired by, and named after, the card game patience. Given an array of n elements from some totally ordered domain, consider this array as a collection of cards and simulate the patience sorting game. When the game is over, recover the sorted sequence by repeatedly picking off the minimum visible card; in other words, perform a k-way merge of the p piles, each of which is internally sorted.

Author
CascadingCascade

Function Documentation

◆ main()

int main ( void  )

Main function.

Returns
0 on exit
157 {
158 test(); // run self-test implementations
159 return 0;
160}
static void test()
Self-test implementations.
Definition patience_sort.c:139
Here is the call graph for this function:

◆ patienceSort()

void patienceSort ( int *  array,
int  length 
)

for assertions for IO operations for memory management

Sorts the target array by dividing it into a variable number of internally sorted piles then merge the piles

Parameters
arraypointer to the array to be sorted
lengthlength of the target array
Returns
void
22 {
23 // An array of pointers used to store each pile
24 int* *piles = (int* *) malloc(sizeof(int*) * length);
25 for (int i = 0; i < length; ++i) {
26 piles[i] = malloc(sizeof(int) * length);
27 }
28
29 // pileSizes keep track of the indices of each pile's topmost element, hence 0 means only one element
30 // Note how calloc() is used to initialize the sizes of all piles to zero
31 int *pileSizes = (int*) calloc(length,sizeof(int));
32
33 // This initializes the first pile, note how using an array of pointers allowed us to access elements through two subscripts
34 // The first subscript indicates which pile we are accessing, the second subscript indicates the location being accessed in that pile
35 piles[0][0] = array[0];
36 int pileCount = 1;
37
38 for (int i = 1; i < length; ++i) {
39 // This will be used to keep track whether an element has been added to an existing pile
40 int flag = 1;
41
42 for (int j = 0; j < pileCount; ++j) {
43 if(piles[j][pileSizes[j]] > array[i]) {
44 // We have found a pile this element can be added to
45 piles[j][pileSizes[j] + 1] = array[i];
46 pileSizes[j]++;
47 flag--;
48 break;
49 }
50 }
51
52 if(flag) {
53 // The element in question can not be added to any existing piles, creating a new pile
54 piles[pileCount][0] = array[i];
55 pileCount++;
56 }
57 }
58
59 // This will keep track of the minimum value of all 'exposed' elements and which pile that value is from
60 int min, minLocation;
61
62 for (int i = 0; i < length; ++i) {
63 // Since there's no guarantee the first pile will be depleted slower than other piles,
64 // Example: when all elements are equal, in that case the first pile will be depleted immediately
65 // We can't simply initialize min to the top most element of the first pile,
66 // this loop finds a value to initialize min to.
67 for (int j = 0; j < pileCount; ++j) {
68 if(pileSizes[j] < 0) {
69 continue;
70 }
71 min = piles[j][pileSizes[j]];
72 minLocation = j;
73 break;
74 }
75
76 for (int j = 0; j < pileCount; ++j) {
77 if(pileSizes[j] < 0) {
78 continue;
79 }
80 if(piles[j][pileSizes[j]] < min) {
81 min = piles[j][pileSizes[j]];
82 minLocation = j;
83 }
84 }
85
86 array[i] = min;
87 pileSizes[minLocation]--;
88 }
89
90 // Deallocate memory
91 free(pileSizes);
92 for (int i = 0; i < length; ++i) {
93 free(piles[i]);
94 }
95 free(piles);
96}
#define malloc(bytes)
This macro replace the standard malloc function with malloc_dbg.
Definition malloc_dbg.h:18
#define free(ptr)
This macro replace the standard free function with free_dbg.
Definition malloc_dbg.h:26
#define calloc(elemCount, elemSize)
This macro replace the standard calloc function with calloc_dbg.
Definition malloc_dbg.h:22

◆ printArray()

void printArray ( int *  array,
int  length 
)

Helper function to print an array.

Parameters
arraypointer to the array
lengthlength of the target array
Returns
void
104 {
105 printf("Array:");
106 for (int i = 0; i < length; ++i) {
107 printf("%d",array[i]);
108 if (i != length - 1) putchar(',');
109 }
110 putchar('\n');
111}

◆ test()

static void test ( void  )
static

Self-test implementations.

Returns
void
139 {
140 int testArray1[] = {2,8,7,1,3,5,6,4};
141 int testArray2[] = {2,2,5,1,3,5,6,4};
142 int testArray3[] = {1,2,3,4,5,6,7,8};
143 int testArray4[] = {8,7,6,5,4,3,2,1};
144
145 testArray(testArray1,8);
146 testArray(testArray2,8);
147 testArray(testArray3,8);
148 testArray(testArray4,8);
149
150 printf("Testing successfully completed!\n");
151}
void testArray(int *array, int length)
Testing Helper function.
Definition patience_sort.c:120
Here is the call graph for this function:

◆ testArray()

void testArray ( int *  array,
int  length 
)

Testing Helper function.

Parameters
arraypointer to the array to be used for testing
lengthlength of the target array
Returns
void
120 {
121 printf("Before sorting:\n");
122 printArray(array,length);
123
124 patienceSort(array,length);
125
126 printf("After sorting:\n");
127 printArray(array,length);
128
129 for (int i = 0; i < length - 1; ++i) {
130 assert(array[i] <= array[i + 1]);
131 }
132 printf("All assertions have passed!\n\n");
133}
void printArray(int *array, int length)
Helper function to print an array.
Definition patience_sort.c:104
void patienceSort(int *array, int length)
for assertions for IO operations for memory management
Definition patience_sort.c:22
Here is the call graph for this function: