需求:要对 3,5,2,7,9,8,6 这组数据进行排序。
1、冒泡排序
冒泡排序会对相邻的两个数据进行比较,每一次冒泡都会让至少一个元素移动到他应该在的位置。如下图所示,
第一次冒泡两两比较,如果左边>右边则进行交换, 9最大,最后被移动到数组的最顶端。
第二次冒泡,只需要对2,3,5,7,6,8 进行两两比较,8最大应该将它放在倒数第二个位置。
依次类推,经过n-1次冒泡,就可以将所有的数据放到正确的位置。
示例代码:
public class Bubble {
/**
* 冒泡排序 效率O(N2)
* @param a
*/
public void bubbleSort(int[] a) {
/**
* 1、定义两个变量out, in; out未排好序的数据的最大索引,
* 通过控制in对剩余未排好序的数据进行两两比较,将最大的数据移动到剩余数据中索引最大的位置。
* 2.外层循环out从a.length - 1到1
* 3.内层循环in从 0到out-1
* 4.比较in>in+1? 是 交换
*/
for (int out = a.length - 1; out > 0; out--){
// outer loop (backward)两两比较
for (int in = 0; in < out; in++)
if (a[in] > a[in + 1])
swap(a,in, in + 1);//交换
}
}
/**
* 交换
* @param a
* @param one
* @param two
*/
private void swap(int[] a,int one, int two) {
int temp = a[one];
a[one] = a[two];
a[two] = temp;
}
/**
* 打印数组
* @param arr
*/
public void display(int[] arr){
for (int i=0;i < arr.length;i++){
System.out.print(arr[i]);
if (i == (arr.length-1)){
System.out.print(" \n");
}else{
System.out.print(" ");
}
}
}
public static void main(String[] args) {
int[] arr = {3,5,2,7,9,8,6};
Bubble bubble = new Bubble();
bubble.bubbleSort(arr);
bubble.display(arr);
}
}
2、选择排序
选择排序改进了冒泡排序,将必要的交换次数从 O(N2)减少到O(N)。不幸的是比较的次数仍然保持为O(N2),不过,选择排序仍然为数据排序提供了一种重要的改进,因为他减少了交换的时间,有时候交换的时间比比较的时间更为重要。
选择排序第一次从数组中选择最小的元素放在第1个位置,第二次从剩下的数据中选择最小的数据移动到第2个位置,依次类推,经过n次选择,就可以将整个数组变成有序。
示例代码:
public class Select {
public void sort(int[] a) {
/**
* out未排好序的数据中最左端的数据
* in是out后面的数据
* min初始值为out 通过in的增长与min比较获得未排好序的数据最小的值
*/
int out, in, min;
for (out = 0; out < a.length - 1; out++)
{
min = out;//默认最小的元素为out,也就是剩余元素最左端的索引
//通过循环找到剩余的元素最小的
for (in = out + 1; in < a.length; in++)
if (a[in] < a[min]) // if min greater,
min = in; // we have a new min
swap(a,out, min); // swap them
}
}
/**
* 交换
* @param a
* @param one
* @param two
*/
private void swap(int[] a,int one, int two) {
int temp = a[one];
a[one] = a[two];
a[two] = temp;
}
public static void main(String[] args) {
int[] arr = {3,5,2,7,9,8,6};
Select select = new Select();
select.sort(arr);
select.display(arr);
}
/**
* 打印数组
* @param arr
*/
public void display(int[] arr){
for (int i=0;i < arr.length;i++){
System.out.print(arr[i]);
if (i == (arr.length-1)){
System.out.print(" \n");
}else{
System.out.print(" ");
}
}
}
}
3、插入排序
大多数情况下,插入排序是基本排序中最好的一种。插入排序将数组分为已排好序的部分和未排好序的部分,将未排好序的部分最左侧的数据拿出和已排好序的数据进行比较,然后找到合适的位置插入。重复这个过程,直到未排序部分的数据为空为止。
示例代码:
public class Insert {
/**
* 在插入排序中
* 在外层for循环中,out变量从1开始向右移动,它标记了未被排序的数据最左端的数据
* 在内层循环中,通过控制in遍历已排好序的元素和value比较,直到找到插入的位置
*/
public void sort(int[] a) {
for (int out = 1; out < a.length; out++){
int value = a[out]; // remove marked item
int in = out - 1; // start shifts at out
//查找插入的位置
for(;in >= 0; -- in){
if(a[in] > value){
a[in + 1] = a[in];//将a[in] 移动到a[out]这个位置
}else{
break;//跳出循环,已找到插入位置为 in+1
}
}
a[in + 1] = value; // 插入元素
}
}
public static void main(String[] args) {
int[] arr = {3,5,2,2,9,8,6};
Insert insert = new Insert();
insert.sort(arr);
insert.display(arr);
}
/**
* 打印数组
* @param arr
*/
public void display(int[] arr){
for (int i=0;i < arr.length;i++){
System.out.print(arr[i]);
if (i == (arr.length-1)){
System.out.print(" \n");
}else{
System.out.print(" ");
}
}
}
}