各种排序算法Java代码实现

一、冒泡排序

​
public static void bubbleSort(int[] arr){
		if(arr == null || arr.length < 2) return;
		for(int end = arr.length - 1; end > 0; end--){
			for(int i = 0; i < end; i++){
				if(arr[i] > arr[i + 1]){
					swap(arr, i, i + 1);
				}
			}
		}
	}
	
public static void swap(int[] arr, int i, int j){
		int tmp = arr[i];
		arr[i] = arr[j];
		arr[j] = tmp;
}

​

二、选择排序

    /*
	 * 数组长为n
	 * 排0~n-1,最小的放0
	 * 排1~n-1,最小的放1
	 * 排2~n-1,最小的放2
	 * ....
	 */
	public static void selectSort(int[] arr){
		if(arr == null || arr.length < 2) return;
		//外层0~n-1
		for(int i = 0; i < arr.length - 1; i++){
			//最小的从0~n-1开始
			int minIndex = i;
			for(int j = i + 1; j < arr.length; j++){
				if(arr[j] < arr[minIndex]){
					minIndex = j;
				}
			}
			swap(arr, i, minIndex);
		}
	}
	
	public static void swap(int[] arr, int i, int j){
		int tmp = arr[i];
		arr[i] = arr[j];
		arr[j] = tmp;
	}

三、插入排序

    public static void insertSort(int[] arr){
		if(arr == null || arr.length < 2) return ;
		//从下标为1的开始往后走
		for(int i = 1; i < arr.length; i++){
			//j每次比i小1,然后比较,前面的比后面的大,则不停的交换
			for(int j = i - 1; j >= 0 && arr[j] > arr[j + 1]; j--){
				swap(arr, j, j + 1);
			}
		}
	}
	
	public static void swap(int[] arr, int i, int j){
		arr[i] = arr[i] ^ arr[j];
		arr[j] = arr[i] ^ arr[j];
		arr[i] = arr[i] ^ arr[j];	
	}

四、快速排序

    /**
	 * 
	 * @param arr
	 * @param start
	 *            递归排序时开始的位置
	 * @param end
	 *            递归排序时结束的位置
	 */
	public static void quickSort(int[] arr, int start, int end) {
		if (start < end) {

			// 找到标准数,一般为第0个
			int stard = arr[start];
			// 记录需要排序的下标
			int low = start;
			int high = end;
			// 循环找比标准数大的数和比标准数小的数
			while (low < high) {
				// 高标志的数字比标准数大
				while (low < high && stard <= arr[high]) {
					high--;
				}
				// 高标志的数字比标准数小,则用高标志的数字替换左边的数字,即低标志的数字
				arr[low] = arr[high];
				// 低标志数字比标准数小
				while (low < high && arr[low] <= stard) {
					low++;
				}
				// 低标志的数字大于标准数,将低标志数赋给高标志数
				arr[high] = arr[low];
			}
			// 循环后标准数所在位已经不是标准数,将标准数赋给低标志所在的元素
			arr[low] = stard;
			// 处理所有的小的数字,递归
			quickSort(arr, start, low);
			// 处理所有的大的数字,递归
			quickSort(arr, low + 1, end);
		}
	}

五、归并排序

    /**
	 * 1.先合并两个数组,处理数组使两个数组有序
	 * @param arr 数组
	 * @param low 从哪里开始
	 * @param middle 从哪里分割,指向小数组的最后一个
	 * @param high 从哪里结束
	 */
	public static void merge(int[] arr, int low, int middle, int high){
		//用于存储归并后的临时数组
		int[] temp = new int[high - low + 1];
		//用于记录第一个数组中需要遍历的下标,两段
		int i = low;
		int j = middle + 1;
		//记录在临时数组中的存放下标
		int index = 0;
		//遍历两段数组,取出小的数字放入临时数组中
		while(i <= middle && j <= high){
			if(arr[i] < arr[j]){
				temp[index++] = arr[i++];				
			}else{
				temp[index++] = arr[j++];
			}
		}
		//一段数组放完,处理另一段多余的数据
		while(j <= high){
			temp[index++] = arr[j++];
		}
		while(i <= middle){
			temp[index++] = arr[i++];
		}
		//把临时数组中数据重新存到原数组
		for (int k = 0; k < temp.length; k++) {
			arr[k + low] = temp[k];
		}
	}
	
	// 递归的排序两段(主调方法)
	public static void mergeSort(int[] arr, int low, int high) {
		if (low == high) {
			return;
		}
		int middle = (low + high) / 2;
		// 处理左边
		mergeSort(arr, low, middle);
		// 处理右边
		mergeSort(arr, middle + 1, high);
		// 排序后归并
		merge(arr, low, middle, high);

	}
    //堆排序
	public static void heapSort(int[] arr){
		if(arr == null || arr.length < 2) return;
		//1.调整为大顶堆
		for (int i = 0; i < arr.length; i++) {
			heapInsert(arr, i);
		}
		int heapSize = arr.length;
		//2.交换堆上0位置的数和堆上最后一个位置的数,并且使堆的大小减1
		swap(arr, 0, --heapSize);
		while(heapSize > 0){
			//3.
			heapify(arr, 0, heapSize);
			swap(arr, 0, --heapSize);
		}
	}

	/**
	 * 调整为大顶堆
	 * @param arr
	 * @param index 调整过程中要交换的位置
	 */
	public static void heapInsert(int[] arr, int index) {
		//index为当前位置,父节点位置为(index - 1) / 2
		while(arr[index] > arr[(index - 1) / 2]){
			swap(arr, index, (index - 1) / 2); 
			index = (index - 1) / 2;
		}
	}
	
	/**
	 * 
	 * @param arr
	 * @param index 从哪个位置开始heapify
	 * @param heapSize 堆一共的大小(不是数组的大小)
	 */
	public static void heapify(int[] arr, int index, int heapSize) {
		int left = (index * 2) + 1;
		while(left < heapSize){
			//left+1是右孩子
			//给出孩子中较大的孩子的下标
			int largest = left + 1 < heapSize && arr[left + 1] > arr[left] ? left + 1 :             left; 
			//左右两个孩子的较大的值如果大于当前的值,孩子的下标赋给largest,即 我和我的孩子,    
 哪个大,哪个作为largest
			largest = arr[largest] > arr[index] ? largest : index;
			//如果父节点依旧是最大的,不用交换了,直接break
			if(largest == index){
				break;
			}
			//此时说明我孩子的某一个值比我的值要大,那个孩子的位置是largest
			swap(arr, largest, index);
			//原来的index位置被换到了largest位置,要从largest继续往下走,要换回来
			index = largest;
			//此时的左孩子的位置变了,要更新为下一次while使用
			left = index * 2 + 1;
		}
	}

	public static void swap(int[] arr, int i, int j){
		arr[i] = arr[i] ^ arr[j];
		arr[j] = arr[i] ^ arr[j];
		arr[i] = arr[i] ^ arr[j];
	}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值