数据结构与算法复习
同样学习过C语言版,这里用java实现直接选择排序
实际上选择排序分为两种:直接选择排序和堆排序,本文介绍的就是直接选择排序
算法思想
从待排序的元素集合中选取关键字最小的数据元素并将它与原始数据元素集合中的第一个数据元素交换位置;然后从不包括第一个位置的数据元素集合中选取关键字最小的数据元素并将它与原始数据集合中的第二个数据元素交换位置;如此重复,直到数据元素集合中只剩下一个数据元素为止
简洁版:每次扫描剩余待排序数组中的最小的放到排好序的序列中,直到最后一个数为止。
提炼:选到待排序中最小的,与待排序第一个(递增则是第一个)位置交换位置。
图片说明
百度动图而来,感谢分享者。
java代码实现
[java]
1. /**
2. * 直接选择排序,每次选最小的放到最前
3. */
4. public static void choiceSort(int[] arr){
5.
6. if(arr == null || arr.length < 1){
7. return;
8. }
9.
10. int min = 0;
11. int
12. /*只需要进行 n - 1 轮选择*/
13. for(int i = 0;i<arr.length - 1;i++){
14. //初始化当前最小的
15. for(int j = i + 1;j<arr.length;j++){
16. if(arr[min] > arr[j]){
17. //记住最小元素下标
18. }
19.
20. }
21.
22. //一轮后,当最小元素的下标不为i时交换位置
23. if(min != i){
24. temp = arr[i];
25. arr[i] = arr[min];
26. arr[min] = temp;
27. }
28. }
29.
30.
31. }
测试代码:
[java]
1. public static void
2.
3. int arrLength = 8; //测试数组的长度
4. /*
5. * 获得随机arrLength个数的数组
6. */
7. int[] arr = new int[arrLength];
8. for(int i = 0;i < arrLength;i++){
9. //随机情况
10. int) (Math.random() * arrLength);
11. }
12.
13.
14. //排序前的输出
15. for(int
16. " ");
17. }
18. System.out.println();
19.
20.
21. choiceSort(arr);
22. //排序后的输出
23. for(int
24. " ");
25. }
26.
27. }
随机的8个样本数组序列进行测试,这里展示三组测试结果:
[java]
1. 2 4 3 7 6 1 6 6
2. 1 2 3 4 6 6 6 7
3.
4. 2 6 6 5 7 7 0 3
5. 0 2 3 5 6 6 7 7
6.
7. 1 3 0 0 3 7 2 7
8. 0 0 1 2 3 3 7 7
完美测试成功。
时间复杂度
在直接选择排序中,第一次排序要进行n-1次比较,第二次排序要进行n-2 此比较....第n-1次排序要进行一次比较,所以总的比较次数为:
比较次数=(n - 1)+(n - 2)+...+ 1 = n(n - 1) / 2
各次排序中,数据元素移动的次数最好为0此,最坏为3次。所以总的移动次数最好为0次,最坏为3(n - 1)次。因此时间复杂度为:O(n2)
空间复杂度
空间复杂度为O(1)
稳定性
直选排序时不稳定的排序算法。
每次从无序记录去选出最小记录后,与无序区的第一个交换引起的,因为交换可能引起关键字相同的数据元素位置发生变化。
实际上它的稳定性是可以保证的,思路就是:在选出最小记录后,将它前面的无序记录依次后移,然后再将最小记录放在有序区的后面,这样就能保证排序算法的稳定性。这样就可能会降低效率。