8种排序算法

1. 选择排序

两层循环嵌套,0到n-1选出最小的,与第0个交换,缩小集合为1到n-1,选出最小的,与第一个交换……

时间复杂度:O(n2),

空间复杂度:因为中间只增加了两个新变量,存储最小值和下标,所以空间复杂度为O(1)

当数组为已排序状态时,仍需要n次比较,最好的情况仍需要O(n2)

	public static void selectSort(int[] array){
		for(int i = 0; i < array.length; i++){
			int min = array[i];
			int x = i;
			for(int j = i; j < array.length; j++){
				if(array[j] < min){
					min = array[j];
					x = j;
				}				
			}
			array[x] = array[i];
			array[i] = min;
		}
	}

2. 冒泡排序

两两比较,将较大的值放后面,第一次循环结束后,最大值在最后,二次循环后,次大值在倒数第二个……

若某次循环,未发生任何交换,则说明队列已排序。

时间复杂度:O(n2),

空间复杂度:因为中间只增加了一个temp值做辅助,所以空间复杂度为O(1)

当数组为已排序状态时,只需要一次循环,n次比较,最好的情况只需要O(n)

	public static int[] bubbleSort(int[] array) {
		int temp;
		boolean needNextPass = true;
		for (int i = array.length - 1; i > 0 && needNextPass; i--) {
			needNextPass = false;
			for (int j = 0; j < i; j++) {
				if (array[j] > array[j + 1]) {
					temp = array[j];
					array[j] = array[j + 1];
					array[j + 1] = temp;
					needNextPass = true;
				}
			}
		}
		return array;
	}

3. 插入排序

向前面已排号的序列中插入新的值,第二层嵌套里,需要比较值,并向后移动。

时间复杂度: O(n2)

空间复杂度: O(1)

当对已排序数组处理时,第二层嵌套里不需要向后移动,最好的情况时间复杂度为O(n)

	public static void insertSort(int[] array){
		for(int i = 1; i < array.length; i++){
			int currentValue = array[i];
			int j = i - 1;
			while(j >= 0 && array[j] > currentValue){
				array[j + 1] = array[j];
				j--;
			}
			array[j + 1] = currentValue;
		}
	}

4. 归并排序

这是一种递归的排序算法,将数组分成两组,分别排序,再合并一起。排序的总数为n,n/2,n/4,n/8……

排序在合并时,需要使用一个辅助数组。

时间复杂度:O(nlogn)

空间复杂度:O(n)

最好的情况时,即数据已排序的情况,时间复杂度为仍为O(nlogn)

	public static void mergeSort(int[] array) {
		if (array.length > 1){
			int[] firstHalf = new int[array.length / 2];
			System.arraycopy(array, 0, firstHalf, 0, array.length / 2);
			mergeSort(firstHalf);
			
			int[] sceondHalf = new int[array.length - array.length / 2];
			System.arraycopy(array, array.length / 2, sceondHalf, 0, array.length - array.length / 2);
			mergeSort(sceondHalf);
			
			int temp[] = conArray(firstHalf, sceondHalf);
			System.arraycopy(temp, 0, array, 0, temp.length);
					
			
		}

	}

	public static int[] conArray(int[] array1, int[] array2) {
		int m = array1.length;
		int n = array2.length;
		int[] temp = new int[m + n];
		int i = 0,j = 0, k = 0;

		while(i < m && j < n){
			if(array1[i] <= array2[j]){
				temp[k++] = array1[i++];
			}
			else{
				temp[k++] = array2[j++];
			}
		}
		
		while(i < m){
			temp[k++] = array1[i++];
			}
		while(j < n){
			temp[k++] = array2[j++];
			}
		return temp;
	}

5. 快速排序

选择第一个值作为主元,将剩余值分列主元的两边,这时主元的位置是正确的位置,递归的调用这个方法,将所有的值作为主元,确定位置。

时间复杂度: O(nlogn)

空间复杂度: O(1) 不需要辅助数组

最差的情况下,主元将数组分成一个空数组和一个完整数组,时间复杂度为O(n2)

	public static void quickSort(int[] array) {
		quickSort(array, 0, array.length - 1);
	}

	public static void quickSort(int[] array, int first, int last) {
		if (last - first > 0) {
			int pivotIndex = partition(array, first, last);
			quickSort(array, first, pivotIndex - 1);
			quickSort(array, pivotIndex + 1, last);
		}
	}

	public static int partition(int[] array, int first, int last) {
		int pivot = array[first];
		int low = first + 1;
		int high = last;
		while (high > low) {
			while (low <= high && array[low] < pivot)
				low++;

			while (low <= high && array[high] > pivot)
				high--;

			if (high > low) {
				int temp = array[low];
				array[low] = array[high];
				array[high] = temp;
			}

		}
		while (high > first && array[high] >= pivot)
			high--;
		if (pivot > array[high]) {
			array[first] = array[high];
			array[high] = pivot;
			return high;
		} else
			return pivot;
	}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值