標籤:退出 插入 一個 部分 問題: int 尋找 -- style
這是一個《演算法導論》上的練習,可將插入排序的總體已耗用時間降至Θ(nlgn),我們先看看插入排序的演算法代碼:
#include <stdio.h>int main(void){ int arr[] = {6,3,1,5,4,2}; int i, j; int temp; for(i = 1; i < sizeof(arr)/sizeof(int); i++) //已耗用時間Θ(n) { temp = arr[i]; j = i - 1; while(j >= 0 && arr[j] > temp) //這裡線性時間進行尋找移動,已耗用時間Θ(n),所以整體已耗用時間Θ(n^2) { arr[j + 1] = arr[j]; j--; } arr[j + 1] = temp; } for(i = 0; i < sizeof(arr)/sizeof(int); i++) printf("%d ", arr[i]); printf("\n"); return 0;}
從代碼可以看出,arr[j] > temp的判斷尋找是在前面所有小於 j 的部分中進行移動和尋找的,而小於的 j 部分都是已經排好序的,因此我們可設計使用二分尋找帶進行更快速的處理。但我的嘗試出現了問題:
/** * 二分法+插入排序 - Θ(nlgn) * */#include <stdio.h>int main(void){ int arr[] = {6,3,1,5,4,2}; int i, j; int mid, left; int temp; left = 0; for(i = 1; i < sizeof(arr)/sizeof(int); i++) { temp = arr[i]; j = i - 1; mid = (left + j) / 2; while(temp > arr[mid + 1] || temp < arr[mid - 1])
//情況是這樣的,比如:進行到 123645,當把4進行比較後,從1236中尋找位置時
//只有當同時不滿足迴圈條件,即 3 < 4 < 6 時,不滿足條件 ,就可以退出了,當前的 mid 就是4可以插入的位置。 { if(arr[mid] > temp) mid = (mid + j) / 2; else if(arr[mid] < temp) mid = (left + mid) / 2; } for(j = i - 1; j >= mid; j--){ //移動要插入的位置以後且小於當前比較數以前的位置 arr[j + 1] = arr[j]; } arr[j] = temp; //把比較數插入其中 } for(i = 0; i < sizeof(arr)/sizeof(int); i++) printf("%d ", arr[i]); printf("\n"); return 0;}
然而,我的嘗試失敗了,代碼看上去好像沒什麼問題,但while還是陷入了死迴圈,不知道什麼原因...這個迴圈條件的判斷難道有什麼問題嗎?我暫時先記錄下來吧,改天再繼續思考這個問題...
二分法插入排序演算法的嘗試