三大简单排序算法(java)
2016-02-06 23:42
393 查看
排序是日常生活中最常见的数据处理应用之一,排序算法也是算法学习中的基础课程之一,从最基础的三大排序算法开始,开始算法学习之路吧。
准备工作:为了便于进行算法验证,先将在类ArraySort中封装一个int型的数组,并提供insert、display等方法。
1.冒泡排序
冒泡排序,顾名思义就是像气泡冒起一样,把无序数组中最大的数据项冒起到无序数组的顶端并固定其位置,每遍历无序数组一次,就能固定一个数据项的位置,无需数组长度减一,循环进行这个操作直到数组中无序的部分长度为0为止。
冒泡算法实现如下:
整个算法包括2层循环,外层循环out表示需要“冒泡”的次数,从数组结尾开始,到数组第二个元素结束(因为无序数组长度减小到1时,这部分实际上已经是有序的了),内层循环表示每次数据项需要“冒泡”到达的位置,从0开始,到out结束。整个算法过程中,数组中下标大于out的部分是有序的。
进行数据验证(后2种排序算法可采用同样的验证方法)
public class ArraySortApp {
public static void main(String[] args){
int maxSize = 10;
ArraySort arr = new ArraySort(maxSize);
for(int i=0;i<10;i++){
int value = (int)(Math.random()*99);
arr.insert(value);
}
System.out.print("The origin array is:");
arr.display();
arr.bubbleSort();
System.out.print("The sorted array is:");
arr.display();
}
}
效率:算法总共要进行N*(N-1)/2次比较运算,平均要进行N²/4次交换操作。
2.选择排序
选择排序的核心思想是遍历数组中无序的部分,从中找出最小的一个数据项,和数组这部分钟最左边的数据项交换位置。
整个算法包含2层循环,外层循环out从0开始,到数组的倒数第二个元素结束(同冒泡排序一样,当数组中无序的部分长度为1时,这部分实际上是有序的),内层循环in从out开始,到数组结尾结束,找到其中最小的数据项的下标,和第out项交换位置。整个算法过程中,数组中下标小于out的部分是有序的。
效率:算法总共要进行N*(N-1)/2次比较运算,进行不到N次交换操作。
3.插入排序
插入排序是从数组第二个元素开始,以当前数据项为枢纽,下标小于此数据项的部分是相对有序的,大于部分是未处理的,将当前数据项插入到有序的部分中,并将枢纽下标+1,重复上述操作。
效率:算法平均要进行N*(N-1)/4次比较运算,复制的次数约等于比较的次数。
以上3种排序算法,平均情况下的算法复杂度都是O(n²),但实际情况中其效率仍存在差异。冒泡排序是最基础的排序算法,其逻辑是最为简单易懂的;选择排序相较于冒泡排序,在比较次数相同的情况下,明显减少了交换次数,当交换数据比比较数据更耗时的情况下,选择排序是更好的选择;插入排序虽然复制操作的时间复杂度也是O(n²),但相较于数据交换也减少了2/3的操作(复制只需要1步,交换需要3步),此外插入排序在处理基本有序的数据时,是更好的选择(基本有序的数组,会明显减少插入排序的内层循环次数),因此插入排序也经常应用于一些高级排序算法的最后阶段中。
准备工作:为了便于进行算法验证,先将在类ArraySort中封装一个int型的数组,并提供insert、display等方法。
<pre name="code" class="java">public class ArraySort { private int[] a; private int nElems;//数组长度 public ArraySort(int max){ a = new int[max]; nElems = 0; } public void insert(int value){ if(nElems<a.length){ a[nElems] = value; nElems++; }else{ throw new ArrayIndexOutOfBoundsException("The array is full"); } } public void display(){ for(int j=0; j<nElems; j++){ System.out.print(a[j] + " "); } System.out.println(); } private void swap(int ind1, int ind2){ int temp = a[ind1]; a[ind1] = a[ind2]; a[ind2] = temp; } }
1.冒泡排序
冒泡排序,顾名思义就是像气泡冒起一样,把无序数组中最大的数据项冒起到无序数组的顶端并固定其位置,每遍历无序数组一次,就能固定一个数据项的位置,无需数组长度减一,循环进行这个操作直到数组中无序的部分长度为0为止。
冒泡算法实现如下:
<pre name="code" class="java">public void bubbleSort(){ int out,in; for(out=nElems-1; out>1; out--){ for(in=0; in<out; in++){ if(a[in]>a[in+1]){ swap(in, in+1); } } } }
整个算法包括2层循环,外层循环out表示需要“冒泡”的次数,从数组结尾开始,到数组第二个元素结束(因为无序数组长度减小到1时,这部分实际上已经是有序的了),内层循环表示每次数据项需要“冒泡”到达的位置,从0开始,到out结束。整个算法过程中,数组中下标大于out的部分是有序的。
进行数据验证(后2种排序算法可采用同样的验证方法)
public class ArraySortApp {
public static void main(String[] args){
int maxSize = 10;
ArraySort arr = new ArraySort(maxSize);
for(int i=0;i<10;i++){
int value = (int)(Math.random()*99);
arr.insert(value);
}
System.out.print("The origin array is:");
arr.display();
arr.bubbleSort();
System.out.print("The sorted array is:");
arr.display();
}
}
效率:算法总共要进行N*(N-1)/2次比较运算,平均要进行N²/4次交换操作。
2.选择排序
选择排序的核心思想是遍历数组中无序的部分,从中找出最小的一个数据项,和数组这部分钟最左边的数据项交换位置。
public void selectSort(){ int out,in,min; for(out=0; out<nElems-1; out++){ min = out; for(in=out; in<nElems; in++){ if(a[in]<a[min]){ min = in; } } if(min!=out){ <pre name="code" class="java" style="font-size:18px;"><span style="white-space:pre"> </span>swap(min, out);}}}
整个算法包含2层循环,外层循环out从0开始,到数组的倒数第二个元素结束(同冒泡排序一样,当数组中无序的部分长度为1时,这部分实际上是有序的),内层循环in从out开始,到数组结尾结束,找到其中最小的数据项的下标,和第out项交换位置。整个算法过程中,数组中下标小于out的部分是有序的。
效率:算法总共要进行N*(N-1)/2次比较运算,进行不到N次交换操作。
3.插入排序
插入排序是从数组第二个元素开始,以当前数据项为枢纽,下标小于此数据项的部分是相对有序的,大于部分是未处理的,将当前数据项插入到有序的部分中,并将枢纽下标+1,重复上述操作。
public void insertSort(){ int out,in; int temp; for(out=1; out<nElems; out++){ temp = a[out]; in = out; while(in>0&&a[in-1]>=temp){ a[in] = a[in-1]; in--; } a[in] = temp; } }整个算法依旧是包含2层循环,外层循环从数组第二个元素开始,直到数组结束;内层循环in从out开始递减,知道出现小于枢纽项元素的数据项为止,然后把枢纽项数据插入到这个位置,从这个位置到枢纽项下标-1位置的元素全部右移一位。
效率:算法平均要进行N*(N-1)/4次比较运算,复制的次数约等于比较的次数。
以上3种排序算法,平均情况下的算法复杂度都是O(n²),但实际情况中其效率仍存在差异。冒泡排序是最基础的排序算法,其逻辑是最为简单易懂的;选择排序相较于冒泡排序,在比较次数相同的情况下,明显减少了交换次数,当交换数据比比较数据更耗时的情况下,选择排序是更好的选择;插入排序虽然复制操作的时间复杂度也是O(n²),但相较于数据交换也减少了2/3的操作(复制只需要1步,交换需要3步),此外插入排序在处理基本有序的数据时,是更好的选择(基本有序的数组,会明显减少插入排序的内层循环次数),因此插入排序也经常应用于一些高级排序算法的最后阶段中。
相关文章推荐
- JavaScript演示排序算法
- 算法之排序算法的算法思想和使用场景总结
- PHP版本常用的排序算法汇总
- php 地区分类排序算法
- js三种排序算法分享
- Javascript中的常见排序算法
- java 合并排序算法、冒泡排序算法、选择排序算法、插入排序算法、快速排序算法的描述
- 排序算法的javascript实现与讲解(99js手记)
- C++中十种内部排序算法的比较分析
- Java实现几种常见排序算法代码
- 浅谈javascript实现八大排序
- PHP常用的排序和查找算法
- JavaScript中九种常用排序算法
- STl中的排序算法详细解析
- 算法学习入门之使用C语言实现各大基本的排序算法
- PHP四种基本排序算法示例
- 排序算法之PHP版快速排序、冒泡排序
- JavaScript排序算法之希尔排序的2个实例
- Java常用排序算法及性能测试集合
- Java中常用的6种排序算法详细分解