排序算法小结

排序算法

在这里插入图片描述

1冒泡排序算法

1.1 原理

从序列的头部开始,依次比较相邻两个数的值,若逆序,则交换两个数的位置。一轮下来,尾部的数的位置可以确定为极值(若顺序为从小到大,即为最大值)。第二轮开始,最后一个数据则不用参与交换,第二轮可以确定除最后一个数外的极值(若顺序为从小到大,即为第二大的值)。依此类推,则可以进行n-1(n为序列的大小)轮排序后,序列为有序。

1.2 代码实现

//定义一个长度为80000的随机数组
int[] arr = new int[80000];
        for (int i = 0; i < 80000; i++) {
            arr[i] = (int) (Math.random() * 8000000);
        }
//定义一个标志,用于判断是否进行了交换。若一轮中未进行交换,则代表此时序列已经有序,可以提前结束排序        
boolean flag = false;
//定义一个暂时保存数值的对象
int temp = 0;
//外循环为冒泡排序轮次,共需进行n-1轮,故进行n-1次循环;因为每一轮需要判断交换的次数是递减的,故使用i自减的形式
for (int i = arr.length - 1; i > 0; i--) {
	//内循环为每一轮的比较
    for (int j = 0; j < i; j++) {
    	//判断是否需要交换(这里按从小到大排序)
        if (arr[j] > arr[j + 1]) {
            flag = true;//将是否进行交换的标志状态赋值为true
            temp = arr[j];
            arr[j] = arr[j + 1];
            arr[j + 1] = temp;
        }
    }
    //如果未进行过交换,直接跳出循环
    if (!flag) {
        break;
    } else {
        flag = false;
    }
}

2. 选择排序算法

2.1 原理

先从数组中找到符合顺序的数,然后按照规定交换位置
例如在一个长度为n的数组arr中,按照从小到大排序的步骤为:

  1. 第1次从arr[0]~arr[n-1]中找到最小的数,将其与arr[0]上的数交换位置;
  2. 第2次从arr[1]~arr[n-1]中找到最小的数,将其与arr[1]上的数交换位置;
  3. 第n-1次从arr[n-2]~arr[n-1]中找到最小的数, 将其与arr[n-2]上的数交换位置.

2.2 代码实现


public static void main(String[] args) {
	//总共进行n-1次交换,做n-1次循环
	for (int i = 0; i < arr.length-1; i++) {
		//定义目标位置的索引
	    int minIndex = i;
	    int min = arr[i];
	    //找到指定范围内要找的最小值
	    for (int j = i+1; j < arr.length; j++) {
	        if(min > arr[j]){
	            minIndex=j;
	            min=arr[j];
	        }
	    }
	    //判断是否需要进行交换
	    if(minIndex!=i) {
	        arr[minIndex] = arr[i];
	        arr[i] = min;
	    }
	}
}

3. 插入算法

3.1 原理

把n个元素看成一个有序表和一个无序表,有序表内只有一个元素,将无序表的元素依次按照规则插入到有序表中。
例如在长度为n的数组arr中,按照从小到大排序的步骤为:

  1. 第1步将arr[0]看为有序表,arr[1]~arr[n-1]为无序表,将arr[1]与arr[0]的数据进行比较,若逆序,则交换位置,可以将此步骤视为判断arr[1]的数据应当排在arr[0]上数据的前面还是后面;
  2. 第2步将arr[0]~arr[1]看为有序表,arr[2] ~arr[n-1]为无序表,将arr[2]与arr[1]的数据进行比较,若逆序,则交换位置,并且继续与arr[0]进行比较;
  3. 以此类推,第n-1步时进行最后一个数据的插入。

3.2 代码实现

public static void insertSort(int[] arr){
	//共进行n-1次插入,故做n-1次循环
   for (int i = 1; i < arr.length; i++) {
   		//定义插入值和插入目标(即要进行比较的目标)的索引
        int insertVal = arr[i];
        int insertIndex = i - 1;
        //如果插入位置在插入目标前面,则要与下一个目标进行比较,直到全比较完或插入位置在目标后面
        while (insertIndex >= 0 && insertVal<arr[insertIndex]){
            arr[insertIndex+1]=arr[insertIndex];
            insertIndex--;
        }
        arr[insertIndex+1]=insertVal;
    }
}

4 希尔排序算法

4.1 原理

希尔排序是将插入排序改进后的更高效的一个版本,把元素按照一定增量分组,随着增量逐渐减少,每组包含的元素越来越多,当增量减至1时,进行最后一次排序。

4.2 代码实现

 public static void shellSort(int[] arr){
    int temp = 0;
     int count = 0;
     for (int gap = arr.length/2;gap>0;gap/=2){
         for (int i = gap;i<arr.length;i++){
             for(int j= i-gap;j>=0;j-=gap){
                 if(arr[j]>arr[j+gap]){
                     temp =arr[j];
                     arr[j]= arr[j+gap];
                     arr[j+gap]=temp;
                 }
             }
         }
     }
}
public static void shellSort2(int[] arr){
    for (int gap = arr.length/2;gap>0;gap/=2){
        for (int i = gap; i < arr.length; i++) {
            int j=i;
            int temp=arr[j];
            if(arr[j]<arr[j-gap]){
                while (j-gap>=0&&temp<arr[j-gap]){
                    arr[j]=arr[j-gap];
                    j-=gap;
                }
                arr[j]=temp;
            }
        }
    }
}

5 快速排序算法

5.1 原理

快速排序是对冒泡排序的一种改进。基本思路为:通过一趟排序将一组元素分为两部分,其中一部分元素比另一部分元素都小,
然后对这两部分都分别进行快速排序,整个排序过程可以递归进行,以此完成整个排序。
例:将一组元素中的中间元素为基准,把比它小的数放到左边,比它大的数放在右边,即可完成一次分组。

5.2 代码实现

public static void quickSort(int[] arr,int left,int right){
    int l = left;
    int r = right;
    int pivot = arr[(left+right)/2];
    int temp = 0;
    while (1<r){
        while (arr[l]<pivot){
            l+=1;
        }
        while (arr[r]>pivot){
            r-=1;
        }
        if(l>=r){
            break;
        }
        temp = arr[l];
        arr[l]=arr[r];
        arr[r]=temp;
        if(arr[l]==pivot){
            r-=1;
        }
        if(arr[r]==pivot){
            l+=1;
        }
    }
    if(l==r){
        l+=1;
        r-=1;
    }
    if(left<r){
        quickSort(arr, left,r);
    }
    if(right>l){
        quickSort(arr, l,right);
    }
}

6 归并排序算法

6.1 原理

归并排序是利用归并的思想实现的排序算法,采用经典的分治策略。先将问题分成小问题然后递归求解,治则是将各个小问题的解修补在一起。
例如:
分阶段:将8个元素分成2组,每组4个元素,再将4个元素分为2组,每组2个元素,再将2个元素分为2组,每组1一个元素。
治阶段:将分开的2组数合并成一组数,合并过程要排序。将8组元素合并成4组,合并4次,形成4组有序数组;将4组有序数组合并成2组,合并2次,形成2个有序数组;将2组元素合并成一组,合并一次,形成一个有序数组。

6.2 代码实现

public static void mergeSort(int[] arr,int left,int right,int[] temp){
    if(left<right){
        int mid = (left+right)/2;
        mergeSort(arr,left,mid,temp);
        mergeSort(arr,mid+1,right,temp);
        merge(arr,left,mid,right,temp);
    }
}
public static void merge(int[] arr,int left,int mid,int right,int[] temp){
    int i = left;
    int j = mid+1;
    int t = 0;
    while (i<=mid&&j<=right){
        if(arr[i]<=arr[j]){
            temp[t] = arr[i];
            t+=1;
            i+=1;
        }else {
            temp[t] = arr[j];
            t+=1;
            j+=1;
        }
    }
    while (i<=mid){
        temp[t] = arr[i];
        t+=1;
        i+=1;
    }
    while (j<=right){
        temp[t] = arr[j];
        t+=1;
        j+=1;
    }
    t=0;
    int tempLeft =left;
    while (tempLeft<=right){
        arr[tempLeft]=temp[t];
        t+=1;
        tempLeft+=1;
    }
}

7 基数排序算法

7.1 原理

建立10个桶,每个桶按顺序给定0~9十个下标。将要排序的数组按顺序放入桶内。
放入规则为:
第一轮以个位上的数为准,放入对应下标的桶内,全部放入后,按桶的下标顺序取出并放回数组(桶内的取出规则为先放的先取)
第二轮则以十位上的数为准,以此类推,即经过最大数的最高位的位数的轮次后,完成排序。
代码实现时,创建一个二位数组代表桶,创建一个一维数组代表桶内的指针。

7.2 代码实现

public static void radixSort(int[] arr){
    int max = arr[0];
    for (int i = 0; i < arr.length; i++) {
        if(arr[i]>max){
            max=arr[i];
        }
    }
    int maxLength = (max+"").length();


    int[][] bucket = new int[10][arr.length];
    int[] bucketElementCounts = new int[10];

    for (int i = 0,n=1; i < maxLength; i++,n*=10) {
        for (int j = 0; j < arr.length; j++) {
            int digitOfElement = arr[j]/n%10;
            bucket[digitOfElement][bucketElementCounts[digitOfElement]] = arr[j];
            bucketElementCounts[digitOfElement]++;
        }
        int index = 0;
        for(int k=0;k<bucketElementCounts.length;k++){
            if(bucketElementCounts[k]!=0){
                for (int l = 0; l < bucketElementCounts[k]; l++) {
                    arr[index++] = bucket[k][l];
                }
            }
            bucketElementCounts[k]=0;
        }
    }


}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值