排序算法

Posted TengYunhao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了排序算法相关的知识,希望对你有一定的参考价值。

1、插入排序(Insertion Sort)

基本思路:将一个记录插入到已排序好的有序表中,从而得到一个新的有序表。即:先将序列的第1个记录看成是一个有序的子序列,然后从第2个记录逐个进行插入,直至整个序列有序为止。

 1 void InsertSort(int a[])  {  
 2     for(int i = 1; i < a.length; i++){  
 3         if(a[i] < a[i-1]){     //若小于则移动表后插入,大于则不做处理,即等于直接插入。
 4             int j = i-1;      //记录待插入的位置,j最终可能是i-1,也可能小于i-1
 5             int x = a[i];      //存储待插入的元素,即待排序元素
 6             a[i] = a[i-1];     //后移待插入位置的元素一个位置
 7             while(j>=0 && x < a[j]){     //查找在有序表的插入位置  
 8                 a[j+1] = a[j]; //后移元素
 9                 j--;           //元素后移,更改待插入位置
10             }  
11             a[j+1] = x;        //插入到正确位置  
12         }  
13     }  
14 }  

 

2、快速排序(Quick Sort)

基本思路:选取数列中一个数为基准,将数列分成两部分,其中一部分的所有元素比另一部分的所有元素都要大,然后再按照此方式对这两部分进行排序。排序过程可以用递归进行,以此达到有序。

如无序数列 [6 9 2 7 1 8 3 4 5]

a、先把第一项 [6] 取出来,依次与其它项比较,比 [6] 小的放在前面,比 [6] 大的放在后面。

则数列变为 [2 1 3 4 5 6 9 7 8],即 [2 1 3 4 5 6] 与 [9 7 8] 两部分。

b、继续对这两部分数列按照a的方式排序,重复若干次后数列变为有序。

 1 static int partition(int[] unsorted, int start, int end)
 2 {
 3     int pivot = unsorted[start];
 4     while (start < end)
 5     {
 6         while (start < end && unsorted[end] > pivot) end--;
 7         unsorted[start] = unsorted[end];
 8         while (start < end && unsorted[start] <= pivot) start++;
 9         unsorted[end] = unsorted[start];
10     }
11     unsorted[start] = pivot;
12     return start;
13 }
14 
15 static void quickSort(int[] unsorted, int start, int end)
16 {
17     if (start < end)
18     {
19         int loc = partition(unsorted, start, end);
20         quickSort(unsorted, start, loc - 1);
21         quickSort(unsorted, loc + 1, end);
22     }
23 }
24 
25 static void Main(string[] args)
26 {
27     int[] x = { 6, 2, 4, 1, 5, 9 };
28     quickSort(x, 0, x.Length - 1);
29 }        

 

3、选择排序(Selection Sort)

基本思路:每次都从待排序区间选出来最小的元素,然后将这个元素与该区间第一个元素交换位置。

 1 static void selectionSort(int[] unsorted)
 2 {
 3     for (int i = 0; i < unsorted.Length; i++)
 4     {
 5         int min = unsorted[i], min_index = i;
 6         for (int j = i; j < unsorted.Length; j++)
 7         {
 8             if (unsorted[j] < min)
 9             {
10                 min = unsorted[j];
11                 min_index = j;
12             }
13         }
14         if (min_index != i)
15         {
16             int temp = unsorted[i];
17             unsorted[i] = unsorted[min_index];
18             unsorted[min_index] = temp;
19         }
20     }
21 }
22 
23 static void Main(string[] args)
24 {
25     int[] x = { 6, 2, 4, 1, 5, 9 };
26     selectionSort(x);
27 }        

 

4、桶排序(Bucket Sort)

基本思路:根据元素范围创建一个新数组,遍历待排序数组的每一项并将其放入到新数组中,遍历完成后排序完成。

 1 static int[] bucketSort(int[] unsorted, int maxNumber = 99)
 2 {
 3     int[] sorted = new int[maxNumber + 1];
 4     for (int i = 0; i < unsorted.Length; i++)
 5     {
 6         sorted[unsorted[i]] = unsorted[i];
 7     }
 8     return sorted;
 9 }
10 
11 static void Main(string[] args)
12 {
13     int[] x = { 99, 65, 24, 47, 50, 88,33, 66, 67, 31, 18 };
14     var sorted = bucketSort(x, 99);
15 }

 

5、基数排序(Radix Sort)

基本思路:类似于桶排序,但这里需要的桶总是10个,先按个位数进行装桶,再按十位装桶、百位装桶,所有位数都装过桶后排序完成。

 1 static void radixSort(int[] unsorted, int array_x = 10, int array_y = 100)
 2 {
 3     for (int i = 0; i < array_x/* 最大数字不超过999999999...(array_x个9) */; i++)
 4     {
 5         int[,] bucket = new int[array_x, array_y];
 6         foreach (var item in unsorted)
 7         {
 8             int temp = (item / (int)Math.Pow(10, i)) % 10;
 9             for (int l = 0; l < array_y; l++)
10             {
11                 if (bucket[temp, l] == 0)
12                 {
13                     bucket[temp, l] = item;
14                     break;
15                 }
16             }
17         }
18         for (int o = 0, x = 0; x < array_x; x++)
19         {
20             for (int y = 0; y < array_y; y++)
21             {
22                 if (bucket[x, y] == 0) continue;
23                 unsorted[o++] = bucket[x, y];
24             }
25         }
26     }
27 }
28 
29 static void Main(string[] args)
30 {
31     int[] x = {999999999, 65, 24, 47, 13, 50, 92, 88, 66, 33, 22445, 10001, 624159, 624158, 624155501};
32     radixSort(x);
33 }    

 

6、鸽巢排序(Pigeonhole Sort)

基本思路:类似于桶排序,比桶排序更利于记录重复数据,根据范围创建一个数组,数组索引的位置就表示值,数组里的值表示这个数出现的次数。

 1 static int[] pogeon_sort(int[] unsorted, int maxNumber = 10)
 2 {
 3     int[] pogeonHole = new int[maxNumber + 1];
 4     foreach (var item in unsorted)
 5     {
 6         pogeonHole[item]++;
 7     }
 8     return pogeonHole;
 9 }
10 
11 static void Main(string[] args)
12 {
13     int[] x = { 99, 65, 24, 47, 47, 50, 99, 88, 66, 33, 66, 67, 31, 18, 24 };
14     var sorted = pogeon_sort(x, 99);
15 }    

 

以上是关于排序算法的主要内容,如果未能解决你的问题,请参考以下文章

算法排序之堆排序

快速排序-递归实现

从搜索文档中查找最小片段的算法?

在第6731次释放指针后双重免费或损坏

TimSort算法分析

以下代码片段的算法复杂度