/** * 基本二分查找算法 */ int binarySearch(int a[], int n, int t) { int l = 0, u = n - 1; while (l <= u) { int m = l (u - l) / 2; // 同(l u)/ 2,这里是为了防溢出 if (t > a[m]) l = m 1; else if (t < a[m]) u = m - 1; else return m; } return -(l 1); }
/** * 二分查找第一次出现位置 */ int binarySearchFirst(int a[], int n, int t) { int l = -1, u = n; while (l 1 != u) { /*循环不变式a[l]<t<=a[u] && l<u*/ int m = l (u - l) / 2; //同(l u)/ 2 if (t > a[m]) l = m; else u = m; } /*assert: l 1=u && a[l]<t<=a[u]*/ int p = u; if (p>=n || a[p]!=t) p = -1; return p; }
/** * 二分查找最后一次出现位置 */ int binarySearchLast(int a[], int n, int t) { int l = -1, u = n; while (l 1 != u) { /*循环不变式, a[l] <= t < a[u]*/ int m = l (u - l) / 2; if (t >= a[m]) l = m; else u = m; } /*assert: l 1 = u && a[l] <= t < a[u]*/ int p = l; if (p<=-1 || a[p]!=t) p = -1; return p; }
/** * 二分查找第一次和最后一次出现位置 */ int binarySearchFirstAndLast(int a[], int n, int t, int firstFlag) { int l = 0; int u = n - 1; while(l <= u) { int m = l (u - l) / 2; if(a[m] == t) { //找到了,判断是第一次出现还是最后一次出现 if(firstFlag) { //查询第一次出现的位置 if(m != 0 && a[m-1] != t) return m; else if(m == 0) return 0; else u = m - 1; } else { //查询最后一次出现的位置 if(m != n-1 && a[m 1] != t) return m; else if(m == n-1) return n-1; else l = m 1; } } else if(a[m] < t) l = m 1; else u = m - 1; } return -1; }
/** * 旋转数组查找-两次二分查找 */ int binarySearchRotateTwice(int a[], int n, int t) { int p = findRotatePosition(a, n); //找到旋转位置 if (p == -1) return binarySearchFirst(a, n, t); //如果原数组有序,则直接二分查找即可 int left = binarySearchFirst(a, p 1, t); //查找左半部分 if (left != -1) return left; //左半部分找到,则直接返回 int right = binarySearchFirst(a p 1, n-p-1, t); //左半部分没有找到,则查找右半部分 if (right == -1) return -1; return right p 1; //返回位置,注意要加上p 1 } /** * 查找旋转位置 */ int findRotatePosition(int a[], int n) { int i; for (i = 0; i < n-1; i ) { if (a[i 1] < a[i]) return i; } return -1; }
/** * 旋转数组二分查找-一次二分查找 */ int binarySearchRotateOnce(int a[], int n, int t) { int l = 0, u = n-1; while (l <= u) { int m = l (u-l) / 2; if (t == a[m]) return m; if (a[m] >= a[l]) { //数组左半有序 if (t >= a[l] && t < a[m]) u = m - 1; else l = m 1; } else { //数组右半段有序 if (t > a[m] && t <= a[u]) l = m 1; else u = m - 1; } } return -1; }