排序算法复习
三、选择排序
选择排序:类似插入排序,也分为有序区和无序区。但是选择排序每次从无序区中选出最小的元素放在有序区的最后一位
步骤:
- 最初整个数列都位于无序区中,选出其中最小值
- 将其放入有序区的最后一位(第一次即为数组的第零位)
- 重复以上步骤
package SortTest;
import java.util.Random;
public class ChoiceSortedTest {
public static void main(String[] args) {
ChoiceSortedTest choiceSortedTest = new ChoiceSortedTest();
int[] buildelement = choiceSortedTest.buildelement();
int[] insertSorted = choiceSortedTest.choiceSorted(buildelement);
choiceSortedTest.printSort(insertSorted);
}
//建立长度为10的测试数组
public int[] buildelement(){
int[] element = new int[10];
Random random = new Random();
for (int i=0;i<10;i++){
//生成0-10之间的随机数
element[i] = random.nextInt(10);
}
return element;
}
//选择排序算法
public int[] choiceSorted(int[] element){
if (element.length <= 1){
return element;
}
int temp;
//外层循环对应整个数列
for(int i=0;i<element.length;i++){
int minIndex = i;
//在无序区中选取最小值
for(int j=i;j<element.length;j++){
if (element[j]<element[minIndex]){
minIndex = j;
}
}
//将其放入有序区最后一位
temp = element[i];
element[i] = element[minIndex];
element[minIndex] = temp;
}
return element;
}
//结果输出
public void printSort(int[] element){
for (int i=0;i<element.length;i++){
System.out.print(element[i]+" ");
}
}
}
选择排序总结:
- 时间复杂度:O(n2)、最好时间复杂度O(n)、最坏时间复杂度O(n2)
- 空间复杂度:O(1)
- 稳定性:不稳定(例5,8,5,2,7)第一次2与5交换位置后两个5的相对位置改变
四、归并排序
归并排序:采用分治思想。将数列分组排序之后对排好序的数列再进行合并。与递归有异曲同工之妙
步骤:
- 将原数列分组,一直分组到每组只有一个元素
- 之后开始进行合并,一直合并到最初的数列
- 思想简单,代码却不易懂
图示:
分治部分:
- 将数列分割至最小
合并部分(难点):
-
需要定义三个数组指针,用以标定当前数组位置
-
因为每个小数组已经有序,所以需要判断两个数组中哪一个数组的元素放入辅助数组中
-
放入辅助数组后,如图将指针p2右移,辅助数组指针也右移
-
之后p1指针指向的数据与p2指针指向的数据比较,决定谁放入数组中
-
注意:如果当某一个指针越界,那么证明该指针指向的数组元素已经全部放入辅助数组中,另一个数组的元素直接复制到辅助数组
代码如下:
package SortTest;
import java.util.Arrays;
import java.util.Random;
public class MergeSortTest {
public static void main(String[] args) {
MergeSortTest mergeSortTest = new MergeSortTest();
int[] buildelement = mergeSortTest.buildelement();
int[] meger = mergeSortTest.mergeSorted_split(buildelement);
mergeSortTest.printSort(meger);
}
//建立长度为10的测试数组
public int[] buildelement(){
int[] element = new int[10];
Random random = new Random();
for (int i=0;i<10;i++){
//生成0-10之间的随机数
element[i] = random.nextInt(20);
}
return element;
}
//选择排序算法
//拆分部分
public int[] mergeSorted_split(int[] element){
if (element.length<=1){
return element;
}
int mid = element.length/2;
int[] left = Arrays.copyOfRange(element,0,mid);
int[] right = Arrays.copyOfRange(element,mid,element.length);
return megerSorted_meger(mergeSorted_split(left),mergeSorted_split(right));
}
//合并部分
public int[] megerSorted_meger(int[] left,int[] right){
int[] meger = new int[left.length+right.length];
//左数组指针
int p1 = 0;
//右数组指针
int p2 = 0;
//临时数组指针
int p3 = 0;
//当某个数组的指针越界后就跳出循环
while(p1<left.length && p2<right.length){
if(left[p1]<=right[p2]){
meger[p3++] = left[p1++];
}else{
meger[p3++] = right[p2++];
}
}
if(p1<left.length){
for(int i=p1;i<left.length;i++){
meger[p3++] = left[p1++];
}
}
if(p2<right.length){
for (int i=p2;i<right.length;i++){
meger[p3++] = right[p2]++;
}
}
return meger;
}
//结果输出
public void printSort(int[] element){
for (int i=0;i<element.length;i++){
System.out.print(element[i]+" ");
}
}
}
归并排序总结:
- 时间复杂度:O(nlogn)
- 空间复杂度:因为需要使用辅助数组,所以空间复杂度为O(n)
- 稳定性:稳定
参考:传智播客