常见排序方法
原创文章,转载请添加本网页链接
https://blog.csdn.net/qq_37334950/article/details/104378361
2、插入排序:将数组分为有序组(数组的第一个元素)和无序组(数组的第二个元素~最后一个元素),每次取出无序组的第一个元素,经过比较插入有序组的合适位置
举例:
初始数组:9 3 4 2 6 7 5 1
分组:(9)(3 4 2 6 7 5 1) 9为有序组,3~1为无序组
第一次插入:(3 9)(4 2 6 7 5 1) 将无序组的3取出,插入有序组9的前面
第二次插入:(3 4 9)(2 6 7 5 1) 将无序组的4取出,插入有序组9的前面
第三次插入:(2 3 4 9)(6 7 5 1) 将无序组的2取出,插入有序组3的前面
第四次插入:(2 3 4 6 9)(7 5 1) 将无序组的6取出,插入有序组9的前面
第五次插入:(2 3 4 6 7 9)(5 1) 将无序组的7取出,插入有序组9的前面
第六次插入:(2 3 4 5 6 7 9)(1) 将无序组的5取出,插入有序组6的前面
第七次插入:(1 2 3 4 5 6 7 9) 将无序组的1取出,插入有序组2的前面,至此无序组已经没有元素,所有元素均正序在有序组内
分析:进行了(n-1)次插入,第一次插入判断1次,第二次插入最多判断2次,最后一次插入最多判断(n-1)次,总计最少(n-1)1=(n-1)次,最多(n-1)[1+2+…+(n-1)]=(n-1)*n/2次。
代码逻辑:首先将初始数组list拆分为有序数组orderedList和无序数组unorderedList,其中有序数组orderedList里面有初始数组list的第一个元素,无需数组unorderedList里面有初始数组list的第二至最后一个元素。然后进行(n-1)次for循环A代表(n-1)次插入。接着在A的内部进行一个以1至(n-1)为上限的循环B代表比较的次数,最后循环B的内部比较元素大小,通过判断并插入元素后使用break跳出当前循环B,进行下一轮的循环B。
代码示例(代码工具-AS):
public static void main(String args[]){
ArrayList<Integer> list = new ArrayList<>();
list.add(9);
list.add(3);
list.add(4);
list.add(2);
list.add(6);
list.add(7);
list.add(5);
list.add(1);
log(list,"默认数组:");//打印数组
/**
* 插入排序
*/
int i = list.size();
ArrayList<Integer> orderedList = new ArrayList<>(list.subList(0, 1));//有序组为第一个元素
ArrayList<Integer> unorderedList = new ArrayList<>(list.subList(1, list.size()));//无序组为第二至最后一个元素
for (int j = 1; j < i; j++) {
int k = orderedList.size();
int m = unorderedList.get(0);
System.out.print("第" + j + "次插入,取得插入值为:" + m);
for (int l = 0; l < k; l++) {
if (orderedList.get(l) >= m){
orderedList.add(l,m);
System.out.println(",插入位置为:" + (l+1));
break;
} else if (l==(k-1)){//走到这一步说明有序组的所有元素都比待插入元素小,需要在当前完成插入到最后一个元素后面的操作
orderedList.add(k,m);
}
}
unorderedList.remove(0);
log(orderedList,"当前有序组结果为:");//打印数组
}
log(orderedList,"最终结果为");//打印数组
}
/**
* 打印数组
* @param list 要打印的数组
* @param string 打印前缀
*/
private static void log(ArrayList<Integer> list,String string){
String s = "";
for (int m = 0; m < list.size(); m++) {
if (m == 0){
s = list.get(0)+"";
} else {
s = s + "," + (list.get(m)+"");
}
}
if (string == null){
System.out.println("--打印数组:" + s);
} else {
System.out.println(string + s);
}
}
结果一览:
结果分析:示例数组经过7次插入,(1+2+1+4+5+4+1)=18次比较后排序成功。对于插入排序来说,如果需要经过最少次的比较得到结果,每次至少都比较1次,意味着每次的插入值都比上一个值小,那么原数组需要完全倒序;如果需要经过最多次的比较得到结果,意味着每次的插入值都比上一个值大,那么原数组就是一个正序的数组。插入排序的性能结论:对于一个数组来说,如果它越偏向正序,则越耗费时间;如果它越偏向倒序,则越节省时间。