關於二分查找的兩個疑問?

  二分查找簡直是簡單的不能再簡單的一個算法了, 很多人入門時幾乎都是踩着二分查找的屍體入門的,那麼這個算法你除了會用,思考過裏邊的一些細節嗎?比如這個爲什麼這樣設計? 那個爲什麼那樣設計?接下來我就帶你重新認識一下這個既熟悉又陌生的二分查找。
  二分查找的大體思路,就是將一個有範圍限定的數****比較次數降低,不再像冒泡排序那樣一個一個的比較,這個降低的比較次數是非常的大的,可以大大提升我們程序的效率。好了,這些估計你們都懂。
先看一個運用二分法的程序:很明顯這是一個求完全平方數的一個程序。

func isPerfectSquare(num int) bool {
	if num == 1 {
		return true
	}
	low, high := 2, num/2
	for low <= high {
		mid := low + (high-low)>>1
		result := mid * mid
		if result == num {
			return true
		} else if result > num {
			high = mid - 1
		} else {
			low = mid + 1
		}
	}
	return false
}

1、你知道在計算mid時爲什麼大多數人要用low + (high-low)>>1這個公式嗎?而不是直接用**(low + high)/2**這個公式嗎?
答案:(1)右移一位,相當於除以2,但右移的運算速度更快
(2)若使用(low+high)/2求中間位置容易溢出
2、你知道爲什麼low = mid + 1,high = mid - 1這樣設計,而不是low = mid,high = mid這樣設計嗎?
你可能會說,當然是爲了進一步的減少比較次數了!
我們先來看一個程序,這個程序的輸出結果和上邊這個程序的輸出結果是相同的。

func isPerfectSquare(num int) bool {
	if num == 1 {
		return true
	}
	low, high := 2, num/2
	for low <= high {
		mid := low + (high-low)>>1
		result := mid * mid
		if result == num {
			return true
		} else if result > num {
			high = mid
		} else {
			if(low == mid){
				return false
			}
			low = mid
		}
	}
	return false
}

如果你仔細看完程序你會發現,在程序中,low = mid,high = mid,我是這樣設計的。
如果下邊這個程序low = mid,high = mid這樣設計,那麼必須要有if(low == mid){return false}這樣一個條件,因爲沒有的話,某些數會造成死循環。所以,我覺得二分查找之所以這樣設計low = mid + 1,high = mid - 1,第一是進一步的減少比較次數,第二個原因是防止由於low = mid,high = mid這樣設計而忘寫那個if判斷條件出現死循環。

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