排序算法之直接插入排序、选择排序和冒泡排序

来源:互联网 发布:全国房地产数据服务商 编辑:程序博客网 时间:2024/06/01 07:31
/*概述:
 *1.排序有内部排序和外部排序,内部排序是记录在内存中进行排序,而外部排序是因为排序的数据很大,
 * 一次不能容纳全部的排序记录,在排序过程中需要访问外存
 *2.当n较大时,则应采用时间复杂度为O(nlog2n)的排序算法,如快速排序、堆排序和归并排序
 *3.快速排序是目前基于比较的内部排序中被认为最好的方法,当待排序的关键字是随机分布,快速排序的平均时间最短*/

1.直接插入排序(Straight Insertion Sort)


/**
 * 基本思想:
 * 将一个记录插入到已排序好的有序表中,从而得到一个新的、记录数增1的有序表。
 * 即:先将序列的第一个记录看成是一个有序的子序列,然后从第二个记录逐个进行插入,直到整个序列有序为止。
 * 要点:设立哨兵,作为临时存储和判断数组边界之用。
 * 注意:如果碰见一个和插入元素相等的,那么插入元素把想插入的元素放在相等元素的后面。所以,相等元素的前后位置
 * 没有改变,从原来无序序列出去的顺序就是排好序后的顺序,所以插入排序是稳定的。
 */
public class InsertSort {
public static void print(int a[]){
for(int j=0;j<a.length;j++){
System.out.print(a[j]+" ");
}
}
public static void insertSort(int a[]){
for(int i=1;i<a.length;i++){
if(a[i]<a[i-1]){
int j=i-1;
int x=a[i];//设置哨兵,即存储待排序元素
a[i]=a[i-1];//后移一个元素
while(j>-1&&x<a[j]){//查找在有序表的插入位置
a[j+1]=a[j];
j--;//元素后移
}
a[j+1]=x;//插入到正确位置
}
print(a);
System.out.println();
}
}
public static void main(String[] args) {
int[] a={3,1,2,5,7,4,9,6};
insertSort(a);
}

}

2.选择排序(Select Sort)


package com.java.sort;
/**
 * 二元选择排序:简单选择排序每趟只能确定一个元素排序后的定位,
 * 我们可以考虑改进为每趟循环确定两个元素(当前趟的最大记录和最小记录)的位置,
 * 从而减少排序所需的循环次数。改进后对n个数据进行排序,最多只需要进行n/2趟循环即可。
 */
public class SelectSort {
public static void print(int a[]){
for(int j=0;j<a.length;j++){
System.out.print(a[j]+" ");
}
}
public static void selectSort(int[] a){
int n=a.length;
for(int i=1;i<=n/2;i++){
//分别记录最大值和最小值的位置
int minIndex=i;
int maxIndex=i;
for(int j=i+1;j<=n-i;j++){
if(a[j]>a[maxIndex]){
maxIndex=j;
}
if(a[j]<a[minIndex]){
minIndex=j;
}
}
int temp1=a[i-1];
a[i-1]=a[minIndex];
a[minIndex]=temp1;

int temp2=a[n-i];
a[n-i]=a[maxIndex];
a[maxIndex]=temp2;
}
print(a);
}
public static void main(String[] args) {
int[] a={3,1,2,5,7,4,9,6};
selectSort(a);
}
}

3.冒泡排序(Bubble Sort)


package com.java.sort;
/**
 * 在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,
 * 让较大的数往下沉,较小的往上冒。即:每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换。
 */
public class BubbleSort {
public static void print(int a[]){
for(int j=0;j<a.length;j++){
System.out.print(a[j]+" ");
}
}
public static void bubbleSort(int[] a){
int n=a.length;
for(int i=0;i<n-1;i++){
for(int j=0;j<n-i-1;j++){
if(a[j]>a[j+1]){
int temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
print(a);
}
/**
* 冒泡排序改进一:设置一标志性变量pos,用于记录每趟排序中最后一次进行交换的位置,
* 由于pos位置之后的记录均已交换到位,故在进行下一趟排序时只要扫描到pos位置即可。
* @param a
*/
public static void bubbleSort1(int[]a){
int n=a.length;
int i=n-1;
if(i>0){
int pos=0;//每趟记录开始时,无记录交换
for(int j=0;j<i;j++){
if(a[j]>a[j+1]){
pos=j;//记录交换的位置
int temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
i=pos;//为下一趟排序做准备
}
}
print(a);
}
/**
* 冒泡排序改进二:传统冒泡排序中每一趟只能找到一个最大值或者最小值,我们考虑利用在每趟排序中进行正向
* 和反向两遍冒泡的方法一次可以得到两个最终值(最大值和最小值),从而使排序趟数几乎减少一半。
* @param a
*/
public static void bubbleSort2(int[] a){
int low=0;
int high=a.length-1;
if(low<high){
for(int j=low;j<high;j++){//正向冒泡,找最大值
if(a[j]>a[j+1]){
int temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
--high;
}
for(int j=high;j>low;j--){//反向冒泡,找最小值
if(a[j]<a[j-1]){
int temp=a[j];
a[j]=a[j-1];
a[j-1]=temp;
}
++low;
}
}
print(a);
}
public static void main(String[] args) {
int[] a={3,1,2,5,7,4,9,6};
bubbleSort(a);
System.out.println();
bubbleSort1(a);
System.out.println();
bubbleSort2(a);
}
}

阅读全文
1 0
原创粉丝点击