七种排序算法的具体实现(Java)

排序算法根据不同的算法思想往往有很多不同的实现。近期,个人整理了常见的七种算法,并用java对各个算法进行了具体实现,包括:插入排序、冒泡排序、选择排序、shell排序、归并排序、快速排序以及堆排序。

一、插入排序

算法步骤:

从第二个数值开始依次往后遍历。将第k个数值放到前面已经排好序的k-1个数值的合适位置。所谓的合适位置(以从小到大排序为例)就是该位置的前一个数值小于number[k],而后一个位置的数值大于number[k]。

移动方法,依次比较k-1到0的所有数值,如果number[k]小于它前一个位置的数,就交换两个数的位置。

过程示例:

核心代码:

	//插入排序
	public static int[] insertSort(int[] number){
		for(int i=1;i<number.length;i++){
			int processPosition=i;
			for(int j=i-1;j>=0;j--){
				if(number[processPosition]<number[j]){
					int temp=number[processPosition];
					number[processPosition]=number[j];
					number[j]=temp;
					processPosition=j;
				}
				else break;
			}
		}	
		return number;
	}

二、冒泡排序

算法步骤:

总共进行n-1趟(n为数组长度)。每一趟都能取出未排序序列中的最小值,然后放到未排序序列的最前面,也就是第k趟取出的是整个序列中第k小的值。

移动方法,从最后一个数往前移动,比较相邻两个位置上数的大小,如果number[k]小于number[k-1],就交换两个数值的位置。

过程示例:

核心代码:

	//冒泡排序
	public static int[] bubblingSort(int[] number){
		for(int i=0;i<number.length;i++){
			for(int j=number.length-1;j>i;j--){
				if(number[j]<number[j-1]){
					int temp=number[j];
					number[j]=number[j-1];
					number[j-1]=temp;
				}
			}
		}
		return number;
	}

三、选择排序

算法过程:

过程和冒泡排序差不多,只不过它只做最后的那次交换。

过程示例:

核心代码:

	//选择排序
	public static int[] chooseSort(int[] number){
		for(int i=0;i<number.length;i++){
			int minValuePosition=number.length-1;
			for(int j=number.length-2;j>=i;j--){
				if(number[minValuePosition]>number[j]){
					minValuePosition=j;
				}
			}
			int temp=number[i];
			number[i]=number[minValuePosition];
			number[minValuePosition]=temp;
		}
		return number;
	}

四、shell排序

算法步骤:

选择一个初始增量,对距离为该增量的数值序列进行插入排序。不断缩小增量,不断进行插入排序。直到增量为1,最后进行一次排序后终止,即可得到结果。

过程示例:

核心代码:

	//shell排序
	public static int[] shellSort(int[] number){
		//选择增量
		for(int i=number.length/2;i>=1;i=i/2){
			for(int j=0;j<i;j++){
				insSort(number,j,i);
			}
		}
		return number;
	}
	//shell排序中的插入排序
	private static int[] insSort(int[] number,int start, int inc) {
		for(int i=start;i<number.length;i+=inc){
			int processPosition=i;
			for(int j=i-1;j>=start;j-=inc){
				if(number[processPosition]<number[j]){
					int temp=number[j];
					number[j]=number[processPosition];
					number[processPosition]=temp;
					processPosition=j;
				}
				else break;
			}
		}
		return number;
	}

五、归并排序

算法步骤:

基于二分法的思想,每次都把待排序列划分为两个部分,对两个部分进行排序。运行递归不断缩小待排序列的规模,终止条件为待排序列大小为1时。当两个部分已排好序时,对其进行合并,依次比较两个部分的最小值,取出更小的数值存入临时数组中。

过程示例:

核心代码:

        //归并排序
	public static void mergeSort(int[] number,int start,int len){
		if(len==1) return; 
		int half=start+len/2-1;
		mergeSort(number,start,len/2);
		mergeSort(number,half+1,len/2);
		merge(number,start,len);
	}
	//归并排序的数组合并函数
	private static void merge(int[] number, int start, int len) {
		System.out.println("合并后的数组:"+start+" "+len);
		int leftstart=start;
		int leftend=start+len/2-1;
		int rightstart=start+len/2;
		int rightend=start+len-1;
		int[] temp=new int[len];
		int position=0;
		while(position<temp.length){
			if((leftstart<=leftend)&&(rightstart<=rightend)){
				if(number[leftstart]<number[rightstart]){
					temp[position]=number[leftstart];
					position++;
					leftstart++;
				}
				else{
					temp[position]=number[rightstart];
					position++;
					rightstart++;
				}
			}
			else if(leftstart>leftend){
				for(int i=rightstart;i<=rightend;i++){
					temp[position]=number[i];
					position++;
				}
				break;
			}
			else if(rightstart>rightend){
				for(int i=leftstart;i<=leftend;i++){
					temp[position]=number[i];
					position++;
				}
				break;
			}
		}
		for(int i=0;i<len;i++){
			number[start+i]=temp[i];
		}
	}

六、快速排序

算法思想:

确定一个轴值。把在轴值左边并且比它大的数据放到它的右边,把在轴值右边并且比它小的数据放到左边。

过程示例:

核心代码:

	//快速排序
	public static void qSort(int[] number,int start,int end){
		if(end<=start) return;
		int devided=partition(number,start,end);
		qSort(number,start,devided-1);
		qSort(number,devided+1,end);
	}
	//排序的核心代码
	private static int partition(int[] number, int start, int end) {
		int half=(end-start)/2+start;
		int l=start,r=end;
		while(l<r){
			while((number[l]<=number[half])&&(l<end)){
				 l++;
			}
			while((r>l)&&(number[r]>=number[half])) r--;
			swap(number,l,r);
		}
		if(((l<half)&&(number[l]>number[half]))||((l>half)&&(number[l]<number[half]))){
			//改变轴值的位置
			swap(number,l,half);
		}
		return l;
	}
	//交换函数
	private static void swap(int[] number, int i, int j) {
		int temp=number[i];
		number[i]=number[j];
		number[j]=temp;
	}

七、堆排序

堆排序由于需要建树,比较复杂。这里只给我的测试代码,堆的构建和具体的算法思想可以看我的另一篇博客:《堆的实现(数据结构)》

测试代码:

                //测试代码
		ArrayList<Node>nodeList=new ArrayList();
		nodeList.add(new Node(1,"A"));
		nodeList.add(new Node(9,"B"));
		nodeList.add(new Node(3,"C"));
		nodeList.add(new Node(6,"D"));
		nodeList.add(new Node(7,"E"));
		
		Heap heap=new Heap(nodeList);
		
		heap.buildHeap();
		System.out.println("当前的堆结构");
		for(int i=0;i<heap.length();i++){
			System.out.println(heap.nodeList.get(i).key+"-"+heap.nodeList.get(i).value);
		}
		System.out.println("堆排序后的结果");
		int max=heap.length();
		for(int j=0;j<max;j++){
			Node result=heap.removeFirst();
			System.out.println(result.key+result.value);
		}	

 

整个程序完整的代码较长,这里就不放上来了,有需要的可以留言。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章