JavaBase之8种基本排序算法

 8种排序,写了6中,剩下2种后面再补*-*

package sort;

import java.util.Arrays;

public class Sort {

	private static final int[] arr = { 25, 63, 15, 21, 26, 56,45,46,23};

	/*
	 * 冒泡排序: (邻近,两两比较)
	 * 	1. 从0开始到(len-1)都要比较,目的是将最值放入最后(下面,升序,目的则是将最大值依次放入最后)  -> 第一个for
	 * 	2. 比较的具体操作: 两两比较,大的往后移,结果最后就是最大值。
	 * 		a. 长度arr.len-1 :  可以想象5个数,只需要比4次
	 * 		b. 长度arr.len-1-i : 由于i在增1,相反j比较次数就要减1
	 */
	public static void maopao(int[] arr) {
		int tem = 0;
		for (int i = 0; i < arr.length; i++) {
			for (int j = 0; j < arr.length - i - 1; j++) {
				if (arr[j] > arr[j + 1]) {
					tem = arr[j];
					arr[j] = arr[j + 1];
					arr[j + 1] = tem;
				}
			}
		}
	}

	/*
	 * 快速排序:(二分法思想)
	 * 	1. 首先是二分法思想(前后一起走,当前后的下标相等,则说明全部排序完成) -> while
	 * 	2. 具体做法: 从后往前找小于arr[left]值,从前往后找大于arr[left]的值,
	 * 			找到后:
	 * 				a. 前后的下标一致,说明找完了,又因为i=j,所以跳出循环
	 * 				b. 前后的下标不一致,将两个值前后置换(大的去了后面,小的来了前面),又因为i和j没有相遇,说明没有走完,接着while循环
	 * 	3. 做完后,当时的arr[left]应该找到了,它所在的位置: 将while中找到的中间点i,和left置换位置
	 *  4. 递归开始下次排序,
	 *  		分两组:
	 *  			a. (arr, 0, i-1)
	 *  			b. (arr, i+1, arr.len)
	 */
	public static void fast(int a[], int left, int right) {
		int i,j,t;
		
		// 递归调用中,若left>=right,说明达到递归出口,元素已经全部有序
		if (left >= right)
			return;
		// 定义a[left]为切分的基准元素(可优化为随机选取基准元素,消除数据依赖)
		int temp = a[left];
		i = left;
		j = right;
		while (i != j) {	// 若跳出循环,证明i和j相遇
			while (a[j] >= temp && i < j)
				j--;// 从右往左找到需要交换的a[j]位置
			while (a[i] <= temp && i < j)
				i++;// 从左往右找到需要交换的a[i]位置
			if (i < j) { // 满足i<j,交换a[i]和a[j]两个位置
				t = a[i];
				a[i] = a[j];
				a[j] = t;
			}
		} 
		// 此时,需要将基准数tem归位到i==j的那个位置
		a[left] = a[i];
		a[i] = temp;
		// 将已经归为的左边和右边的数,再次递归调用快速排序
		fast(a, left, i - 1);
		fast(a, i + 1, right);
	}

	/*
	 * 选择排序:(查找最值,进行置换)
	 * 	1. 一共排序次数arr.len-1次 ->  第一个for循环   (对于是len次还是len-1,再解释)
	 * 	2. 每次 [i+1,len]找最小值,因为当时默认最小值是arr[i],所以找到的最小值,就是数组中所有数最小值,将最小值,放最前面。
	 * 		这里有两步:		
	 * 			a. 在[i+1,len] 中找到最小值 -> 第二个for循环
	 * 			b. 将i的值和找到最小值置换
	 */
	public static void select(int[] arr) {
		for(int i=0; i<arr.length-1;i++) {  //从第一个开始比较,到最后一个-1
			int min = arr[i];
			for(int j=i+1; j<arr.length;j++) {
				if(min>arr[j]) {
					int temp = min;
					min = arr[j];
					arr[j] = temp;
				}
			}
			
			if(min != arr[i]) {
				int temp = min;
				min = arr[i];
				arr[i] = temp;
			}
		}
	}

	/*
	 * 插入排序:(不断将最值移向数组头部)
	 * 	1. 先把找位置的元素挖出  -> temp=arr[i]
	 * 	2. 从当前元素下标开始找到数组头下标,如果前面1个比当前这个元素大,则前面元素后移一位 -> while()
	 * 	(这里要注意,从头到此刻的过程已经保证次元素前面是排序好的,换句话:不会出现,现在位置是31的这种情况12,13,45,32,31)
	 * 	3. 最后把比找位置的元素大的元素都完后移动后,空出的位置,就是找位置的元素  -> arr[i]=temp
	 */
	public static void insert(int[] arr) {
		int temp;
		for(int i=1; i<arr.length; i++) {
			//找位置的元素,先挖出
			temp = arr[i];
			//如果前面的元素比后面元素大,前面元素后退1,整好把挖出元素所在位置填上
			while(i>=1 && arr[i-1]>temp) {
				arr[i] = arr[i-1];
				i--;
			}
			//如果跳出while循环,说明找位置的元素找到了位置,下标就是当前i
			arr[i]=temp;
		}
	}

	/*
	 * 希尔排序:
	 * 	分两组然后直接插入排序,把插入排序中的分割基值的1改成d。
	 */
	public static void sheel(int[] a) {
		int d = a.length;
		while (d != 0) {
			d = d / 2;
			for (int x = 0; x < d; x++) {// 分的组数
				for (int i = x + d; i < a.length; i += d) {// 组中的元素,从第二个数开始
					int temp = a[i];// 要插入的元素
					while(i>=x+d && arr[i-d]>temp) {
						arr[i] = arr[i-d];
						i-=d;
					}
					a[i] = temp;
				}
				System.out.println(Arrays.toString(a));
			}
		}
	}

	/*
	 * 堆排序:
	 * 	1. 数组->最大堆
	 * 	2. 最大堆的根节点交换末尾子节点,断开交换后的最后节点(将最大元素依次剔除)
	 * 	3. 重复执行1、2,直至所有节点都断开
	 */
	
	/*
	 * 基数排序:
	 * 	依次将数组中的数字从最低位到最后位,依次放入0-9的10个桶中 
	 */
	
	/*
	 * 归并排序:
	 * 	
	 */
	public static void sort(int[] arr, int L, int R) {
	    if(L == R) {
	        return;
	    }
	    int mid = L + ((R - L) >> 1);
	    sort(arr, L, mid);
	    sort(arr, mid + 1, R);
	    merge(arr, L, mid, R);
	}

	public static void merge(int[] arr, int L, int mid, int R) {
	    int[] temp = new int[R - L + 1];
	    int i = 0;
	    int p1 = L;
	    int p2 = mid + 1;
	    // 比较左右两部分的元素,哪个小,把那个元素填入temp中
	    while(p1 <= mid && p2 <= R) {
	        temp[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
	    }
	    // 上面的循环退出后,把剩余的元素依次填入到temp中
	    // 以下两个while只有一个会执行
	    while(p1 <= mid) {
	        temp[i++] = arr[p1++];
	    }
	    while(p2 <= R) {
	        temp[i++] = arr[p2++];
	    }
	    // 把最终的排序的结果复制给原数组
	    for(i = 0; i < temp.length; i++) {
	        arr[L + i] = temp[i];
	    }
	}
	
	/*
	 * 数组中两个数置换
	 */
	public static void swap(int arr[], int i, int j) {
		int temp;
		temp = arr[i];
		arr[i] = arr[j];
		arr[j] = temp;
	}
	
	public static void main(String[] args) {
//		maopao(arr);
//		fast(arr,0,arr.length-1);
//		select(arr);
//		insert(arr);
		System.out.println(">>>>>>>>>"+Arrays.toString(arr)+"<<<<<<<<<\n");
//		sheel(arr);
		sort(arr, 0, arr.length-1);
		System.out.println(Arrays.toString(arr));
	}
	
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值