一、选择排序
1、算法思想:
将待排序序列分为两部分,一部分为有序序列,另一部分为无序序列。第一趟:从a[0]到a[n-1]中找到最小的数a[i],然后将a[i]与a[0]交换,第二趟:从a[1]到a[n-1]中找到最小的数a[j],然后将a[j]与a[1]交换,第三趟:从a[2]到a[n-1]中找到最小的数a[k],然后将a[k]与a[2]交换 ……
2、实例分析:
{13,15,37,89,60,39,12,109,56,72}
第一趟 :12 {15,37,89,60,39,13,109,56,72}
第二趟:12 ,13 {37,89,60,39,15,109,56,72}
第三趟:12 ,13 ,15 {89,60,39,37,109,56,72}
……
3、算法代码:
import java.util.*;
public class Selection {
//选择排序
public static void sort(Comparable[] a){
int n = a.length;
for(int i=0; i<n; i++){
int min = i;
for(int j=i+1; j<n; j++){
if(less(a[j], a[min])){
min=j;
}
}
exch(a, i, min);
}
}
// v是否小于w ?
private static boolean less(Comparable v, Comparable w) {
return v.compareTo(w) < 0;
}
// 交换a[i]和a[j]
private static void exch(Object[] a, int i, int j) {
Object swap = a[i];
a[i] = a[j];
a[j] = swap;
}
// 打印数组到输出
private static void show(Comparable[] a) {
for (int i = 0; i < a.length; i++) {
System.out.print(a[i]+" ");
}
System.out.println();
}
//测试函数
public static void main(String[] args) {
Comparable[] a = new Comparable[]{8,4,6,3,5,2,9,1,7};
System.out.print("排序前:");
show(a);
System.out.print("排序后:");
Selection.sort(a);
show(a);
}
}
[程序输出]:
排序前:8 4 6 3 5 2 9 1 7
排序后:1 2 3 4 5 6 7 8 9
二、插入排序
1、算法思想:
1〉从第一个元素开始,该元素可以认为已经被排序
2〉取出第一个未排序元素存放在临时变量temp中,在已经排序的元素序列中从后往前扫描,逐一比较
3〉如果temp小于已排序元素,将该元素移到下个位置
4〉重复步骤3〉,直到找到已排序的元素小于或者等于
tips:该算法的排序和抓扑克牌的排序方式一致!先从第一张开始抓,后面抓的牌插入到已经抓的牌的合适位置。
2、实例分析:
{13,15,37,89,60,39,12,109,56,72}
第一趟: 13 {15,37,89,60,39,12,109,56,72}
第二趟: 13 ,15 { 37,89,60,39,12,109,56,72}
第三趟: 13,15 ,37 {89,60,39,12,109,56,72}
第三趟: 13,15 ,37 ,89 {60,39,12,109,56,72}
第四趟: 13,15 ,37 , 60,89 {39,12,109,56,72}
……
3、算法代码:
public class Insertion {
//插入排序
public static void sort(Comparable[] a){
int n = a.length;
for(int i=0; i<n; i++){
for(int j=i+1; j>0; j--){
if(less(a[j], a[j-1])){
exch(a, j, j-1);
}
}
}
}
// v是否小于w ?
private static boolean less(Comparable v, Comparable w) {
return v.compareTo(w) < 0;
}
// 交换a[i]和a[j]
private static void exch(Object[] a, int i, int j) {
Object swap = a[i];
a[i] = a[j];
a[j] = swap;
}
// 打印数组到输出
private static void show(Comparable[] a) {
for (int i = 0; i < a.length; i++) {
System.out.print(a[i]+" ");
}
System.out.println();
}
//测试函数
public static void main(String[] args) {
Comparable[] a = new Comparable[]{8,4,6,3,5,2,9,1,7};
System.out.print("排序前:");
show(a);
System.out.print("排序后:");
Selection.sort(a);
show(a);
}
}
[程序输出]
排序前:8 4 6 3 5 2 9 1 7
排序后:1 2 3 4 5 6 7 8 9
三、冒泡排序
1、算法思想:
对要排序的数据,从上到下依次比较两个相邻的数并加以调整,将最大的数向下移动,较小的数向上冒起。即:每一趟依次比较相邻的两个数据元素,将较小的数放在左边,循环进行同样的操作,直到全部待排序的数据元素排完。整个过程就像气泡在上浮一样。
2、实例分析:
例如:我们要将身高不等的十个人站在一排,要求他们按照身高由低到高排队,设将10个人编号为0—9 ,相邻的两个人依次比较,如果左边的比右边的人高,则交换两个人的位置,否则不交换,直到最后两个人,即此时完成了一趟排序。一趟排序后,最高的人已经在最右边了。
如此都多趟的排序,最终就完成了整个的排序。
3、算法分析:(有小到大排序)
1>、每一趟过程中,就是依次比较两个相邻的数,若a[i]>a[i+1],则交换两数,否则不换;
2>、每一趟就是一重循环,而由于要经过多趟过程,即外面还有一重循环,所以就存在双重循环。
4、算法代码:
public class Bubble {
//冒泡排序
public static void sort(Comparable[] a){
int n = a.length;
for(int i=0; i<n-1; i++){
for(int j=0; j<n-i-1; j++){
if(less(a[j], a[j+1])){
exch(a, j, j+1);
}
}
}
}
// v是否小于w ?
private static boolean less(Comparable v, Comparable w) {
return v.compareTo(w) < 0;
}
// 交换a[i]和a[j]
private static void exch(Object[] a, int i, int j) {
Object swap = a[i];
a[i] = a[j];
a[j] = swap;
}
// 打印数组到输出
private static void show(Comparable[] a) {
for (int i = 0; i < a.length; i++) {
System.out.print(a[i]+" ");
}
System.out.println();
}
//测试函数
public static void main(String[] args) {
Comparable[] a = new Comparable[]{8,4,6,3,5,2,9,1,7};
System.out.print("排序前:");
show(a);
System.out.print("排序后:");
Selection.sort(a);
show(a);
}
}
[程序输出]
排序前:8 4 6 3 5 2 9 1 7
排序后:1 2 3 4 5 6 7 8 9
5,优化
上面的算法,无论的你的数据怎么样,始终都要比n²次,效率很低。若你的数据局部有序,经过几趟交换以后,已经有序,则不用继续往下比。效率会高很多。核心代码如下:
//改进的冒泡排序
public static void sort(Comparable[] a){
int n = a.length;
for(int i=0; i<n-1; i++){
boolean didExch = false;
for(int j=0; j<n-i-1; j++){
if(less(a[j], a[j+1])){
exch(a, j, j+1);
didExch = true;
}
}
if(!didExch) return;
}
}