排序算法整理(一)

来源:互联网 发布:淘宝网店价值评估 编辑:程序博客网 时间:2024/05/17 23:24

一、冒泡排序

 

冒泡排序相对于最简单的排序有了改进,即每次交换都是对后续有帮助的,大数将会越来越大,小的数将会越来越小;

冒泡排序思想:两两相邻元素之间的比较,如果前者大于后者,则交换

因此此排序属于交换排序一类,同类的还有现在最常用的排序方法:快速排序;

 

1.标准冒泡排序

 

此种方法是最一般的冒泡排序实现,思想就是两两相邻比较并交换;

算法实现如下:

1. public static int[] bubble_sort2(int[] arr) { 

2. for (int i = 0; i < arr.length; i++) { 

3. for (int j = arr.length - 1; j > i; j--) { 

4. if (arr[j] < arr[j - 1]) { 

5. swap(arr, j, j - 1); 

6. } 

7. } 

8. } 

9. return arr; 

10. } 

public static int[] bubble_sort2(int[] arr) {

for (int i = 0; i < arr.length; i++) {

for (int j = arr.length - 1; j > i; j--) {

if (arr[j] < arr[j - 1]) {

swap(arr, j, j - 1);

}

}

}

return arr;

}

 

 

2.改进冒泡排序

 

改进在于如果出现一个序列,此序列基本是排好序的,如果是标准的冒泡排序,则还是需要进行不断的比较;

改进方法:通过一个boolean isChanged,如果一次循环中没有交换过元素,则说明已经排好序;

算法实现如下:

1. // 最好:n-1次比较,不移动,因此时间复杂度为O(n),不占用辅助空间 

2. // 最坏:n(n-1)/2次比较和移动,因此O(n^2),占用交换的临时空间,大小为1 

3. public static int[] bubble_sort3(int[] arr) { 

4. boolean isChanged = true; 

5. for (int i = 0; i < arr.length && isChanged; i++) { 

6. isChanged = false; 

7. for (int j = i + 1; j < arr.length; j++) { 

8. if (arr[i] > arr[j]) { 

9. swap(arr, i, j); 

10. isChanged = true; 

11. } 

12. } 

13. } 

14. return arr; 

15. } 

// 最好:n-1次比较,不移动,因此时间复杂度为O(n),不占用辅助空间

// 最坏:n(n-1)/2次比较和移动,因此O(n^2),占用交换的临时空间,大小为1;

public static int[] bubble_sort3(int[] arr) {

boolean isChanged = true;

for (int i = 0; i < arr.length && isChanged; i++) {

isChanged = false;

for (int j = i + 1; j < arr.length; j++) {

if (arr[i] > arr[j]) {

swap(arr, i, j);

isChanged = true;

}

}

}

return arr;

}

 

 

二、简单选择排序

简单选择排序特点:每次循环找到最小值,并交换,因此交换次数始终为n-1次;

相对于最简单的排序,对于很多不必要的交换做了改进,每个循环不断比较后记录最小值,只做了一次交换(当然也可能不交换,当最小值已经在正确位置)

算法如下:

1. //最差:n(n-1)/2次比较,n-1次交换,因此时间复杂度为O(n^2) 

2. //最好:n(n-1)/2次比较,不交换,因此时间复杂度为O(n^2) 

3. //好于冒泡排序 

4. public static int[] selection_sort(int[] arr) { 

5. for (int i = 0; i < arr.length - 1; i++) { 

6. int min = i; 

7. for (int j = i + 1; j < arr.length; j++) { 

8. if (arr[min] > arr[j]) { 

9. min = j; 

10. } 

11. } 

12. if (min != i) 

13. swap(arr, min, i); 

14. } 

15. return arr; 

16. } 

//最差:n(n-1)/2次比较,n-1次交换,因此时间复杂度为O(n^2)

//最好:n(n-1)/2次比较,不交换,因此时间复杂度为O(n^2)

//好于冒泡排序

public static int[] selection_sort(int[] arr) {

for (int i = 0; i < arr.length - 1; i++) {

int min = i;

for (int j = i + 1; j < arr.length; j++) {

if (arr[min] > arr[j]) {

min = j;

}

}

if (min != i)

swap(arr, min, i);

}

return arr;

}

 

三、简单插入排序

 

思想给定序列,存在一个分界线,分界线的左边被认为是有序的,分界线的右边还没被排序,每次取没被排序的最左边一个和已排序的做比较,并插入到正确位置;我们默认索引0的子数组有序;每次循环将分界线右边的一个元素插入有序数组中,并将分界线向右移一位;

算法如下:

1. // 最好:n-1次比较,0次移动 ,时间复杂度为O(n) 

2. // 最差:(n+2)(n-1)/2次比较,(n+4)(n-1)/2次移动,时间复杂度为 O(n^2) 

3. public static int[] insertion_sort(int[] arr) { 

4. int j; 

5. for (int i = 1; i < arr.length; i++) { 

6. if (arr[i] < arr[i - 1]) { 

7. int tmp = arr[i]; 

8. for (j = i - 1; j >= 0 && arr[j] > tmp; j--) { 

9. arr[j + 1] = arr[j]; 

10. } 

11. arr[j + 1] = tmp; 

12. } 

13. } 

14. return arr; 

15. } 

// 最好:n-1次比较,0次移动 ,时间复杂度为O(n)

// 最差:(n+2)(n-1)/2次比较,(n+4)(n-1)/2次移动,时间复杂度为 O(n^2)

public static int[] insertion_sort(int[] arr) {

int j;

for (int i = 1; i < arr.length; i++) {

if (arr[i] < arr[i - 1]) {

int tmp = arr[i];

for (j = i - 1; j >= 0 && arr[j] > tmp; j--) {

arr[j + 1] = arr[j];

}

arr[j + 1] = tmp;

}

}

return arr;

}

 

简单插入排序比选择排序和冒泡排序好!

 

四、希尔排序

 

1959Shell发明;

第一个突破O(n^2)的排序算法;是简单插入排序的改进版;

思想:由于简单插入排序对于记录较少或基本有序时很有效,因此我们可以通过将序列进行分组排序使得每组容量变小,再进行分组排序,然后进行一次简单插入排序即可;

这里的分组是跳跃分组,即第1,4,7位置为一组,第258位置为一组,第369位置为一组;

 

索引

1

2

3

4

5

6

7

8

9

 

此时,如果increment=3,则i%3相等的索引为一组,比如索引11+31+3*2

一般增量公式为:increment = increment/3+1;

算法实现如下:

1. // O(n^(3/2)) 

2. //不稳定排序算法 

3. public static int[] shell_sort(int[] arr) { 

4. int j; 

5. int increment = arr.length; 

6. do { 

7. increment = increment / 3 + 1

8. for (int i = increment; i < arr.length; i++) { //i=increment 因为插入排序默认每组的第一个记录都是已排序的 

9. if (arr[i] < arr[i - increment]) { 

10. int tmp = arr[i]; 

11. for (j = i - increment; j >= 0 && arr[j] > tmp; j -= increment) { 

12. arr[j + increment] = arr[j]; 

13. } 

14. arr[j + increment] = tmp; 

15. } 

16. } 

17. } while (increment > 1); 

18. return arr; 

}

0 0
原创粉丝点击