Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-09 07:49:13

0001 // name=insertionSort ; gcc $name.cc -std=c++11 -lstdc++ -o /tmp/$name && /tmp/$name
0002 // https://www.geeksforgeeks.org/insertion-sort/
0003 
0004 #include <cmath>
0005 #include <cstdio>
0006 #include <cassert>
0007 
0008 /** 
0009 
0010 Move elements of a[0..i-1], that are
0011 greater than key, to one position ahead
0012 of their current position 
0013 **/
0014 
0015 void insertionSort(int* a, int n)
0016 {
0017     int i, key, j;
0018     for (i = 1; i < n; i++) 
0019     {
0020         key = a[i];
0021         j = i - 1;
0022 
0023         while (j >= 0 && a[j] > key) 
0024         {
0025             a[j + 1] = a[j];
0026             j = j - 1;
0027         }
0028         a[j + 1] = key;
0029     }
0030 }
0031 
0032 /**
0033 insertionSortIndirect
0034 ----------------------
0035 
0036 Expects *idx* to start as 0,1,2,3,...,n-1
0037 
0038 This indices are shuffled in a way that would make
0039 the values of *a* to be in ascending order 
0040 without touching a. 
0041 
0042 https://algs4.cs.princeton.edu/21elementary/Insertion.java.html
0043 
0044 **/
0045 
0046 void insertionSortIndirect(int* idx, const int* a, int n)
0047 {
0048     for (int i = 1; i < n; i++) 
0049     {
0050         for(int j = i ; j > 0 && a[idx[j]] < a[idx[j-1]] ; j-- )
0051         {
0052              int swap = idx[j] ; 
0053              idx[j] = idx[j-1]; 
0054              idx[j-1] = swap ; 
0055         } 
0056     }
0057 }
0058 
0059 /**
0060 insertionSortIndirectSentinel
0061 ---------------------------------
0062 
0063 The sorting stops on reaching a with the sentinel value.
0064 
0065 This assumes that sweepSentinel has been invoked previously
0066 to prime the indices. 
0067 
0068 **/
0069 
0070 void insertionSortIndirectSentinel(int* idx, const int* a, int n, int sentinel)
0071 {
0072     for (int i = 1; i < n; i++) 
0073     {
0074         if( a[idx[i]] == sentinel ) return ; 
0075 
0076         for(int j = i ; j > 0 && a[idx[j]] < a[idx[j-1]] ; j-- )
0077         {
0078              int swap = idx[j] ; 
0079              idx[j] = idx[j-1]; 
0080              idx[j-1] = swap ; 
0081         } 
0082     }
0083 }
0084 
0085 
0086 
0087 /**
0088 sweepSentinel
0089 ---------------
0090 
0091 Indices are shuffled such to indirectly move sentinel values 
0092 into far right "high value" slots.
0093 This is done to prevent having to move them via the sort. 
0094  
0095 **/
0096 
0097 void sweepSentinel(int* idx, const int* a, int n, int sentinel)
0098 {
0099     int j = n-1 ; 
0100     for (int i = 0; i < n; i++) 
0101     {
0102         if(sentinel == a[idx[i]] && i < j)
0103         {
0104             int swap = idx[j] ; 
0105             idx[j] = idx[i] ; 
0106             idx[i] = swap ;  
0107             j-- ;  
0108         }  
0109     }
0110 }
0111 
0112 
0113 
0114 
0115 void printArray(int* a, int n)
0116 {
0117     int i;
0118     for (i = 0; i < n; i++) printf("%d ", a[i]);
0119     printf("\n");
0120 }
0121 
0122 void printArrayIndirect(int* idx, int* a, int n)
0123 {
0124     int i;
0125     for (i = 0; i < n; i++) printf("%5d ", idx[i]);
0126     printf("\n");
0127     for (i = 0; i < n; i++) printf("%5d ", a[idx[i]]);
0128     printf("\n");
0129 
0130 }
0131 
0132 
0133 
0134 int* create_sample(int n, int sentinel )
0135 {
0136     assert( n == 5 ); 
0137     int* a = new int[n] ; 
0138     a[0] = 12 ;     
0139     a[1] = 11 ;     
0140     a[2] = 13 ;     
0141     a[3] = 5 ;     
0142     a[4] = 6 ;
0143 
0144     if(sentinel > 0)
0145     {
0146        a[3] = sentinel ; 
0147     }
0148      
0149     return a ;  
0150 }
0151 
0152 int* create_indices(int n)
0153 {
0154     int* idx = new int[n] ; 
0155     for(int i=0 ; i < n ; i++)  idx[i] = i ; 
0156     return idx ; 
0157 }
0158 
0159 void test_insertionSort()
0160 {
0161     int n = 5 ; 
0162     int* a = create_sample(n, 0); 
0163     insertionSort(a, n);
0164     printArray(a, n);
0165 }
0166 
0167 void test_insertionSortIndirect()
0168 {
0169     int n = 5 ; 
0170     printf("test_insertionSortIndirect %d \n", n); 
0171 
0172     int* a = create_sample(n, 0); 
0173     int* idx = create_indices(n); 
0174 
0175     printArrayIndirect(idx, a, n);
0176 
0177     insertionSortIndirect(idx, a, n);
0178 
0179     printArrayIndirect(idx, a, n);
0180 }
0181 
0182 
0183 void test_sweepSentinel()
0184 {
0185     int n = 5 ; 
0186     int sentinel = 10000 ; 
0187     int* a = create_sample(n, sentinel); 
0188     int* idx = create_indices(n); 
0189 
0190     sweepSentinel(idx, a, n, sentinel);
0191     printArrayIndirect(idx, a, n);
0192 }
0193 
0194 
0195 void test_insertionSortIndirectSentinel()
0196 {
0197     int n = 5 ; 
0198     int sentinel = 100000 ; 
0199 
0200     printf("test_insertionSortIndirectSentinel %d \n", n); 
0201 
0202     int* a = create_sample(n, sentinel); 
0203     int* idx = create_indices(n); 
0204 
0205     printArrayIndirect(idx, a, n);
0206 
0207     sweepSentinel(idx, a, n, sentinel);
0208 
0209     insertionSortIndirectSentinel(idx, a, n, sentinel);
0210 
0211     printArrayIndirect(idx, a, n);
0212 }
0213 
0214 
0215 
0216 
0217 
0218 
0219 int main()
0220 {
0221     //test_insertionSort(); 
0222     //test_insertionSortIndirect(); 
0223     //test_sweepSentinel(); 
0224     test_insertionSortIndirectSentinel(); 
0225 
0226     return 0;
0227 }
0228 
0229