经典排序算法之冒泡、选择和插入排序

来源:互联网 发布:mysql主键有什么用 编辑:程序博客网 时间:2024/05/18 11:03

排序算法学了好久了,今天再来复习一下。毕竟是很经典的排序算法。

1 冒泡排序

算法描述

  设待排序记录序列中的记录个数为n
  一般地,第i趟起泡排序从1到n-i+1
  依次比较相邻两个记录的关键字,如果发生逆序,则交换之。
  其结果是这n-i+1个记录中,关键字最大的记录被交换到第n-i+1的位置上,最多作n-1趟。

算法实现:

package cn.hncu.sortAlgorithm;public class SortMethods1 {/* * 算法好坏的评价指标: * 1.时间复杂度,就是算法运行的快慢(时间)-----通常用计算机的运算(算术,赋值)次数来代替 * 2.空间复杂度,占用内存空间的大小------通常用程序中使用了多少变量(栈内存,堆内存),这些变量总共占了多少内存 */public static void main(String[] args) {int a[]={5,8,-3,11,7,28,95,-12,8};//8个数//1.冒泡排序//1.1普通的冒泡排序//bubbleSort(a);//1.2带优化的冒泡排序bubbleSort2(a);}  //1.1普通的冒泡排序private static void bubbleSort(int[] a) {for(int i=0;i<a.length-1;i++){//趟数:n-1for(int j=0;j<a.length-i-1;j++){//让第j个和第j+1个数进行比较,违反需求则交换。j:0->j:n-i-1if(a[j]>a[j+1]){swap(a,j,j+1);}}}}//1.2 冒泡排序(优化)----只要发现一趟走下来没有一次交换那么就认为已经排好序,后面的数就无需再遍历了private static void bubbleSort2(int[] a) {for(int i=0;i<a.length-1;i++){boolean isOk=true;for(int j=0;j<a.length-i-1;j++){if(a[j]>a[j+1]){swap(a,j,j+1);isOk=false;}}if(isOk) break;}}

算法评价


2 选择排序

算法描述

  首先通过n-1次比较,从n个数中找出最小的,将它与第一个数交换——第一趟选择排序,结果最小的数被安置在第一个元素位置上。
  再通过n-2次比较,从剩余的n-1个数中找出关键字次小的记录,将它与第二个数交换——第二趟选择排序。
  重复上述过程,共经过n-1趟排序后,排序结束。

算法实现:

//2.选择排序//2.1 选择排序的类似思维但性能不好----例如排手机//selectSort0(a);//2.2 真正的选择排序selectSort(a);//2.1 选择排序的类似思维但性能不好private static void selectSort0(int[] a) {for(int i=0;i<a.length-1;i++){for(int j=i+1;j<a.length;j++){if(a[i]>a[j]){swap(a,i,j);}}}}//2.2 选择排序private static void selectSort(int[] a) {for(int i=0;i<a.length-1;i++){int k=i;for(int j=i+1;j<a.length;j++){if(a[k]>a[j]) k=j; //要用a[k]和a[j]依次作比较,找出最小的那个}//经过上面的循环,第k个元素一定是当前(从第i个元素到最后这些元素中)最小的if(i!=k) swap(a,i,k);}}

算法评价


3 插入排序

算法描述:

  记录存放在数组R[0….n-1]中,排序过程的某一中间时刻,R被划分成两个子区间R[0…i-1]和R[i….n-1],其中:前一个子区间是已排好序的有序区;后一个子区间则是当前未排序的部分。

基本操作:

  将当前无序区的第1个记录R[i]插入到有序区R[0….i-1]中适当的位置,使R[0…i]变为新的有序区。

操作细节:

  当插入第i(i≥1)个对象时, 前面的r[0], r[1], …, r[i-1]已经排好序。

  用r[i]的关键字与r[i-1],r[i-2], …的关键字顺序进行比较(和顺序查找类似),如果小于,则将r[x]向后移动(插入位置后的记录向后顺移);找到插入位置即将r[i]插入。

算法实现:

//3. 插入排序//3.1 简单插入排序//insertSort(a);// 3.1 简单插入排序private static void insertSort(int[] a) {//依次把每个元素拿来插入到有序序列当中(从第二个开始,到最后就行)for(int i=0;i<a.length-1;i++){//待插入的数int temp=a[i+1];//下面的这一段是决定temp所在的位置(j+1)以及 让比temp大的数往后挪动一个位置int j=i;//System.out.println(a[j]+".."+temp+".."+a[temp]);while(a[j]>temp){//如果有序数列中 第j位置的数 比待插入的数 大,则把a[j]往后挪动一个位置a[j+1]=a[j];// a[j] 挪到了a[j+1]的位置j--;if(j<0) break;}//这样找出来的第a[j]数是比temp小的数,所以让temp坐在第j个数的后一个位置:即j+1a[j+1]=temp;}}

3.2 二分插入排序(直接插入排序的优化)

算法描述:

  在直接插入排序的基础上,利用二分(折半)查找算法决策出当前元素所要插入的位置。

    二分查找:找到中间元素,如果中间元素比当前元素大,则当前元素要插入到中间元素的左侧;否则,中间元素比当前元素小,则当前元素要插入到中间元素的右侧。

  找到当前元素的插入位置i之后,把i和high之间的元素从后往前依次后移一个位置,然后再把当前元素放入位置i。

算法实现:

//3.2 加入二分查找的插入排序 //注:二分查找的前提要有序binaryInsertSort(a);//3.2 加入二分查找的插入排序private static void binaryInsertSort(int[] a) {for(int i=0;i<a.length-1;i++){int temp=a[i+1];//用二分查找决定插入的位置int low=0;int high=i;while(low<=high){int mid=(low+high)/2;//用中间位置元素和当前待插入的数(temp)作比较if(a[mid]>temp)//落在左半区high=mid-1;elselow=mid+1;}//上面这段只是找到插入位置//移位:把待插入位置腾出来for(int j=i;j>high;j--){a[j+1]=a[j];}//让temp坐在a[high+1]的位置上或者a[low]的位置上a[low]=temp;}}


亲测都是可以排序成功的哦。


1 0
原创粉丝点击