七種排序算法的具體實現(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);
		}	

 

整個程序完整的代碼較長,這裏就不放上來了,有需要的可以留言。

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