1. 程式人生 > >直接插入排序,折半插入排序,希爾排序

直接插入排序,折半插入排序,希爾排序

直接插入排序

時間複雜度: 最好 O(n)  最壞 O(n^2) 平均(n^2)

空間複雜度:O(1);

void InsertSort(int *a){//直接插入排序
    int j, temp;
    for(int i = 2; i <= a[0]; i++){
        j = i - 1;
        temp = a[i];
        while( j >= 1 && temp < a[j]){
            a[j+1] = a[j];
            j--;
        }
        a[j+1] = temp;
    }
}

折半插入排序

時間負複雜度 :最好 O(n*log2n) 最壞 O(n^2)平均 O(n^2)

空間複雜度:O(1)

int midFind(int *a, int n, int key){ //折半查詢
    int low, high;
    low = 1;
    high = n;
    while(low <= high){
        int mid = low + (high - low) / 2;
        if(key == a[mid])
            return mid + 1;
        else if(key < a[mid])
            high = mid - 1;
        else
            low = mid + 1;
    }
    return high + 1;
}
void midInsertSort(int *a){ //折半插入
    for(int i = 2; i <= a[0]; i++){
        int temp = a[i];
        int j = midFind(a, i - 1, temp);
        for(int k = i; k > j; k--){
            a[k] = a[k-1];
        }
        a[j] = temp;
    }
}

希爾排序

時間複雜度根據 dk (跳躍距離)而不同:如果每次以增量除以2向下取整 此時為 O(n^2)但是  dk取  2^k - 1 (k為大於等於一的整數) 這時時間複雜度為 O(n^1.5)

空間複雜度 :O(1)

void ShellInsert(int *a, int dk){
	for(int i = dk+1; i <= a[0] ; i++){
		if(a[i] < a[i - dk]){
			int temp = a[i];
			int j = i - dk;
			while( j > 0 && temp < a[j]){
				a[j + dk] = a[j];
				j -= dk;
			}
			a[j+dk] = temp;
		}	
	}
}

void ShellSort(int *a, int *dk){//希爾排序 
    for(int i = 1; i <= a[0]; i++)
	 	 ShellInsert(a, dk[a[0] - i]);
}
int main()
{
    int n;
    cout << "輸入無序陣列的個數 :" << endl;
    cin >> n;
    int *a = new int[n+1];
    a[0] = n;
    
    for(int i = 1; i <= a[0] ; i++){
        cin >> a[i];
    }

    int *dk = new int[a[0] + 1];
    dk[0] = a[0];
    for(int i = 1; i <= dk[0]; i++) //dk是跳躍的距離
        dk[i] = pow(2,i) - 1;
	 	
    ShellSort(a, dk);
	 
    for(int i = 1; i <= a[0]; i++){
        cout << a[i] << " " ;
    }
    cout << endl;
}