二分查找

 

1 //二分查找

2 int binarySearch(int arr[], int len, int key)

3 {

4 int left = 0;

5 int right = len - 1;

6 int mid;

7

8 while (left <= right) {

9 mid = (left + right) / 2;

10 if (key < arr[mid]) {//key在左边

11 right = mid - 1;

12 } else if (arr[mid] < key) {//key在右边

13 left = mid + 1;

14 } else {

15 return mid;

16 }

17 }

18 return -1;

19 }

 

 

二分查找变形

随着二分查找的进行,如果找到key并不结束循环的话,最终的结束状态会是right < left,并且right + 1 = left。

当数组中存在key时,根据二分区间选择的不同,这里又分为两种情况,如下图(key为2时),

当数组中不存在key时,最后仅有一种情况,即把图中的黄色框框去掉。

那么,可以找到

1 最后一个小于key的元素,1,

2 第一个大于等于key的元素,2,

3 最后一个小于等于key的元素,2,

4 第一个大于key的元素,5,

另外,如果存在多个key时,稍加判断,就可以找到

5 第一个与key相等的元素

6 最后一个与key相等的元素

 

1 查找最后一个小于key的元素

1 //1 查找最后一个小于key的元素

2 int findLastLess(int arr[], int len, int key)

3 {

4 int left = 0;

5 int right = len - 1;

6 int mid;

7

8 while (left <= right) {

9 mid = (left + right) / 2;

10 if (key <= arr[mid]) {

11 right = mid - 1;

12 } else {

13 left = mid + 1;

14 }

15 }

16 return right;

17 }

View Code

2 查找第一个大于等于key的元素

1 //2 查找第一个大于等于key的元素

2 int findFirstGreaterEqual(int arr[], int len, int key)

3 {

4 int left = 0;

5 int right = len - 1;

6 int mid;

7

8 while (left <= right) {

9 mid = (left + right) / 2;

10 if (key <= arr[mid]) {

11 right = mid - 1;

12 }

13 else {

14 left = mid + 1;

15 }

16 }

17 return left;

18 }

View Code

3 查找最后一个小于等于key的元素

1 //3 查找最后一个小于等于key的元素

2 int findLastLessEqual(int arr[], int len, int key)

3 {

4 int left = 0;

5 int right = len - 1;

6 int mid;

7

8 while (left <= right) {

9 mid = (left + right) / 2;

10 if (key < arr[mid]) {

11 right = mid - 1;

12 } else {

13 left = mid + 1;

14 }

15 }

16 return right;

17 }

View Code

4 查找第一个大于key的元素

1 //4 查找第一个大于key的元素

2 int findFirstGreater(int arr[], int len, int key)

3 {

4 int left = 0;

5 int right = len - 1;

6 int mid;

7

8 while (left <= right) {

9 mid = (left + right) / 2;

10 if (key < arr[mid]) {

11 right = mid - 1;

12 }

13 else {

14 left = mid + 1;

15 }

16 }

17 return left;

18 }

View Code

5 查找第一个与key相等的元素

1 //5 查找第一个与key相等的元素

2 int findFirstEqual(int arr[], int len, int key)

3 {

4 int left = 0;

5 int right = len - 1;

6 int mid;

7

8 while (left <= right) {

9 mid = (left + right) / 2;

10 if (key <= arr[mid]) {

11 right = mid - 1;

12 } else {//arr[mid] < key

13 left = mid + 1;

14 }

15 }

16 //arr[right] < key <= arr[left]

17 //right是最后一个小于key的

18 //left是第一个大于等于key的

19 if (left < len && arr[left] == key) {

20 return left;

21 }

22 return -1;

23 }

View Code

6 查找最后一个与key相等的元素

1 //6 查找最后一个与key相等的元素

2 int findLastEqual(int arr[], int len, int key)

3 {

4 int left = 0;

5 int right = len - 1;

6 int mid;

7

8 while (left <= right) {

9 mid = (left + right) / 2;

10 if (key < arr[mid]) {

11 right = mid - 1;

12 } else {//arr[mid] <= key

13 left = mid + 1;

14 }

15 }

16 //arr[right] <= key < arr[left]

17 //right是最后一个小于等于key的

18 //left是第一个大于key的

19 if (right >= 0 && arr[right] == key) {

20 return right;

21 }

22 return -1;

23 }

View Code

 

最后补一张图,辅助理解,

 

怎么记呢?

看到其它博客的总结,也不错,

http://www.cnblogs.com/luoxn28/p/5767571.html

但是我觉得不够清晰好记,这里我总结为:

只要记住上面两幅图就好了,哈哈...

 

其实,只要记住比较符号和返回值,其它的代码都一样,

1 while (left <= right) {

2 mid = (left + right) / 2;

3 if (key ? arr[mid]) {

4 right = mid - 1;

5 } else {

6 left = mid + 1;

7 }

8 }

9 return ?;

 

根据要求的值的位置,先确定比较符号,再确定返回值,

比较符号:左<=,右<

返回值:左right,右left

 

 

贴一个完整的测试代码吧,

1 #include

2 using namespace std;

3

4 //二分查找

5 int binarySearch(int arr[], int len, int key)

6 {

7 int left = 0;

8 int right = len - 1;

9 int mid;

10

11 while (left <= right) {

12 mid = (left + right) / 2;

13 if (key < arr[mid]) {//key在左边

14 right = mid - 1;

15 } else if (arr[mid] < key) {//key在右边

16 left = mid + 1;

17 } else {

18 return mid;

19 }

20 }

21 return -1;

22 }

23

24 //1 查找最后一个小于key的元素

25 int findLastLess(int arr[], int len, int key)

26 {

27 int left = 0;

28 int right = len - 1;

29 int mid;

30

31 while (left <= right) {

32 mid = (left + right) / 2;

33 if (key <= arr[mid]) {

34 right = mid - 1;

35 } else {

36 left = mid + 1;

37 }

38 }

39 return right;

40 }

41

42 //2 查找第一个大于等于key的元素

43 int findFirstGreaterEqual(int arr[], int len, int key)

44 {

45 int left = 0;

46 int right = len - 1;

47 int mid;

48

49 while (left <= right) {

50 mid = (left + right) / 2;

51 if (key <= arr[mid]) {

52 right = mid - 1;

53 }

54 else {

55 left = mid + 1;

56 }

57 }

58 return left;

59 }

60

61 //3 查找最后一个小于等于key的元素

62 int findLastLessEqual(int arr[], int len, int key)

63 {

64 int left = 0;

65 int right = len - 1;

66 int mid;

67

68 while (left <= right) {

69 mid = (left + right) / 2;

70 if (key < arr[mid]) {

71 right = mid - 1;

72 } else {

73 left = mid + 1;

74 }

75 }

76 return right;

77 }

78

79 //4 查找第一个大于key的元素

80 int findFirstGreater(int arr[], int len, int key)

81 {

82 int left = 0;

83 int right = len - 1;

84 int mid;

85

86 while (left <= right) {

87 mid = (left + right) / 2;

88 if (key < arr[mid]) {

89 right = mid - 1;

90 }

91 else {

92 left = mid + 1;

93 }

94 }

95 return left;

96 }

97

98 //5 查找第一个与key相等的元素

99 int findFirstEqual(int arr[], int len, int key)

100 {

101 int left = 0;

102 int right = len - 1;

103 int mid;

104

105 while (left <= right) {

106 mid = (left + right) / 2;

107 if (key <= arr[mid]) {

108 right = mid - 1;

109 } else {//arr[mid] < key

110 left = mid + 1;

111 }

112 }

113 //arr[right] < key <= arr[left]

114 //right是最后一个小于key的

115 //left是第一个大于等于key的

116 if (left < len && arr[left] == key) {

117 return left;

118 }

119 return -1;

120 }

121

122 //6 查找最后一个与key相等的元素

123 int findLastEqual(int arr[], int len, int key)

124 {

125 int left = 0;

126 int right = len - 1;

127 int mid;

128

129 while (left <= right) {

130 mid = (left + right) / 2;

131 if (key < arr[mid]) {

132 right = mid - 1;

133 } else {//arr[mid] <= key

134 left = mid + 1;

135 }

136 }

137 //arr[right] <= key < arr[left]

138 //right是最后一个小于等于key的

139 //left是第一个大于key的

140 if (right >= 0 && arr[right] == key) {

141 return right;

142 }

143 return -1;

144 }

145

146

147 void test()

148 {

149 // int a[] = {0, 1, 2, 3, 4, 5, 6};

150 int a[] = {0, 1, 2, 2, 2, 5, 6};

151 int len = 7;

152 int key = 2;

153

154 int index;

155

156 int i;

157 for (i = 0; i < len; ++i) {

158 printf("%d ", i);

159 }

160 printf("\n");

161 for (i = 0; i < len; ++i) {

162 printf("%d ", a[i]);

163 }

164 printf("\n");

165

166 // index = binarySearch(a, 10, 2);

167 printf("%d binarySearch\n", binarySearch(a, len, key));

168 printf("%d findLastLess\n", findLastLess(a, len, key));

169 printf("%d findFirstGreaterEqual\n", findFirstGreaterEqual(a, len, key));

170 printf("%d findLastLessEqual\n", findLastLessEqual(a, len, key));

171 printf("%d findFirstGreater\n", findFirstGreater(a, len, key));

172 printf("%d findFirstEqual\n", findFirstEqual(a, len, key));

173 printf("%d findLastEqual\n", findLastEqual(a, len, key));

174 }

175

176 int main()

177 {

178 test();

179 return 0;

180 }

View Code

 

推荐文章

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。