程序員必備排序之插入排序、希爾排序

由於最近要找實習單位便在刷算法題,發現許多算法題都涉及到排序的知識所以今天把排序的內容總結一遍備忘。博客中的內容大部分是參考《王道數據結構》

內部排序分爲幾類分別爲:插入排序(直接插入排序、希爾排序),交換排序(冒泡排序、快速排序),選擇排序(簡單選擇排序、堆排序),歸併排序和基數排序。

各大排序的比較如下圖所示:



一、插入排序

1.1直接插入排序

1、思想:基本思想在於每次將一個待排序的記錄,按其關鍵字大小插入到前面已經排好序的子序列中,直到全部記錄插入完成。
2、代碼實現
package sort;
public class insertSort {
	public insertSort(int[] a){
		int temp = 0;
		for(int i=1;i<a.length;i++){
			int j=i-1;			//j表示已排序好的最後一個數
			temp = a[i];			//temp表示待插入的數字
			for(;j>=0&&a[j]>temp;j--){
				a[j+1]=a[j];
			}
			a[j+1]  = temp;			//此時的j+1表示爲待插入數字的位置
		}
	}
	private void print(int[] a){
		for(int i=0;i<a.length;i++){
			System.out.print(a[i]+" ");
		}
	}
	public static void main(String[] args){
		 int a[]={49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17,18,23,34,15,35};
		 insertSort sort = new insertSort(a);
		 sort.print(a);
	}
}

1.2折半插入排序

1、思想:直接插入排序的過程分倆步,從前面表中查找待插入數據的位置、給插入位置騰出控件插入待插入的元素。折半插入排序即是在第一步上有所改進使用折半查找來尋找待插入數據的位置。
2、代碼實現:
package sort;
public class insertSort2 {
	public insertSort2(int[] a){
		int temp=0,low,high,mid;
		for(int i=1;i<a.length;i++){
			int j = i-1;
			temp=a[i];
			low=0;
			high=i-1;
			while(low<=high){		//使用折半查找待插入數據的位置
				mid = (low+high)/2;
				if(a[i]>a[mid])		low=mid+1;
				else	high=mid-1;
			}
			for(j=i-1;j>=high+1;j--){
				a[j+1]=a[j];
			}
			a[j+1]=temp;
		}
	}
	private void print(int[] a){
		for(int i=0;i<a.length;i++){
			System.out.print(a[i]+",");
		}
	}
	public static void main(String[] args){
		 int a[]={49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17,18,23,34,15};
		 insertSort2 sort = new insertSort2(a);
		 sort.print(a);
	}
}
從上述算法中不難看出折半插入排序僅僅是減少了比較元素的次數而比較次數與待排序的初始狀態無關,僅取決於表中的元素的個數,故折半插入排序的時間複雜度仍爲O(n^2)。

1.3希爾排序(縮小增量排序)

1、思想:先將待排序表分割爲若干個形如L[i,i+d,i+2d,i+3d,...i+kd]的“特殊”的子表,分別進行插入排序,當整個子表已“基本有序”時,再對全體記錄進行一次直接插入排序
2、代碼實現:
package sort;
public class shellSort {
	public shellSort(int[] a){
		double d = a.length;
		while(true){
			d = Math.ceil(d/2.0);
			int dm = (int)d;
			int temp = 0;
			for(int n=0;n<dm;n++){		   //對整體進行增量爲dm的插入排序
			for(int i=n+dm;i<a.length;i+=dm){  //進行一次插入排序
				int j=i-dm;
				temp = a[i];
				for(;j>=0&&a[j]>temp;j-=dm){
					a[j+dm] = a[j]; 
				}
				a[j+dm] = temp;
			}
			}
			if(dm==1)	return ;	    //進行了增量爲1的排序後跳出循環
		}
	}
	private void print(int[] a){
		for(int i=0;i<a.length;i++){
			System.out.print(a[i]+",");
		}
	}
	public static void main(String[] args){
		 int a[]={49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17,18,23,34,15,35};
		 shellSort sort = new shellSort(a);
		 sort.print(a);
	}
}


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