java排序

用java实现冒泡,插入,选择等排序

冒泡排序(优化)

1.思想

从零号下标开始遍历,相邻的两个数相互比较,将最大的数沉底。

这里写图片描述

2.代码

public static void bubbleSort(int[] a) {
		int tmp = 0 ;
		for(int i=0;i<a.length-1;i++) {//a.length-1是因为最后一次只剩一个数不用排
			boolean s=false;//设置标记
			for(int j=0;j<a.length-1-i;j++) {//a.length-i-1是因为每次会有i个数是已经排好了的
				if(a[j]>a[j+1]) {
					tmp=a[j];
					a[j]=a[j+1];
					a[j+1]=tmp;
					s=true;
				}
			}
			if(!s) {//如果循环了一遍 s还没有置位true则说明已排好序 就break退出循环
				break;
			}
		}
	}

3.稳定性

稳定

4.时间复杂度

O(n^2)

选择排序

1.思想

假设零号位为最小值,然后拿零号位与后面的数依次比较,如果大于则交换。将数组遍历一遍以后,第一个值即为最小值。然后再将一号位设为最小值与后面比较。

2.代码

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

3.稳定性

不稳定

4.时间复杂度

O(n^2)

插入排序

1.思想

以零号位开始为一个有序数组,依次加入数组下一位数,加入的这位数从前往后与前面的数比较,使它成为有序数组。如a[0]本身有序;加入下一位啊a[1],对a[0:1]进行排序,假如a[1]< a[0]则交换,交换后a[0:1]有序;加入下一位a[2],将a[0:2]有序,依次加入到数组最后一位,排序后数组有序。

2.代码

public static void insertSort(int[] array){
	int tmp = 0;
	int j;
	for(int i = 1;i < array.length;i++){
		tmp = array[i];
		for(j = i-1;j j>=0;;j--){
			if(array[j] > tmp){
				array[j+1] = array[j];
			}else{
				break;
			}
		}
		array[j+1] = tmp;
	}
	
}


3.稳定性

稳定

4.时间复杂度

O(n^2)

快速排序(递归)

1.思想

任取待排序对象中的某个对象作为基准,按照该对象的关键码大小,将整个对象序列划分为左右两个子序列。其中,左侧子序列中所有的关键码都小于或等于基准对象的关键码;右侧子序列中所有对象的关键码都大于基准对象的关键码。此时基准对象所在的位置也就是该对象在该序列中最终应该安放的位置。然后递归的在左右子序列中重复实施上述的方法,直至所有的对象都放到相应的位置上为止。

2.代码

public static int partion(int[] a, int low,int high) { 
	int tmp = a[low];
	while(low < high) {
		while(low < high && a[high] >= tmp ) {
			--high;
		} 
		if(low >= high) {
			break;
		}else {
			a[low] = a[high];
		}
		while(low < high && a[low] <=tmp) {
			++low;
		}
		if(low >= high) {
			break;
		}else {
			a[high] = a[low];
		}		
	}
	a[low] =tmp;
	return low;
	}
		public static void quick(int[] a,int start,int end) {
		int par = partion(a, start, end);
		if(par > start+1) {
			quick(a,start,par-1);
		}
		if(par < end - 1) {
			quick(a, par+1, end);
		}
	} 

3.稳定性

不稳定

4.时间复杂度

好情况O(nlog2n) 坏O(n2)


快速排序(非递归)

1.思想

递归的快排算法是编译器自动用栈来实现的,当递归层次比较深的时候,需要占用比较大的进程栈空间,会造成进程栈溢出的危险。因此我们可以自己用栈模拟递归过程,即每次从栈顶取出一部分做划分之后,都把新的两部分的起始位置分别入栈。

2.代码

public static int partion(int[] a, int low,int high) { 
	int tmp = a[low];
	while(low < high) {
		while(low < high && a[high] >= tmp ) {
			--high;
		} 
		if(low >= high) {
			break;
		}else {
			a[low] = a[high];
		}
		while(low < high && a[low] <=tmp) {
			++low;
		}
		if(low >= high) {
			break;
		}else {
			a[high] = a[low];
		}		
	}
	a[low] =tmp;
	return low;
	}
	public static void QSort(int[] a) {
		int[] stack = new int[a.length];
		int top = 0;
		int low =0;
		int high = a.length-1;
		int par =partion(a, low, high);
		if(par > low + 1) {
			stack[top++] = low;
			stack[top++] = par - 1;
		}
		if(par < high - 1) {
			stack[top++] = par + 1;
			stack[top++] = high;
		}
		//出栈
		while(top > 0) {
			high = stack[--top];//最后一次入栈top++了,所以这里用--top而不是top--
			low = stack[--top];
			
			
			par = partion(a,low,high);
			
			
			if(par > low+1) {
				stack[top++] = low;
				stack[top++] = par - 1;
			}
			if(par  < high-1) {
				stack[top++] = par+1;
				stack[top++] = high;
			}
		}
	}

3.稳定性

不稳定

4.时间复杂度

o(n log2n )


shell排序(放大版的插入排序)

1.思想

先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2< d1重复上述的分组和排序,直至所取的增量dt=1(dt< dt-l< …< d2< d1),即所有记录放在同一组中进行直接插入排序为止。

2.代码

public static void shell(int[] a,int gap) {
		int tmp = 0;
		int j;
		for(int i = gap;i< a.length;i++) {
			tmp = a[i];
			for(j = i-gap;j >= 0;j=j-gap) {
				if(a[j] > tmp) {
					a[j+gap] = a[j];
				}else {
					break;
				}
			}
			a[j+gap] = tmp;
		}
	}
	
	public static void shellSort(int[] a) {
		int[] d = {7,3,1};
		for(int i = 0;i<d.length;i++) {
			shell(a,d[i]);
		}
	}

3.稳定性

不稳定

4.时间复杂度

O(n^1.3)


堆排序

1.思想

将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了

2.代码

public static void adjust(int[] a,int start,int end) {
		int tmp = a[start];
		for(int i = 2*start+1;i <= end;i = i*2+1) {
			if(i < end && a[i] < a[i+1] ) {//i < end保证有右孩子
				i++;
			}
			if(a[i] > tmp) {
				a[start] = a[i];
				start = i;
			}
			if(a[i] < tmp) {
				break;
			}
		}
		a[start] = tmp;
	}
	public static void heapSort(int[] a) {
		for(int i = (a.length-1-1)/2;i>=0;i--) {
			adjust(a, i, a.length-1);
		}
		//和根节点交换
		int tmp;
		for(int j = 0;j<a.length-1;j++) {
			tmp = a[0];
			a[0] = a[a.length - 1-j];
			a[a.length - 1-j] = tmp;
			adjust(a, 0, a.length-2-j);
		}
	}

3.稳定性

不稳定

4.时间复杂度

O(nlogn)
-----------.

归并排序

1.思想

基本思路就是将数组分成按a[0]和a[2n]开头的两组。然后建立一个临时数组将他们以a[0]<a[2n]的形式存起来。直到2n-0<a.length.
在这里插入图片描述

2.代码

	public static void mergeSort(int[] a) {
		for (int i = 1; i < a.length; i = i * 2) {
			merge(a, i);
		}
	}

	public static void merge(int[] a, int gap) {
		int start1 = 0;
		int end1 = start1 + gap - 1;
		int start2 = end1 + 1;
		int end2 = start2 + gap - 1 < a.length - 1 ? start2 + gap - 1 : a.length - 1;
		int[] tmpa = new int[a.length];
		int i = 0;
		while (start2 < a.length) {
			while (start1 <= end1 && start2 <= end2) {
				if (a[start1] < a[start2]) {
					tmpa[i++] = a[start1++];
				} else {
					tmpa[i++] = a[start2++];
				}
			}
			while (start1 <= end1) {
				tmpa[i++] = a[start1++];
			}
			while (start2 <= end2) {
				tmpa[i++] = a[start2++];
			}
			start1 = end2 + 1;
			end1 = start1 + gap - 1;
			start2 = end1 + 1;
			end2 = start2 + gap - 1 < a.length - 1 ? start2 + gap - 1 : a.length - 1;
		}
		while (i < a.length) {
			tmpa[i++] = a[start1++];
		}
		for(int j = 0;j<a.length;j++) {
			a[j] = tmpa[j];
		}
	}

3.稳定性

稳定

4.时间复杂度

O(nlogn)

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页