八大排序算法

一、冒泡排序

1.简介

比较相邻的元素。如果第一个比第二个大,就交换他们两个。

对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。

针对所有的元素重复以上的步骤,除了最后一个,即需要进行length-1次。

第一次是对n个数进行n-1次比较,进行到最后第n个的一个是最大的;                                         

第二次是对n-1个数进行n-2次比较,进行到最后第n-1个的一个是最大的;

......

持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
动态图:

 二、代码案例

package com.sort;

import java.util.Arrays;

public class BubbleSort {
	public static void main(String[] args) {
		int[] arr = new int[] { 5, 2, 1, 7, 9, 3, 6, 8, 4 };
		sort(arr);
		System.out.println(Arrays.toString(arr));
	}

	public static void sort(int[] arr) {
		for (int j = 0; j < arr.length; j++) {
			for (int i = 0; i + 1 < arr.length; i++) {
				if (arr[i] > arr[i + 1]) {
					int temp = arr[i];
					arr[i] = arr[i + 1];
					arr[i + 1] = temp;
				}
			}
		}
	}
}

输出结果:

[1, 2, 3, 4, 5, 6, 7, 8, 9]

 二、插入排序

1、简介

插入排序是在一个有序的排列中插入一个元素,默认认为第一个是有序,从后面的元素中比较和前面已经排好序的元素挨个比较,插入合适的位置;因此需要一个循环(外层循环)用来控制元素个数;还需另外一个循环(里层循环)用来控制当前第几个元素后面的元素挨个与前面的有序元素比较,得出插入的合适位置。

二、代码案例

package com.sort;

import java.util.Arrays;

public class InsertSortPlus {
	public static void main(String[] args) {
		int[] num = { 3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48 };
		int j;
		// i=1;从1开始,没必要和自己比
		for (int i = 1; i < num.length; i++) {
			// 记录要插入的值,这时就有了一个长度为i+1的数组可以进行移动
			int temp = num[i];
			System.out.print("第" + i + "次移动的位置:");
			// 在已排序的数组中找到比记录值(temp)要小的值,位置往后移动(记住此时的数组长度(i+1))
			// 要明白为什么往后移动。
			// j >= 0&&num[j] > temp要满足这两个条件,j才会j--;
			for (j = i - 1; j >= 0 && num[j] > temp; j--) {
				System.out.print(j + " ");
				// 符合条件的往后移动一位
				num[j + 1] = num[j];
			}
			System.out.println("\n第" + i + "次移动后的数组:" + Arrays.toString(num) + ",此时j+1的位置为:" + (j + 1));
			// 归位,此时符合条件的都全部移动了一位,此时的j+1就是记录值要插入的位置
			num[j + 1] = temp;
			System.out.println("第" + i + "次交换后的结果:" + Arrays.toString(num));
		}
		System.out.println("最终的排序结果:" + Arrays.toString(num));
	}

}

输出结果:

第1次移动的位置:
第1次移动后的数组:[3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48],此时j+1的位置为:1
第1次交换后的结果:[3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48]
第2次移动的位置:1 
第2次移动后的数组:[3, 44, 44, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48],此时j+1的位置为:1
第2次交换后的结果:[3, 38, 44, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48]
第3次移动的位置:2 1 
第3次移动后的数组:[3, 38, 38, 44, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48],此时j+1的位置为:1
第3次交换后的结果:[3, 5, 38, 44, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48]
第4次移动的位置:
第4次移动后的数组:[3, 5, 38, 44, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48],此时j+1的位置为:4
第4次交换后的结果:[3, 5, 38, 44, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48]
第5次移动的位置:4 3 2 
第5次移动后的数组:[3, 5, 38, 38, 44, 47, 36, 26, 27, 2, 46, 4, 19, 50, 48],此时j+1的位置为:2
第5次交换后的结果:[3, 5, 15, 38, 44, 47, 36, 26, 27, 2, 46, 4, 19, 50, 48]
第6次移动的位置:5 4 3 
第6次移动后的数组:[3, 5, 15, 38, 38, 44, 47, 26, 27, 2, 46, 4, 19, 50, 48],此时j+1的位置为:3
第6次交换后的结果:[3, 5, 15, 36, 38, 44, 47, 26, 27, 2, 46, 4, 19, 50, 48]
第7次移动的位置:6 5 4 3 
第7次移动后的数组:[3, 5, 15, 36, 36, 38, 44, 47, 27, 2, 46, 4, 19, 50, 48],此时j+1的位置为:3
第7次交换后的结果:[3, 5, 15, 26, 36, 38, 44, 47, 27, 2, 46, 4, 19, 50, 48]
第8次移动的位置:7 6 5 4 
第8次移动后的数组:[3, 5, 15, 26, 36, 36, 38, 44, 47, 2, 46, 4, 19, 50, 48],此时j+1的位置为:4
第8次交换后的结果:[3, 5, 15, 26, 27, 36, 38, 44, 47, 2, 46, 4, 19, 50, 48]
第9次移动的位置:8 7 6 5 4 3 2 1 0 
第9次移动后的数组:[3, 3, 5, 15, 26, 27, 36, 38, 44, 47, 46, 4, 19, 50, 48],此时j+1的位置为:0
第9次交换后的结果:[2, 3, 5, 15, 26, 27, 36, 38, 44, 47, 46, 4, 19, 50, 48]
第10次移动的位置:9 
第10次移动后的数组:[2, 3, 5, 15, 26, 27, 36, 38, 44, 47, 47, 4, 19, 50, 48],此时j+1的位置为:9
第10次交换后的结果:[2, 3, 5, 15, 26, 27, 36, 38, 44, 46, 47, 4, 19, 50, 48]
第11次移动的位置:10 9 8 7 6 5 4 3 2 
第11次移动后的数组:[2, 3, 5, 5, 15, 26, 27, 36, 38, 44, 46, 47, 19, 50, 48],此时j+1的位置为:2
第11次交换后的结果:[2, 3, 4, 5, 15, 26, 27, 36, 38, 44, 46, 47, 19, 50, 48]
第12次移动的位置:11 10 9 8 7 6 5 
第12次移动后的数组:[2, 3, 4, 5, 15, 26, 26, 27, 36, 38, 44, 46, 47, 50, 48],此时j+1的位置为:5
第12次交换后的结果:[2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 50, 48]
第13次移动的位置:
第13次移动后的数组:[2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 50, 48],此时j+1的位置为:13
第13次交换后的结果:[2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 50, 48]
第14次移动的位置:13 
第14次移动后的数组:[2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 50, 50],此时j+1的位置为:13
第14次交换后的结果:[2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50]
最终的排序结果:[2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50]

三、快速排序

1、简介

快速排序就是每次找一个基点(第一个元素),然后两个哨兵,一个从最前面往后走,一个从最后面往前面走,如果后面那个哨兵找到了一个比基点大的数停下来,前面那个哨兵找到比基点大的数停下来,然后交换两个哨兵找到的数,如果找不到最后两个哨兵就会碰到一起就结束,最后交换基点和哨兵相遇的地方的元素,然后就将一个序列分为比基点小的一部分和比基点大的一部分,然后递归左半部分和右半部分,最后的结果就是有序的了。

 二、代码案例

public class QuickSort {
    public static void quickSort(int[] arr,int low,int high){
        int i,j,temp,t;
        if(low>high){
            return;
        }
        i=low;
        j=high;
        //temp就是基准位
        temp = arr[low];
 
        while (i<j) {
            //先看右边,依次往左递减
            while (temp<=arr[j]&&i<j) {
                j--;
            }
            //再看左边,依次往右递增
            while (temp>=arr[i]&&i<j) {
                i++;
            }
            //如果满足条件则交换
            if (i<j) {
                t = arr[j];
                arr[j] = arr[i];
                arr[i] = t;
            }
 
        }
        //最后将基准为与i和j相等位置的数字交换
         arr[low] = arr[i];
         arr[i] = temp;
        //递归调用左半数组
        quickSort(arr, low, j-1);
        //递归调用右半数组
        quickSort(arr, j+1, high);
    }
 
 
    public static void main(String[] args){
        int[] arr = {10,7,2,4,7,62,3,4,2,1,8,9,19};
        quickSort(arr, 0, arr.length-1);
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
}

输出:

1  2  2  3  4  4  7  7  8  9  10  19  62  

四、选择排序

1、 简介

每一趟从待排序的数据元素中选择最小(或最大)的一个元素作为首元素,直到所有元素排完为止,简单选择排序是不稳定排序。


二、代码案例

package com.sort;

public class SelectSort {
	public static void main(String[] args) {
		// 模拟数据
		int[] array = { 52, 63, 14, 59, 68, 35, 8, 67, 45, 99 };
		System.out.println("原数组:");
		for (int i : array) {
			System.out.print(i + " ");
		}
		System.out.println();
		selectSort(array);
		System.out.println("排序后:");
		for (int i : array) {
			System.out.print(i + " ");
		}
	}

	public static void selectSort(int[] arr) {
		for (int i = 0; i < arr.length - 1; i++) {
			int min = i;
			for (int j = i + 1; j < arr.length; j++) {
				if (arr[j] < arr[min]) {
					min = j;
				}
			}
			if (min != i) {
				swap(arr, i, min);
			}
		}
	}

	// 完成数组两元素间交换
	public static void swap(int[] arr, int a, int b) {
		int temp = arr[a];
		arr[a] = arr[b];
		arr[b] = temp;
	}
}

输出:

原数组:
52 63 14 59 68 35 8 67 45 99 
排序后:
8 14 35 45 52 59 63 67 68 99 

五、基数排序

1、简介

基数排序就是把数按位考虑,让后我们一位数只能是[0,9],就是我们在考虑某位(个位、百位· · ·)的时候就只看这个位的数,放到在[0,9]相应的位置,然后顺序取出,最后再按其它位这样操作(上面说了要不从低位开始到高位,要不就是从高位到低位)

2、代码案例

package com.sort;

import java.util.Arrays;

public class RadixSort03 {
	public static void main(String[] args) {
		int[] arr = new int[] { 12, 98, 10, 123, 1, 15, 26, 30, 87, 96, 130, 97, 45, 68, 89 };
		sort(arr);
		System.out.println(Arrays.toString(arr));
	}

	public static void sort(int[] arr) {
		// 定义桶
		int[][] bucket = new int[10][arr.length];
		// 定义桶记录器
		int[] elementCounts = new int[10];

		// 找到数组当中的最大值
		int max = arr[0];
		for (int i = 0; i < arr.length; i++) {
			if (arr[i] > max) {
				max = arr[i];
			}
		}

		// 找到最大值的位数
		int maxLength = (max + "").length();

		int n = 1;
		for (int h = 0; h < maxLength; h++) {
			// 向桶内放数据
			for (int i = 0; i < arr.length; i++) {
				// 计算个位的值
				int element = arr[i] / n % 10;// 放入到桶内
				int count = elementCounts[element];
				bucket[element][count] = arr[i];
				elementCounts[element] = elementCounts[element] + 1;
			}
			int index = 0;
			// 将桶内的数据取出
			for (int k = 0; k < elementCounts.length; k++) {
				if (elementCounts[k] != 0) {
					for (int l = 0; l < elementCounts[k]; l++) {
						arr[index] = bucket[k][l];
						index++;
					}
				}
				// 清空桶记录器
				elementCounts[k] = 0;
			}
			n = n * 10;
		}

	}

}

输出:

[1, 10, 12, 15, 26, 30, 45, 68, 87, 89, 96, 97, 98, 123, 130]

六、希尔排序

1、简介

 选定一个增长量h,按照增长量h作为数据分组的依据,对数据进行分组;对分好组的每一组数据完成插入排序;减小增长量,最小减为1,重复第二步操作
 

 2、代码案例

package com.sort;

import java.util.Arrays;

public class ShellSortPlus {
	    public static void main(String[] args) {
	        int[] arr={49,38,65,97,76,13,27,49,78,34};
	        shell(arr);
	    }

	    public static void shell(int[] arr){
	        int temp=0;
	        int count=0;
	        //步长
	        for (int gap= arr.length/2;gap>=1;gap=gap/2){
	            count++;
	            for (int i=gap;i< arr.length;i++){
	                //分组
	                for (int j=i-gap;j>=0;j=j-gap){
	                    if (arr[j]>arr[j+gap]){
	                        temp=arr[j];
	                        arr[j]=arr[j+gap];
	                        arr[j+gap]=temp;
	                    }
	                }
	            }
	            System.out.println("第"+count+"轮排序后的数据:");
	            System.out.println(Arrays.toString(arr));
	        }

	    }
	}

输出:

第1轮排序后的数据:
[13, 27, 49, 78, 34, 49, 38, 65, 97, 76]
第2轮排序后的数据:
[13, 27, 34, 49, 38, 65, 49, 76, 97, 78]
第3轮排序后的数据:
[13, 27, 34, 38, 49, 49, 65, 76, 78, 97]

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值