Java之排序算法-插入排序、快速排序、选择排序、归并排序、基数排序

一、直接插入排序(Straight Insertion Sort)

基本操作是,将一个记录插入到一个已经排好序的有序表中,从而得到一个新的、记录数增加1的有序表。一般情况下直接在原数组上进行操作即可。

public void insertSort(int[] nums) {
	for(int i = 1;i < nums.length;i++) {
	    int val = nums[i];
		//1、找到nums[i]要插入的位置
		int j = i-1;
		while(j >= 0 && nums[j] > val) 
			j--;
		if(j == i-1)//说明不用移动元素
			continue;
		//2、移动元素
		for(int t = i-1;t > j;t--)
			nums[t+1] = nums[t];
		//3、插入元素
		nums[j+1] = val;
	}
}

算法分析:插入排序的基本操作为比较和移动元素,时间复杂度为O(n^2),并且为稳定排序,在排序的过程中不会改变原本就有序的元素的相对位置。

二、冒泡排序

冒泡排序就是,将第一元素与第二个元素进行比较,若为逆序则交换,然后继续比较第二个与第三个,依次类推。每躺排序都会将一个最值放到其相应的位置。例如,从升序时,每趟排序,均会将最大值放到后面去

public void bubbleSort(int[] nums) {
	for(int i = 0;i < nums.length -1 ;i++) {
		for(int j = 0;j < nums.length -1 - i;j++) {
			if(nums[j] < nums[j+1]) {
				int temp = nums[j+1];
				nums[j+1] = nums[j];
				nums[j] = temp;
			}
		}
	}
}

算法分析:冒泡排序需要进行比较和交换,时间复杂度为O(n^2),且是稳定排序

三、快速排序(Quick Sort)

通过一趟排序将待排记录分割成独立的两个部分,其中一部分记录的关键字均比另一部分记录的关键字小,再分别对这两部分记录继续进行排序。具体操作为:设置两个指针low和high,设置枢轴关键字为pivotkey,则首先从high所指位置起向前搜索找到第一个关键字小于pivotkey的记录和pivotkey互相交换,然后从low所指位置起向后搜索,找到第一个关键字大于pivokey的记录与pivokey互相交换,重复这两个步骤,直到low=high,就完成了一趟排序,pivoykey就在其排序后的位置。再分别对左边和右边进行快速排序

public void quickSort(int[] nums,int low,int high) {
	if(low == high || low > high)
		return;//说明仅有一个值
	int temp1 = low;
	int temp2 = high;
	int pivotkey = nums[low];
	//进行一趟排序
	while(low < high) {
		while(low < high && nums[high] >= pivotkey) {//从high开始找比pivotkey小的数
			high--;
		}
		nums[low] = nums[high];//找到后与pivotkey交换
		while(low < high && nums[low] <= pivotkey) {//从low开始找比pivotkey小的数
			low++;
		}
		nums[high] = nums[low];
	}
	nums[low] = pivotkey;
	//退出循环时候low=high
	quickSort(nums,temp1,low-1);//左边的
	quickSort(nums,low+1,temp2);//右边的
}

算法分析:快排主要是比较,时间复杂度为O(nlogn),且是不稳定的排序。

四、选择排序(selection Sort)

选择排序的基本思想:每一躺在n-i-1个记录中选取关键字最小的记录作为有序序列的第i个记录

public void selectSort(int[] nums) {
	for(int i = 0;i < nums.length-1;i++) {
		int min = nums[i];
		int index = i;
		for(int j = i+1;j < nums.length;j++) {
			if(nums[j] < min) {
				min = nums[j];
				index = j;
			}	
		}
		nums[index] = nums[i];
		nums[i] = min;	
	}
}

算法分析:主要是比较,时间复杂度为O(n^2),是不稳定的排序

五、归并排序(Merging Sort)

归并就是将两个或者两个以上的有序表组合成一个新的有序表。

//归并排序
public void mergeSort(int nums[]) {
	if(nums.length < 2)
		return;
	int mid = nums.length / 2;
	int[] left = new int[mid];
	int[] right = new int[nums.length - mid];
	for(int i = 0; i < mid;i++)
		left[i] = nums[i];
	for(int i = mid;i < nums.length;i++)
		right[i-mid] = nums[i];
	//对分解的数组 进一步分解
	mergeSort(left);
	mergeSort(right);
	//当不能再分解时合并
	merge(left,right,nums);
}
//将两个数组合并
private void merge(int[] array1,int[] array2,int[] arrayNew) {
	//int[] arrayNew = new int[array1.length + array2.length];
	int i = 0;
	int j = 0;
	int k = 0;
	while(i < array1.length && j < array2.length) {
		if(array1[i] <= array2[j]) {
			arrayNew[k] = array1[i];
			i++;
		}else {
			arrayNew[k] = array2[j];
			j++;
		}
		k++;
	}
	//一定有一组数已经结束
	for(;i < array1.length;i++) {
		arrayNew[k] = array1[i];
		k++;
	}
	for(;j < array2.length;j++) {
		arrayNew[k] = array2[j];
			k++;
	}
}

算法分析:时间复杂度为O(nlogn),是稳定排序

六、堆排序

七、基数排序

八、上述排序性能比较表

排序方法平均时间复杂度最坏时间复杂度稳定性
插入排序   
冒泡排序   
快速排序   
选择排序   
归并排序   
堆排序   
基数排序   

未完待续。。。。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值