There are many sorting algorithms, so it is important to use which algorithm in a particular scenario. In order to select the appropriate algorithm, the following criteria can be considered in the suggested order:
(1) Execution time
(2) Storage space
(3) Programming work
For small data, (1) (2) The difference is not small, the main consideration (3), but for the large number of data, (1) is the first.
First, Bubble (Bubble) sort
Copy Code code as follows:
void Bubblesortarray ()
{
for (int i= 1;i<n;i++)
{
for (int j=0;i< n-i;j++)
{
if (a[j]>a[j+1])//comparison exchange adjacent elements
{
int temp;
TEMP=A[J]; A[J]=A[J+1]; A[j+1]=temp;
}
}
}
}
Efficiency O (n²), suitable for sorting small lists.
Second, select the sort
Copy Code code as follows:
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 minimum for each scan
if (Arr[j]<arr[min_index]) min_index=j;
if (min_index!=i)//Find the minimum Exchange, move 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.
Third, insert sort
Copy Code code as follows:
void Insertsortarray ()
{
The for (int i=1;i<n;i++)//loop starts with the second array element because Arr[0] is the first sorted part
{
int temp=arr[i];//temp marked as unordered first element
int j=i-1;
while (j>=0 && arr[j]>temp)/* Compares temp with the sorted element from small to large to find where temp should be inserted.
{
ARR[J+1]=ARR[J];
j--;
}
Arr[j+1]=temp;
}
}
Best Efficiency O (n); the worst Efficiency O (n²) is the same as bubbling and selection, suitable for sorting small lists
If the list is basically ordered, the insertion order is more efficient than bubbling and choosing.
Copy Code code as follows:
void Shellsortarray ()
{
for (int incr=3;incr<0;incr--)//increment decrement, take increment 3,2,1 as example
{
for (int l=0; l< (n-1)/incr; l++)//repeat divided into each sub list
{
for (int i=l+incr;i<n;i+=incr)//Apply insert sort to each child list
{
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;
}
}
}
}
Applies to sorting small lists.
The efficiency estimate O (nlog2^n) ~o (n^1.5) depends on the initial size of the increment value. It is recommended that you use prime numbers as increment values, because if the increment is a power of 2, the same element will be compared again in the next channel.
Shell (shell) sorting improves the insertion order, reducing the number of comparisons. is an unstable sort, because elements in the sort process may jump backwards and forwards.
Copy Code code as follows:
void mergesort (int low,int high)
{
if (Low>=high) return;//stop when one element remains in each child list
else int mid= (low+high)/2;/* divides the list into equal two sub lists, and if there are odd elements, the left child list is greater than the right child list.
MergeSort (Low,mid);//Sub-list further divided
MergeSort (Mid+1,high);
int [] b=new int [high-low+1];//a new array to store the merged elements
for (int i=low,j=mid+1,k=low;i<=mid && j<=high;k++)/* Two sub lists sorted and merged until one of the two sub-lists ends */
{
if (Arr[i]<=arr[j];)
{
B[k]=arr[i];
i++;
}
Else
{B[k]=arr[j]; j + +;}
}
for (; j<=high;j++,k++)//If there are still elements in the second child list, append to the new list
B[K]=ARR[J];
for (; i<=mid;i++,k++)//If there are still elements in the first child list, append to the new list
B[k]=arr[i];
for (int z=0;z<high-low+1;z++)//copies all the elements of the sorted array B into the original array arr
ARR[Z]=B[Z];
}
Efficiency O (NLOGN), there is no difference between the best, average, and worst use case efficiencies of merging.
Applies to sorting large lists, based on divide-and-conquer methods.
Copy Code code as follows:
/* Fast sorting algorithm idea: Select a pivot element, treats the sort sequence to divide, after the division the sequence one part is smaller than the pivot element, one part is bigger than the pivot element, then carries on these two good subsequence to carry on the above process. */void swap (int a,int b) {int t;t =a; a =b; b =t;}
int Partition (int [] arr,int low,int High)
{
int pivot=arr[low];//takes the first element of a subsequence as a pivot element
while (Low < high)
{
Look for the first element less than the pivot element from the latter half
while (Low < high && Arr[high] >= pivot)
{
--high;
}
Swap this element smaller than the pivot element to the first half
Swap (Arr[low], Arr[high]);
Look for the first element that is larger than the pivot element from the top part of the trip
while (Low <high &&arr [Low]<=pivot)
{
++low;
}
Swap (arr [Low],arr [high])//exchange The elements of this hub element to the second half
}
return to low;/returns the location of the pivot element
}
void QuickSort (int [] a,int low,int High)
{
if (Low <high)
{
int N=partition (A, low, high);
QuickSort (A, low, n);
QuickSort (A, n +1,high);
}
}
Average efficiency O (NLOGN), suitable for sorting large lists.
The total time of this algorithm depends on the location of the hub value, and selecting the first element as the hub may result in an O (n²) worst-case use case efficiency. If the number is basically orderly, the efficiency is the worst. Option intermediate value as pivot, efficiency is O (NLOGN).
Based on the divide-and-conquer method.
Seven, Heap sorting
Maximum heap: The key for any non-terminal node is greater than or equal to its left and right child's keyword, at which point the node at the top of the heap is the largest of the entire sequence.
Thought:
(1) Make i=l, and make temp= KL;
(2) Calculate the left child j=2i+1 of I;
(3) If j<=n-1, then turn (4), otherwise turn (6);
(4) Compare KJ and kj+1, if kj+1>kj, then make j=j+1, otherwise j unchanged;
(5) compared to the temp and KJ, if kj>temp, then Ki equals kj, and make i=j,j=2i+1, and turn (3), otherwise turn (6)
(6) Make Ki equal to temp, end.
Copy Code code as follows:
void Heapsort (Seqiast R)
{
R[1..N] For heap sequencing, you may use the r[0] to do temporary storage unit
int I; Buildheap (R);
R[1-n] is built into the initial heap for (i=n;i>1;i--)//The current unordered area R[1..I] for heap sorting, a total of n-1 trip.
{
R[0]=R[1]; R[1]=r[i]; R[I]=R[0]; Swap the last record in the heap top and heap for heapify (r,1,i-1); R[1..I-1] Reset to heap, only r[1] may violate heap properties
}
}
The time of the heap sort is mainly composed of the time cost of establishing the initial heap and the iterative rebuilding heap, which are all realized by calling Heapify.
The worst time complexity for heap sorting is O (NLGN). The average performance of heap sorting is closer to the worst performance. Heap sorting is not appropriate for files with fewer records because the number of comparisons required to build the initial heap is high. The heap sort is in-place ordering, and the auxiliary space is O (1), which is an unstable sort method.
The difference between heap sort and direct insert ordering:
In order to select the smallest key word record from R[1..N], it is necessary to make a n-1 comparison, then choose the smallest key word record in R[2..N], and do n-2 comparison. In fact, there are a number of comparisons that might have been done in the previous n-1 comparison, but because the comparison was not preserved in the previous n-2, the comparison was repeated during the latter sort of time.
Heap sorting can save some of the comparison results by using a tree structure to reduce the number of comparisons.
Eight, topology sorting
Example: The sequence of students ' elective course arrangement
Topological ordering: The process of arranging the vertices of a direction graph into a linear sequence according to their priority relationship to each other.
Method:
In a direction graph, select a vertex without a precursor and output
Remove the vertex and all arcs with its tail from the diagram
Repeat these two steps until all the vertices are output (the topology is sorted successfully), or there are no predecessors in the graph (there are loops in the diagram).
Copy Code code as follows:
void Topologicalsort ()/* Output topology sort function. If G has no loop, then output a topological sequence of vertices of G and return OK, otherwise return error*/
{
int indegree[m];
int i,k,j;
char N;
int count=0;
Stack Thestack;
Findindegree (G,indegree)//To each vertex to enter degrees Indegree[0....num]
Initstack (thestack);//Initialize Stack
for (i=0;i<g.num;i++)
Console.WriteLine ("+g.vertices[i].data+" of "Node" is "+indegree[i");
for (i=0;i<g.num;i++)
{
if (indegree[i]==0)
Push (Thestack.vertices[i]);
}
Console.Write ("Topology sort output order is:");
while (Thestack. Peek ()!=null)
{
Pop (Thestack. Peek ());
J=locatevex (G,n);
if (j==-2)
{
Console.WriteLine ("Error occurred, end of program.") ");
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 ("The diagram has a loop, an error has occurred and cannot be sorted.") ");
Else
Console.WriteLine ("Sort succeeded.") ");
}
The time Complexity O (n+e) of the algorithm.
Ninth, tournament ranking
The algorithm idea of tournament sort is similar to sports competition.
First, the n data element 22 is grouped, respectively, by the keyword comparison, the winner of the N/2 comparison (the key word), as the first step of the comparison of the results retained,
Then the N/2 data elements are grouped by 22, respectively, according to the keyword, ..., so repeat until you select the smallest data element for the keyword.
Copy Code code as follows:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define SIZE 100000
#define MAX 1000000
struct node
{
Long num;//keyword
Char str[10];
int lastwin;//the last winning opponent
int killer;//defeated opponents
Long times;//Tournament Times
}data[size];
Long comparenum=0;
Long exchangenum=0;
Long read (char name[])//reads the data in the file A.txt and holds it in the array data[]; the last number of data returned
{
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 (long)//Create a winner tree to return the subscript of the Champion (minimum) in array data[]
{
int i,j1,j2,max,time=1;
Long min;//record the subscript for the current champion
For (I=1;pow (2,i-1) <num;i++)
Max=pow (2,i-1)//To find the number of leaf nodes.
for (i=1;i<=max;i++)//Initialize 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)//First round 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;//records two consecutive contestants ' subscripts.
while (Time <= log (max)/log (2))//Knockout
{
for (i=1;i<=max;i++)
{
if (data[i].times==time && data[i].killer==0)//Find a contestant
{
j2=i;//defaults to its two contestants in the later
if (j1==0)//If the first position is empty, the newly arrived contestant first.
J1=j2;
else//or the first contestant is coming, then the contestants have come to the game.
{
++comparenum;
if (data[j1].num <= data[j2].num)//First contestant wins
{
Data[j1].lastwin = j2;//The last to win is J2
Data[j2].killer=j1;//j2 was eliminated by J1.
++data[j1].times;
++data[j2].times;//two contestants plus 1.
min=j1;//minimum number subscript as J1
j1=j2=0;//will j1,j2 0
}
else//Empathy
{
data[j2].lastwin=j1;
Data[j1].killer=j2;
++data[j1].times;
++data[j2].times;
Min=j2;
j1=j2=0;
}
}
}
}
time++;//Wheel Number plus 1
}
Return min;//returns the champion's subscript
}
void Tournamentsort (Long num)//Tournament Sort
{
Long tag=create (num);//return minimum number subscript
FILE *FP1;
Fp1=fopen ("Sort.txt", "w+");//Create and open file for write Sort.txt
while (Data[tag].num!= MAX)//When the minimum value is not infinity
{
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
DATA[TAG].NUM=MAX;//replaces the current champion with Infinity
Tag=create (num)//Return to next champion's subscript
}
}
int main ()
{
int num;
Char name[10];
printf ("Input Name of the file:");
Gets (name);
Num=read (name);//Read files
Tournamentsort (num);//Tournament sort
printf ("comparenum=%d\nexchangenum=%d\n", comparenum,exchangenum);
return 0;
}
Ten, the Cardinal order
Cardinality sorting is also called bucket sorting. Compared to the sorting methods described earlier, cardinality sorting differs markedly from them.
The sorting method described above is based on the comparison of data element keywords, so it can be called based on the comparison of the sort;
The cardinality sort first assigns the data elements to be sorted into different buckets, then "collects" the data elements from each bucket.
By using this "allocation" and "collection" Method of sorting multiple keywords, the cardinality sort implements sorting multiple keywords.
Cases:
Each card has two "keywords": color and face value. The order of magnitude is:
Color: §<¨<©<ª
Face value: 2<3< ... <k<a
The size of the playing card is based on the color comparison, the big card is bigger than the suit and the size of the card. So, the cards are sorted in order from small to large, and the following sequence can be obtained:
§2,...,§a,¨2,...,¨a,©2,...,©a,ª2,...,ªa
This sort of ordering is equivalent to two keywords, and is generally implemented in two ways.
One: can be divided into four piles (each pile of cards with the same color), and then in each pile of cards in the order of small to large orders, and finally ranked the four stacks of cards by color from small to large order to be stacked together to get sorted results.
Second: You can sort by the value of 13 piles (each stack has the same face value), then the 13 stacks are stacked in the order of small to large, then the whole deck in order according to the color and then divided into four piles (each pile of cards have been from small to large in order), Finally, the four stacks of cards by color from small to dahe together to get the result of sorting.
Implementation method:
The highest priority (Most significant Digit first) method, referred to as MSD method: Start by K1 sorting group, the same group of records, key code K1 equal, and then to each group by K2 sorted into subgroups, after the following key code continue such sorting grouping, Until the subgroups are sorted by the most-important KD. By connecting the groups together, we get an ordered sequence.
The lowest priority (least significant Digit first), referred to as LSD: start with KD, then sort the kd-1, repeat in sequence, and then get an ordered sequence after sorting K1.
Copy Code code as follows:
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);//Generate random array
Print (arr);//output array
Radixsort (ref arr);//Sort
Print (arr);//output sorted results
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> ()//to store elements after each sort
list<int>[] Listarr = new list<int>[10];//10 barrels
Char currnetchar;//holds the current character, such as 2 of an element 123.
String currentitem;//holds the current element, such as an element 123
for (int i = 0; i < listarr.length i++)//for 10 buckets to allocate memory initialization.
Listarr[i] = new list<int> ();
for (int i = 0; i < imaxlength i++)//The imaxlength is executed altogether, imaxlength is the maximum number of digits of the element.
{
foreach (int number in ARR)//split barrel
{
CurrentItem = number. ToString ();//Converts the current element to a string
try {Currnetchar = currentitem[currentitem.length-i-1];} Starting from Single-digit to high
catch {listarr[0]. ADD (number); Continue }//If an exception occurs, the number is pressed into listarr[0]. For example, 5 is not a 10-digit, the operation of the above will certainly have a cross-border anomaly, which is the expected behavior, we think 5 10 digits is 0, so put it into the bucket of listarr[0].
Switch (CURRNETCHAR)//through the value of the Currnetchar, determine which barrel it presses people.
{
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 (number); Break
Default:throw new Exception ("Unknow error");
}
}
for (int j = 0; J < Listarr.length + +) to rearrange the data in 10 barrels, pressing into the list
foreach (int number in listarr[j]. Toarray<int> ())
{
List. ADD (number);
LISTARR[J]. Clear ()//empty each barrel
}
arr = list. Toarray<int> ();//arr points to the rearranged element
Console.Write ("{0} times:", I);
Print (arr);//output result of one arrangement
List. Clear ()//Empty list
}
}
Gets the number of digits of the maximum element
private static int getmaxlength (int[] arr)
{
int imaxnumber = Int32.minvalue;
foreach (int i in ARR)/traversal gets the maximum value
{
if (i > Imaxnumber)
Imaxnumber = i;
}
Return imaxnumber.tostring (). length;//This is a bit of an opportunistic way to get the maximum number of elements ...
}
Output array element
public static void Print (int[] arr)
{
foreach (int i in arr)
System.Console.Write (i.tostring () + ' \ t ');
System.Console.WriteLine ();
}
Produces a random array. The range of random numbers is 0 to 1000. Parameter ilength refers to 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 (0,1001);
return arr;
}
}
}
The Cardinal order is a sort of stability, whose time complexity is O (Nlog (r) m), where R is the base to be taken, and M is the heap number, and in some cases the efficiency of the cardinality ranking method is higher than that of other comparative sorting methods.