/* Select the sorting idea: Find the smallest element from the unordered data every time, and then exchange it with the last element of the previously ordered element sequence, in this way, the entire source sequence is divided into two parts. The first part is an ordered sequence that has been sorted, and the latter part is unordered, which is used to select the smallest element. After N cycles, the first ordered sequence is extended to the same length as the source sequence, and the length of the unordered part is changed to 0, and the sorting is complete. */
Unsigned long _ stdcall selectsort (void * thearray)
{
Long * array = (mysafearray *) thearray)-> data;
Int ilength = (mysafearray *) thearray)-> ilength;
Long Lmin, lswap;
Int I, j, iminpos;
For (I = 0; I <iLength-1; I ++)
{
Lmin = array [I];
Iminpos = I;
For (j = I + 1; j <= iLength-1; j ++) // find the smallest element from unordered Elements
{
If (array [J] <Lmin)
{
Iminpos = J;
Lmin = array [J];
}
}
// Splice the selected element exchange to the end of the ordered sequence
Lswap = array [I];
Array [I] = array [iminpos];
Array [iminpos] = lswap;
}
Printresult (array, ilength, "select sort"); // print the sorting result to the console
Interlockedincrement (& threadcompleted); // mark the number of threads completed before returning 1
If (threadcompleted = 4) setevent (evtterminate); // check whether other threads have been completed
// If all operations are complete, Set Program End semaphores
Return 0;
}
/* Heap sorting thought: Heap: data elements are arranged from 1 to n into a binary tree, in addition, the root of each subtree of the tree is the smallest or largest element of the elements in the tree. If an unordered data set is a heap, the root element is the smallest or largest Element Heap sorting. It is to constantly build the heap for the remaining data and parse the smallest or largest element. The following Algorithm Starting from the last element, all elements are adjusted based on the principle that a node is greater than the value of the parent node. In this way, a heap is formed once, and the first element is the smallest element. Then create a heap for the remaining unordered data. Note that the Order Number of unordered data elements must be changed. For example, after the first heap, the second element will become a pile of first elements. */
Unsigned long _ stdcall heapsort (void * thearray)
{
Long * array = (mysafearray *) thearray)-> data;
Int ilength = (mysafearray *) thearray)-> ilength;
Int I, j, P;
Long swap;
For (I = 0; I <iLength-1; I ++)
{
For (j = ilength-1; j> I; j --) // compare byte points and parent nodes from the last reciprocal
{
P = (J-I-1)/2 + I; // calculate the subscript of the parent node Array
// Note that the ordinal number of the Tree node is not the same as the array subscript, because the number of elements in the heap is decreasing one by one.
If (array [J] <array [p]) // if the value of the parent node is large, the parent node and the word node are exchanged.
{
Swap = array [J];
Array [J] = array [p];
Array [p] = swap;
}
}
}
Printresult (array, ilength, "Heap Sort"); // print the sorting result to the console
Interlockedincrement (& threadcompleted); // mark the number of threads completed before returning 1
If (threadcompleted = 4) setevent (evtterminate); // check whether other threads have been completed
// If all are executed, set the program end semaphore
Return 0;
}
/* Insert sorting: regards the source data sequence as two halves. The first half is ordered, and the last half is disordered, unordered data is inserted one by one from start to end to the preceding ordered data, increasing the number of ordered data and reducing the number of unordered data, finally, all elements are sorted. */
unsigned long _ stdcall insertsort (void * thearray)
{< br> long * array = (mysafearray *) thearray)-> data;
int ilength = (mysafearray *) thearray)-> ilength;
int I = 1, j = 0;
long temp;
for (I = 1; I {< br> temp = array [I]; // retrieve the first element value of unordered data after a sequence
for (j = I; j> 0; j --) // compare it with the preceding ordered data one by one to find the proper Insertion Location
{< br> If (array [J-1]> temp) // If the element is larger than the inserted value, move it back
array [J] = array [J-1];
else // If the element is smaller than the inserted value, then the last digit of this position is the position of the inserted element
break;
}< br> array [J] = temp;
}< br> printresult (array, ilength, "insert sort"); // print the sorting result to the console
interlockedincrement (& threadcompleted ); // mark the number of completed threads plus 1 before returning
If (threadcompleted = 4) setevent (evtterminate ); // check whether other threads have been executed
// if all threads have been executed, set the program end semaphore
return 0;
}
/* fast sorting: Fast sorting is an application of the sub-governance idea. It selects a pivot, and then exchanges elements smaller than the pivot to the frontend of the pivot, swap the elements greater than the pivot point to the right of the pivot point. Then, the left and right
sides of the Fulcrum are processed in the same way. After several times, the data becomes ordered. The following implementation uses recursion
to create two cursors: ilow, ihigh; ilow points to the first element of the sequence, and ihigh points to the last one and selects the first element as the pivot, store the value in an auxiliary variable. Then the first position becomes null and other elements can be placed. In this way, the cursor is moved forward from the element pointed to by ihigh. ihigh searches for elements smaller than the pivot. if it finds the element, it is placed in the vacant position (which is the first position now ), then, the ihigh cursor stops moving, and the position ihigh points to is vacant. Then, move the ilow cursor to find an element larger than the pivot point and place it in the vacant position pointed to by ihigh, until ilow and ihigh are equal. Finally, use recursion to perform the same processing on the left and right sides */
int quicksort (long * array, int ilow, int ihigh)
{< br> If (ilow> = ihigh) return 1; // recursive end condition
long condition = array [ilow];
int ilowsaved = ilow, ihighsaved = ihigh; // keep unchanged ilow, save the ihigh value
while (ilow {< br> while (array [ihigh]> = running & ihigh> ilow) // search for elements larger than the pivot
ihigh --;
array [ilow] = array [ihigh]; // place the found elements in a vacant location
while (array [ilow] ilow ++;
array [ihigh] = array [ilow]; // place the elements found to a vacant position
}< br> array [ilow] = empty; // place the pivot value to the Pivot Position, at this time, the Pivot Position is vacant
// recursive processing of the left and right parts respectively
quicksort (array, ilowsaved, iHigh-1);
quicksort (array, ilow + 1, ihighsaved);
return 0;
}
// each thread uses this function for output, and only one monitor generates multiple threads
// compete for the right to use the console.
void printresult (long * array, int ilength, const char * headstr)
{< br> waitforsingleobject (evtprint, infinite ); // wait for the event to signal
// entercriticalsection (& csprint); // mark the thread to enter the critical section
// waitforsingleobject (mtxprint, infinite ); // wait for the mutex to be empty (no thread owns it)
int I;
printf ("% s:", headstr );
for (I = 0; I {< br> printf ("% d,", array [I]);
sleep (100); // latency (can be removed)
/* It is easy to see multi-thread access to critical zones
If you comment out the statements of critical control, the output will become messy, the result of each sort will be
inserted and output at intervals, if there is no latency, it is difficult to see the result of this non-critical section control
*/
}< br> printf ("% d \ n", array [I]);
setevent (evtprint); // restores the event semaphore to a signal.
}