10 sorting algorithms and 10 sorting algorithms
There are many sorting algorithms, so which algorithm is very important in a specific scenario. To select an appropriate algorithm, consider the following criteria in the recommended sequence:
(1) execution time
(2) storage space
(3) Programming
When the data size is small, (1) (2) the difference is not big, mainly considering (3). For large data volumes, (1) is the top priority.
The main sorting methods are:
I. Bubble Sorting-adjacent Switching
2. Select sorting-the minimum or large rows are placed at the corresponding position each time.
3. Insert sorting-insert the next row into the sorted Sequence
4. Shell sorting-narrowing down the Increment
V. Merge Sorting
6. Quick sorting
VII. Heap sorting
8. topological sorting
9. Tournament sorting
10. Base sorting
I. Bubble Sorting
Void BubbleSortArray () {for (int I = 1; I <n; I ++) {for (int j = 0; I <n-I; j ++) {if (a [j]> a [j + 1]) // compare swap adjacent elements {int temp; temp = a [j];
A [j] = a [j + 1];
A [j + 1] = temp ;}}}}
Efficiency O (n²), suitable for sorting small lists.
Ii. Select sorting
Void SelectSortArray () {int min_index; for (int I = 0; I <n-1; I ++) {min_index = I; for (int j = I + 1; j <n; j ++) // select the minimum if (arr [j] <arr [min_index]) for each scan.
Min_index = j; if (min_index! = I) // find the minimum item exchange, moving this item to the correct position in the list {int temp; temp = arr [I];
Arr [I] = arr [min_index];
Arr [min_index] = temp ;}}}
Efficiency O (n²), suitable for sorting small lists.
Iii. Insert sorting
Void InsertSortArray () {for (int I = 1; I <n; I ++) // The loop starts from the second array element, because arr [0] serves as the originally sorted part {int temp = arr [I]; // temp is marked as unsorted first element int j = I-1; while (j> = 0 & arr [j]> temp)/* compare temp with sorted elements from small to large, find the location where temp should be inserted */{arr [j + 1] = arr [j]; j --;} arr [j + 1] = temp ;}}
Best efficiency O (n); worst efficiency O (n²) is the same as bubble and selection, suitable for sorting small lists
If the list is basically ordered, insertion sorting is more efficient than bubbling and selection.
4. Shell sorting-narrowing down incremental sorting
Void ShellSortArray () {for (int incr = 3; incr <0; incr --) // incrementally decreases. Take incremental 3, 2, 1 as an example {for (int L = 0; L <(n-1)/incr; L ++) // duplicate sub-list {for (int I = L + incr; I <n; I + = incr) // apply the insert sorting to each sublist {int temp = arr [I]; int j = I-incr; while (j> = 0 & arr [j]> temp) {arr [j + incr] = arr [j]; j-= incr;} arr [j + incr] = temp ;}}}}
Applicable to sorting small lists.
Efficiency estimation O (nlog2 ^ n )~ O (n ^ 1.5) depends on the initial size of the increment value. We recommend that you use the prime number as the increment value, because if the increment value is a power of 2, the same elements will be compared again in the next channel.
Shell sorting improves insert sorting and reduces the number of comparisons. It is an unstable sorting because elements may jump before and after the sorting process.
V. Merge Sorting
Void MergeSort (int low, int high) {if (low> = high) return; // stop else int mid = (low + high) when there is one element left in each sublist) /2;/* divide the List into two equal child lists. If there are an odd number of elements, the Child list on the left is greater than the Child list on the right */MergeSort (low, mid ); // The Sub-list is further divided into MergeSort (mid + 1, high); int [] B = new int [high-low + 1]; // create an array, for (int I = low, j = mid + 1, k = low; I <= mid & j <= high; k ++) /* sort and merge the two sublists until one of the two sublists ends */{if (arr [I] <= arr [j];) {B [k] = arr [I]; I ++;} else {B [k] = arr [j]; j ++ ;}} (; j <= high; j ++, k ++) // if the second sublist still contains elements, append the elements to the new list B [k] = arr [j]; for (; I <= mid; I ++, k ++) // if there are still elements in the first sublist, then it is appended to the new list. B [k] = arr [I]; for (int z = 0; z
Efficiency O (nlogn), there is no difference between the efficiency of the best, average, and worst case.
This function is applicable to sorting large lists based on the division and Control Law.
6. Quick sorting
/* Algorithm idea of fast sorting: select a hub element and separate the sort sequence. After the split, one part of the sequence is smaller than the hub element, and the other part is greater than the hub element, then we perform the above process on the two split subsequences. */Void swap (int a, int B) {int t; t = a; a = B; B = t;} int Partition (int [] arr, int low, int high) {int low = arr [low]; // use the first element of the subsequence as the pivot element while (low
Average efficiency O (nlogn), applicable to sorting large lists.
The total time of this algorithm depends on the location of the pivot value. Selecting the first element as the pivot may lead to the worst case Efficiency of O (n². If the number is basically ordered, the efficiency is the worst. The median of the Option serves as the hub, and the efficiency is O (nlogn ).
Based on the divide and conquer law.
VII. Heap sorting
Max heap: the keywords of any non-terminal node in the latter are greater than or equal to those of its left and right children. At this time, the keywords of the node located at the top of the heap are the largest in the whole sequence.
Thoughts:
(1) make I = l and make temp = kl;
(2) The left child of computing I j = 2i + 1;
(3) If j <= n-1, convert it to (4). Otherwise, convert it to (6 );
(4) Compare kj and kj + 1. If kj + 1> kj, make j = j + 1; otherwise, j remains unchanged;
(5) Compare temp and kj. If kj> temp, make ki equal to kj, and convert I = j, j = 2i + 1 (3 ), otherwise (6)
(6) Make ki equal to temp and end.
Void HeapSort (SeqIAst R) {// pair R [1 .. n] for heap sorting, use R [0] as the temporary storage unit int I; BuildHeap (R); // build R [1-n] into the initial heap for (I = n; i> 1; I --) // for the current unordered zone R [1 .. i] perform heap sorting and perform n-1 queries in total. {R [0] = R [1]; R [1] = R [I]; R [I] = R [0]; // replace Heapify (R, 1, I-1) with the last record in the heap and heap; // Replace R [1 .. i-1] retuned to heap, only R [1] may violate heap nature }}
The Heapify time is mainly composed of the time overhead of establishing the initial heap and re-building the heap. Both of them are implemented by calling Heapify.
The worst time complexity of heap sorting is O (nlgn ). The average performance of heap sorting is closer to the worst performance. Because the initial heap requires a large number of comparisons, the heap sorting is not suitable for files with a small number of records. Heap sorting is a local sorting method with the auxiliary space of O (1). It is an unstable sorting method.
The difference between heap sorting and direct insert sorting:
Directly select the sort, In order .. n] to select the record with the smallest keyword. The record must be compared n-1 times, and then in R [2 .. n] in the selection of the minimum keyword record, and need to do a N-2 comparison. In fact, many comparisons in the next N-2 comparison may have been done in the previous n-1 comparison, but since these comparison results were not retained in the previous sort, therefore, these comparison operations are repeated during the next sorting.
Partial comparison results can be saved in a tree structure to reduce the number of comparisons.
8. topological sorting
For example, the course order of electives for students
Topological sorting: sorts the vertices in a directed graph into a linear sequence based on their priorities.
Method:
Select a vertex without a forward direction graph and output the vertex.
Delete the vertex and all edges ending with it
Repeat the preceding two steps until all vertices have been output (Topology Sorting is successful), or when no vertices without a precursor exist (a loop exists in the figure.
Void TopologicalSort ()/* outputs the topological sorting function. If G has no loop, a topological sequence of the vertex of G is output and OK is returned. Otherwise, ERROR */{int indegree [M]; int I, k, j; char n is returned; int count = 0; Stack thestack; FindInDegree (G, indegree); // calculate the indegree for each vertex [0 .... num] InitStack (thestack); // initialize the stack for (I = 0; I <G. num; I ++) Console. writeLine ("Node" + G. vertices [I]. data + "is" + indegree [I]); for (I = 0; I <G. num; I ++) {if (indegree [I] = 0) Push (thestack. vertices [I]);} Console. write ("Topology Sorting output order:"); while (thestack. peek ()! = Null) {Pop (thestack. peek (); j = locatevex (G, n); if (j =-2) {Console. writeLine ("an error occurs and the program ends. "); Exit ();} Console. write (G. vertices [j]. data); count ++; for (p = G. vertices [j]. firstarc; p! = NULL; p = p. nextarc) {k = p. adjvex; if (! (-- Indegree [k]) Push (G. vertices [k]) ;}} if (count <G. num) Cosole. writeLine ("This graph has a ring, an error occurs, and cannot be sorted. "); Else Console. WriteLine (" sorted successfully. ");}
The time complexity O (n + e) of the algorithm ).
9. Tournament sorting
The algorithm idea of tournament sorting is similar to that of sports competitions.
First, we divide n data elements into two groups and compare them by keywords to obtain n/2 Comparison winners (small keywords), which are retained as the result of the first comparison,
Then the n/2 data elements are divided into two groups and compared by keywords ,..., This is repeated until the smallest data element of a keyword is selected.
# Include <stdio. h> # include <stdlib. h> # include <string. h> # include <math. h> # define SIZE 100000 # define MAX 1000000 struct node {long num; // The keyword char str [10]; int lastwin; // The opponent int killer who wins the least; // beat opponent long times; // Number of matches} data [SIZE]; long CompareNum = 0; long ExchangeNum = 0; long Read (char name []) // read the data in the.txt FILE and store it in the array data []. Finally, the number of returned data {FILE * fp; long I = 1; fp = fopen (name, "rw "); fscanf (fp, "% d % s", & data [I]. Num, data [I]. str); while (! Feof (fp) {I ++; fscanf (fp, "% d % s", & data [I]. num, data [I]. str);} return (I-1);} long Create (long num) // Create the winner tree and return the subscript {int I, j1, j2, max, time = 1; long min; // record the subscript of the current champion for (I = 1; pow (2, I-1) <num; I ++ ); max = pow (2, I-1); // calculate the number of leaf nodes for (I = 1; I <= max; I ++) // initialize the leaf node {data [I]. killer = 0; data [I]. lastwin = 0; data [I]. times = 0; if (I> num) data [I]. num = MAX ;}for (I = 1; I <= max; I + = 2) // The first round of competition {++ CompareNum; if (data [I]. Num <= data [I + 1]. num) {data [I]. lastwin = I + 1; data [I + 1]. killer = I; ++ data [I]. times; ++ data [I + 1]. times; min = I;} else {data [I + 1]. lastwin = I; data [I]. killer = I + 1; ++ data [I]. times; ++ data [I + 1]. times; min = I + 1 ;}} j1 = j2 = 0; // record the subscript while (time <= (log (max) of two consecutive players not eliminated) /log (2) // perform the knockout round {for (I = 1; I <= max; I ++) {if (data [I]. times = time & data [I]. killer = 0) // find a contestant {j2 = I; // by default, it is the later if (j1 = 0) of the two contestants) // if the first position is empty J1 = j2; else // otherwise, the first contestant will be later. Then all contestants will be present and the competition will start {++ CompareNum; if (data [j1]. num <= data [j2]. num) // the first runner wins {data [j1]. lastwin = j2; // The final winner is j2 data [j2]. killer = j1; // j2 is eliminated by j1 ++ data [j1]. times; ++ data [j2]. times; // Add 1 min = j1 for both contestants; // The minimum number subscript is j1 j1 = j2 = 0; // set j1, j2 0} else // similarly {data [j2]. lastwin = j1; data [j1]. killer = j2; ++ data [j1]. times; ++ data [j2]. times; min = j2; j1 = j2 = 0 ;}}} time ++; // round count plus 1} return min; // return to champion Subscript} void TournamentSort (long num) // tournament sorting {long tag = Create (num); // returns the smallest subscript FILE * fp1; fp1 = fopen ("sort.txt ", "w +"); // create and open the file sort.txt while (data [tag]. num! = MAX) // when the minimum value is not infinite {printf ("% d % s \ n", data [tag]. num, data [tag]. str); // output data fprintf (fp1, "% d % s \ n", data [tag]. num, data [tag]. str); // write data [tag]. num = MAX; // Replace the current champion with infinity tag = Create (num); // return the subscript of the next champion} int main () {int num; char name [10]; printf ("Input name of the file:"); gets (name); num = Read (name); // Read the file TournamentSort (num ); // championship sorting printf ("CompareNum = % d \ nExchangeNum = % d \ n", CompareNum, ExchangeNum); return 0 ;}
10. Base sorting
Base sorting is also called Bucket sorting. Compared with the preceding sorting methods, the base sorting method is significantly different from those described above.
The sorting method described above is based on the comparison of data element keywords, so it can be called comparison-based sorting;
The base sorting first "allocates" elements of the data to be sorted to different buckets, and then "collects" the data elements in each bucket.
By sorting multiple keywords using the "Allocation" and "Collection" methods, the base sorting achieves sorting of multiple keywords.
---------------------------------------
Example:
Each playing card has two "keywords": Color and face value. The size order is as follows:
Color: § <\<©<Strong
Nominal value: 2 <3 <...... <K <
The poker card size is first compared based on the color, the card with a large color is larger than the card with a small color; the card with the same color is then compared based on the face value. Therefore, sort the playing cards in ascending order to obtain the following sequence:
2 ,..., § A, 2 ,..., ?,©2 ,...,©A, limit 2 ,..., Region
This sorting is equivalent to sorting with two keywords. Generally, there are two methods to achieve this.
First, you can divide the cards into four stacks based on their colors (each group of cards has the same color), and then sort the cards in the ascending order of their denominations, finally, fold the four stacked cards in ascending order of colors to get the sorting result.
Second, you can first sort the cards into thirteen stacks (each stack has the same nominal value), and then fold the thirteen stacks of cards from small to large in order, then, divide the whole deck into four groups based on the color (each group of cards has been sorted in ascending order by the nominal value ), finally, we can sort these four cards from small to large.
---------------------------------------
Implementation Method:
Most Significant Digit first (MSD) method: group by k1 first, record in the same group, key code k1 is equal, and then group each group by k2 into sub-groups, then, sort the key codes following the key codes until the sub-groups are sorted by the minimum key code kd. Connect the groups to obtain an ordered sequence.
Least Significant Digit first (LSD) method: first sort from kd, then sort the kd-1, repeat, until the first order of k1 will get an ordered sequence.
Using System; using System. collections. generic; using System. linq; using System. text; namespace LearnSort {class Program {static void Main (string [] args) {int [] arr = CreateRandomArray (10); // generates a random array Print (arr ); // output array RadixSort (ref arr); // sort Print (arr); // output the sorted result Console. readKey ();} public static void RadixSort (ref int [] arr) {int iMaxLength = GetMaxLength (arr); RadixSort (ref arr, iMaxLength );} Private static void RadixSort (ref int [] arr, int iMaxLength) {List <int> list = new List <int> (); // store the List of elements after each sorting <int> [] listArr = new List <int> [10]; // ten buckets of char currnetChar; // store the current character, such as 2 string currentItem in element 123; // store the current element, such as an element 123 for (int I = 0; I <listArr. length; I ++) // allocate memory initialization to ten buckets. ListArr [I] = new List <int> (); for (int I = 0; I <iMaxLength; I ++) // iMaxLength is executed in total, iMaxLength is the maximum number of digits of an element. {Foreach (int number in arr) // sub-bucket {currentItem = number. toString (); // convert the current element to a string try {currnetChar = currentItem [currentItem. length-i-1];} // catch {listArr [0] from a single position to a high bit. add (number); continue;} // if an exception occurs, press this number into listArr [0]. For example, if the number of five is no more than 10, an exception will occur when performing the above operations. This is the expected behavior. We think that the number of five is 0, so press it into the listArr [0] bucket. Switch (currnetChar) // use the value of currnetChar to determine the bucket in which it is pressed. {Case '0': listArr [0]. add (number); break; case '1': listArr [1]. add (number); break; case '2': listArr [2]. add (number); break; case '3': listArr [3]. add (number); break; case '4': listArr [4]. add (number); break; case '5': listArr [5]. add (number); break; case '6': listArr [6]. add (number); break; case '7': listArr [7]. add (number); break; case '8': listArr [8]. add (number); break; case '9': listArr [9]. add (numb Er); break; default: throw new Exception ("unknow error") ;}}for (int j = 0; j <listArr. length; j ++) // sorts the data in ten buckets and pushes them into the list foreach (int number in listArr [j]. toArray <int> () {list. add (number); listArr [j]. clear (); // Clear each bucket} arr = list. toArray <int> (); // arr points to the rearranged element // Console. write ("{0} times:", I); Print (arr); // output a list of ordered results. clear (); // Clear list} // obtain the maximum number of digits of the element. private static int GetMaxLength (int [] arr) {Int iMaxNumber = Int32.MinValue; foreach (int I in arr) // obtain the maximum value through traversal {if (I> iMaxNumber) iMaxNumber = I;} return iMaxNumber. toString (). length; // is it a bit opportunistic to obtain the maximum number of digits of the element ...} // output array element public static void Print (int [] arr) {foreach (int I in arr) System. console. write (I. toString () + '\ t'); System. console. writeLine ();} // generates a random array. The random number ranges from 0 to 1000. The iLength parameter indicates how many Random numbers are generated: public static int [] CreateRandomArray (int iLength) {int [] arr = new int [iLength]; random Random = new Random (); for (int I = 0; I <iLength; I ++) arr [I] = random. next (); return arr ;}}}
Base sorting is a stable sorting. the time complexity is O (nlog (r) m), where r is the base number, and m is the number of heaps. In some cases, the base sorting method is more efficient than other comparative sorting methods.