数据结构——排序
以下排序都以数组 int[] arr = new int[] { 3, 4, 2, 1, 9, 7, 6, 5, 0, 8}为例。经过排序后最终实现由小到大的排序。
一、冒泡排序
冒泡排序的步骤如下:
第一轮:
- 首先第一个元素与第二个元素进行比较,如果第二个元素大,就符合由小到大的原则,否则两个元素调换位置。
- 然后第二个元素与第三个元素比较,如果第三个元素大于第二个元素,即符合由小到大的原则,否则两个元素调换位置。
- 按此原则依次将元素与后面紧挨着的元素进行比较,如果后面的元素大于前面的元素,即符合由小到大的原则,则不必调换,否则两个元素调换位置。等到最后两个元素比较完成后则最后一个元素就成为了整个数组中最大的元素。
如下图:
第二轮:与第一轮类似,从第一个元素开始依次与后面紧挨着的元素进行比较,如果后面的元素大于前面的元素,即符合由小到大的原则,则不必调换,否则两个元素调换位置。但由于第一轮过程中已经比较出最大的元素并将其放到最后的位置上,因此我们只需比较前 n-1 位即可。
如图:
第三轮:与前面相似,比较前n-2位元素。
……
第9轮:比较前n-8位,在本例中为10-8=2位,比较完后整个数组元素即按照由小到大的原则排序。
特点:比较n-1轮,第i轮比较前n-i+1个元素
示例代码如下:
1 public static void sort(int[] arr) 2 { 3 int temp = 0; 4 for (int i = 0; i < arr.Length; i++) 5 { 6 for (int j = 1; j < arr.Length - i; j++) 7 { 8 if (arr[j - 1] > arr[j]) 9 { 10 temp = arr[j - 1]; 11 arr[j - 1] = arr[j]; 12 arr[j] = temp; 13 } 14 } 15 } 16 }
二、插入排序
将一个元素L与前面已经排序好的元素进行比较,从排序好的元素后面开始依次与元素 L 比较。找到第一个比元素 L 小或者相等的元素,假设为元素 S ,由于前面的已经由小到大排序好了,所以元素 S 前面也肯定比元素 L 小,那么只需要将元素 S(包括S)与L(不包括)之间的元素依次向后移动一位。再将元素 L 移动到元素S原先的位置。
详细步骤如下:认为第一个元素已经是排序好的。直接从第二个元素开始排序。
1、第二个元素:与第一个元素比较, 第一个元素比第二个元素小,无需调换;如下图:
2、第三个元素:依次与前面的两个元素比较,首先比较第二个元素,4<2,此时在比较第一个,3<2,即前面的元素比第三个元素都小。此时将第三个元素保存到一个变量中,将第二个元素移动到第三个元素位置上;第一个元素移动到第二个元素上;变量中的数据保存到第一个元素位置上。如下图:
3:第四位元素:与上面的类似,如下图:
示例:
1 public static void sort(int[] arr) 2 { 3 for (int i = 1; i < arr.Length; i++) 4 { 5 if (arr[i] < arr[i-1]) 6 { 7 int temp = arr[i]; 8 int j = i; 9 while (j > 0 && arr[j-1] > temp) 10 { 11 arr[j] = arr[j - 1]; 12 j--; 13 } 14 arr[j] = temp; 15 } 16 } 17 }
三、希尔排序
希尔排序是对插入排序的一种优化,由于在排序时随着数组元素长度的增加,当一个数组极度无序时(如一个很大的数值在数组的前面,而一个很小的元素数值却在后面),排序所耗费的时间呈指数增加,因此希尔排序将插入排序进行了优化。过程如下:先确定一个步长gap,将位置为0、0+gap、0+gap*2、0+gap*3、0+gap*4……到0+gap*n的元素作为第一组,将位置为1、1+gap、1+gap*2……1+gap*n作为第二组,依次类推将 i、i+gap、i+gap*2……i+gap*n作为第 i+1 组。对各个组分别进行插入排序,其目的是将数值较小但位置太靠后的元素迅速移动靠前的位置上,使数组成为一个基本有序的数组,从而加快将整个数组作为一个整体进行插入排序的过程加快速度。
详细步骤图解如下:
(1)确定步长:gap=Length/2=5,将位置为0、5(0+5)的元素作为第一组;将位置为1、6(1+5)的元素作为第二组;位置为2、7(2+5)的元素作为第三组;将位置为3、8(3+5)的元素作为第四组;位置为4、9(4+5)的元素作为第五组。分别对这几个分组进行插入排序。如图:
(2)
(3)
1 public static void sort(int[] arr) 2 { 3 for (int gap = arr.Length / 2; gap > 0; gap /= 2) 4 { 5 for (int i = gap; i < arr.Length; i++) 6 { 7 int temp = arr[i]; 8 int j = 0; 9 for (j = i - gap; j >= 0 && arr[j] > temp; j -= gap) 10 arr[j + gap] = arr[j]; 11 arr[j + gap] = temp; 12 } 13 } 14 }
四、选择排序
1 public static void sort(int[] arr) 2 { 3 int temp; int jj; int j; 4 for (int i = 0; i < arr.Length-1; i++) 5 { 6 temp = arr[i]; jj = i; 7 for (j = i + 1; j < arr.Length; j++) 8 { 9 if (arr[j] < temp) 10 { 11 temp = arr[j]; 12 jj = j; 13 } 14 } 15 arr[jj] = arr[i]; 16 arr[i] = temp; 17 18 } 19 20 }
三、快速排序
1 public static int Packet(int[] arrs, int low, int hight)
2 {
3 int temp=arrs[low];
4 while (low < hight)
5 {
6 while (low < hight && arrs[hight] >= temp)
7 hight--;
8 arrs[low] = arrs[hight];
9 while (low < hight && arrs[low] < temp)
10 low++;
11 arrs[hight] = arrs[low];
12 }
13 arrs[hight] = temp;
14 return hight ;
15 }
16
17 public static void sort(int[] arrs, int low, int hight)
18 {
19 if (low < hight)
20 {
21 int midd= Packet(arrs, low, hight);
22 sort(arrs, midd+1, hight);
23 sort(arrs, low, midd-1);
24 }
25 }