Stellen Sie sich das wirklich einfachen Fall, dass Sie nur zwei Elemente in der Liste haben
A = [1 3]
und rufen Sie Ihre BinarySearch
auf einem item
, die in der Mitte der Liste liegen würde. Schauen Sie sich die Kommentare unten, die folgen, wie Sie Ihre Funktion verhält ...
BinarySearch(A, 1, 2, 2)
% mid = 1
% item ~= A(1): go to else
% item > A(1): go to else
% BinarySearch(A, 1, 2, 2)
% ... rinse and repeat
Wenn Ihr item
zu klein
BinarySearch(A, 1, 2, 0)
% mid = 1
% item ~= A(1): go to else
% item < A(1)
% BinarySearch(A, 1, 1, 0)
% mid = 1
% beg <= last (this is still true)
% item ~= A(1): go to else
% item < A(1)
% BinarySearch(A, 1, 1, 0)
% ... rinse and repeat
war
Ebenso für eine item
, der größer ist als alle in der Liste enthalten ist,
BinarySearch(A, 1, 2, 5)
% leads to BinarySearch(A, 1, 2, 5)
% ... repeat!!
Sie überprüfen immer wieder die gleiche Region, weil Sie links (beg
) und rechts (last
) Indizes dürfen beide gleich bleiben.
Lassen Sie uns neu implementieren die Funktion, einen tatsächlichen Wert zurückkehrt, anstatt nur die Position auch auf der Konsole ausdrucken. Die Kommentare beziehen sich direkt auf die nummerierten Schritte in der Wikipedia article for binary search, die in ihrer Struktur ähnlich sieht, was Sie versucht haben:
function idx = BinarySearch(A, L, R, item)
%% BINARYSEARCH search for an item in the array A. Assumes that A is sorted ascending
% 1. Should be initially called using idx = BinarySearch(A, 1, n, item)
% where n is the number of elements in A, numel(A)
% 2. if L > R, the search terminates as unsuccessful
if L > R
idx = 0;
else
% 3. set m (position of middle element) to the floor of (L+R)/2
m = floor((L+R)/2);
% 4. if Am < item, set L to m+1 and go to 2.
if A(m) < item
L = m + 1; % YOU MISSED THIS STEP, CAUSING OVERLAPPING SEARCH REGIONS
idx = BinarySearch(A, L, R, item);
% 5. if Am > item, set R to m-1 and go to 2.
elseif A(m) > item
R = m - 1; % THE OTHER HALF OF THE STEP YOU MISSED
idx = BinarySearch(A, L, R, item);
% 6. Now Am = item, search is done, return index
else
idx = m;
end
end
end
Tests mit A
wie zuvor:
BinarySearch(A, 1, 2, 2); % returns 0: not found
BinarySearch(A, 1, 2, 0); % returns 0: not found
BinarySearch(A, 1, 2, 5); % returns 0: not found
BinarySearch(A, 1, 2, 3); % returns 2: 3 is at index 2
BinarySearch(A, 1, 2, 1); % returns 1: 1 is at index 1
Beachten Sie, dass es nicht sein kann, am effizientesten, um dies rekursiv zu implementieren. Ich werde es als Übung verlassen, aber dies könnte leicht mit einer while
Schleife statt implementiert werden. Die gleiche logische Struktur würde verwendet werden.
die Funktion zu debuggen, können Sie aus den Werten von 'mid' und' beg' in der Funktion ausdrucken und sehen, was die Ausgaben sind, wenn eine Endlosschleife angetroffen. – mikkola