Làm thế nào để tính toán độ phức tạp của tìm kiếm nhị phân


144

Tôi nghe ai đó nói rằng vì tìm kiếm nhị phân giảm một nửa đầu vào cần thiết để tìm kiếm do đó là thuật toán log (n). Vì tôi không đến từ nền tảng toán học nên tôi không thể liên quan đến nó. Ai đó có thể giải thích nó chi tiết hơn một chút? nó có phải làm gì đó với chuỗi logarit không?


1
điều này có thể giúp bạn: stackoverflow.com/a/13093274/550393
2cupsOfTech

Câu trả lời:


385

Đây là một cách toán học hơn để nhìn thấy nó, mặc dù không thực sự phức tạp. IMO rõ ràng hơn nhiều như những người không chính thức:

Câu hỏi là, bạn có thể chia N bao nhiêu lần cho đến khi bạn có 1? Điều này về cơ bản là nói, thực hiện tìm kiếm nhị phân (một nửa các yếu tố) cho đến khi bạn tìm thấy nó. Trong một công thức, đây sẽ là:

1 = N / 2 x

nhân với 2 x :

2 x = N

Bây giờ làm nhật ký 2 :

log 2 (2 x ) = log 2 N
x * log 2 (2) = log 2 N
x * 1 = log 2 N

điều này có nghĩa là bạn có thể chia log N lần cho đến khi bạn chia mọi thứ. Điều đó có nghĩa là bạn phải chia log N ("thực hiện bước tìm kiếm nhị phân") cho đến khi bạn tìm thấy phần tử của mình.


tôi chỉ tính nó cho t (n) = (2 ^ 2) * K. Làm thế nào để làm cho nó để đăng nhập mẫu?
Shan Khan

1
khái niệm tương tự được giải thích bằng đồ họa: stackoverflow.com/a/13093274/550393
2cupsOfTech

Phần tôi thiếu là, nếu bạn có BST với 7 mục, công thức của nó là gì? log2 (7)? Tôi đã thực hiện một phép tính vũ phu với mọi kết quả có thể, và đi đến một câu trả lời không bằng log2 (7), vậy tôi đang làm gì sai?
Perry Monschau

1
Vì vậy, dễ dàng hơn nhiều so với giải thích cây nhị phân.
NoName

1
Câu trả lời rất hay
VHS

22

Đối với Tìm kiếm nhị phân, T (N) = T (N / 2) + O (1) // mối quan hệ lặp lại

Áp dụng Định lý Masters cho tính toán Độ phức tạp thời gian chạy của quan hệ lặp lại: T (N) = aT (N / b) + f (N)

Ở đây, a = 1, b = 2 => log (cơ sở b) = 1

Ngoài ra, ở đây f (N) = n ^ c log ^ k (n) // k = 0 & c = log (một cơ sở b)

Vậy, T (N) = O (N ^ c log ^ (k + 1) N) = O (log (N))

Nguồn: http://en.wikipedia.org/wiki/Master_theorem


1
tại sao log (cơ sở b) là 1 khi a = 1 và b = 2, không nên là 0?
GAURANG VYAS

16

T (n) = T (n / 2) +1

T (n / 2) = T (n / 4) + 1 + 1

Đặt giá trị của The (n / 2) ở trên để T (n) = T (n / 4) + 1 + 1. . . . T (n / 2 ^ k) + 1 + 1 + 1 ..... + 1

= T (2 ^ k / 2 ^ k) + 1 + 1 .... + 1 lên đến k

= T (1) + k

Khi chúng tôi lấy 2 ^ k = n

K = log n

Vì vậy, độ phức tạp thời gian là O (log n)


10

Nó không mất một nửa thời gian tìm kiếm, điều đó sẽ không làm cho nó đăng nhập (n). Nó giảm nó logarit. Hãy suy nghĩ về điều này trong một thời điểm. Nếu bạn có 128 mục trong một bảng và phải tìm kiếm tuyến tính cho giá trị của mình, có thể sẽ mất trung bình khoảng 64 mục để tìm giá trị của bạn. Đó là n / 2 hoặc thời gian tuyến tính. Với tìm kiếm nhị phân, bạn loại bỏ 1/2 các mục có thể mỗi lần lặp, như vậy, nhiều nhất chỉ mất 7 so sánh để tìm giá trị của bạn (cơ sở đăng nhập 2 của 128 là 7 hoặc 2 với 7 sức mạnh là 128.) Đây là sức mạnh của tìm kiếm nhị phân.


Xin lỗi vì cần thiết nhưng 128 không phải là một cây được lấp đầy. Tôi đã sử dụng một ví dụ cơ bản để hiểu rõ về điều này và tôi thấy rằng 7 mục đồng đều lấp đầy một cây với 3 lớp. Tôi đã tính toán rằng độ phức tạp phải là 17/7 (giá trị trung bình của tổng số so sánh) là 2,43. Nhưng log2 (7) là 2,81. Vậy tôi còn thiếu gì ở đây?
Perry Monschau

Hai câu trả lời - Câu hỏi thứ nhất ở đây: Ngay cả khi không có lỗi trong toán học, chúng ta có thể thấy rằng trung bình 2,43 vẫn tốt hơn trung bình 3,5 đối với tuyến tính và đây là giá trị thấp. Khi bạn nhận được vào 100 mục nhập, log2 () tốt hơn nhiều so với tuyến tính. Tôi nghĩ rằng bạn nhìn thấy điều này mặc dù, vì vậy tiếp theo.
Michael Dorgan

1
Câu trả lời thứ hai: Tôi không chắc bạn thuộc loại cây nào trong đó 7 có tất cả mọi thứ. Khi tôi nghĩ về một cây hoàn hảo gồm 8 mục, tôi thấy một cây sâu 3 cấp với tổng số 8 lá. Trong cây này, bất kể bạn tìm kiếm số nào, phải mất tổng cộng 3 lần so sánh để lấy từ gốc đến lá. Đối với 7 mục, một trong các đường dẫn sẽ mất một so sánh ít hơn 20/7 (6 nút của 3 so sánh, 1 nút của 2 so sánh) là ~ 2,85. Nhật ký 2 (7) là ~ 2,81. Tôi không có nền tảng toán học để giải thích sự khác biệt 0,04, nhưng tôi đoán nó phải làm với việc không có sẵn các bit phân số hoặc một số phép thuật khác :)
Michael Dorgan

số lượng là số lượng lá!? Không phải số lượng nút? Vâng, đó là một thông tin lớn mà tôi đã thiếu .. Có vẻ lạ đối với tôi rằng chức năng này dựa trên các lá, khi mỗi nút phân nhánh cũng là một điểm dừng tiềm năng. Dù sao, cảm ơn vì đã nói thẳng ra cho tôi!
Perry Monschau

5

Độ phức tạp thời gian của thuật toán tìm kiếm nhị phân thuộc về lớp O (log n). Đây được gọi là ký hiệu O lớn . Cách bạn nên diễn giải điều này là sự tăng trưởng tiệm cận của thời gian mà hàm thực hiện để đưa ra một bộ đầu vào có kích thước n sẽ không vượt quá log n.

Đây chỉ là một biệt ngữ toán học chính thức để có thể chứng minh các phát biểu, v.v ... Nó có một lời giải thích rất đơn giản. Khi n phát triển rất lớn, hàm log n sẽ phát triển hết thời gian cần thiết để thực thi hàm. Kích thước của "bộ đầu vào", n, chỉ là độ dài của danh sách.

Nói một cách đơn giản, lý do tìm kiếm nhị phân nằm trong O (log n) là vì nó giảm một nửa bộ đầu vào trong mỗi lần lặp. Dễ dàng hơn để nghĩ về nó trong tình huống ngược lại. Trên các lần lặp x, thuật toán tìm kiếm nhị phân có thể kéo dài bao lâu? Câu trả lời là 2 ^ x. Từ đó, chúng ta có thể thấy rằng điều ngược lại là trung bình thuật toán tìm kiếm nhị phân cần các lần lặp log2 n cho một danh sách có độ dài n.

Nếu tại sao nó là O (log n) chứ không phải O (log2 n), thì đó là vì đơn giản chỉ cần đặt lại - Sử dụng các hằng ký hiệu O lớn không được tính.


4

Đây là mục nhập wikipedia

Nếu bạn nhìn vào phương pháp lặp đơn giản. Bạn chỉ cần loại bỏ một nửa các yếu tố cần tìm kiếm cho đến khi bạn tìm thấy yếu tố bạn cần.

Dưới đây là lời giải thích về cách chúng tôi đưa ra công thức.

Giả sử ban đầu bạn có N số phần tử và sau đó những gì bạn làm là ⌊N / 2⌋ như một lần thử đầu tiên. Trong đó N là tổng của giới hạn dưới và giới hạn trên. Giá trị thời gian đầu tiên của N sẽ bằng (L + H), trong đó L là chỉ mục đầu tiên (0) và H là chỉ mục cuối cùng của danh sách bạn đang tìm kiếm. Nếu bạn may mắn, yếu tố bạn cố gắng tìm sẽ nằm ở giữa [ví dụ. Bạn đang tìm kiếm 18 trong danh sách {16, 17, 18, 19, 20} thì bạn tính (0 + 4) / 2⌋ = 2 trong đó 0 bị ràng buộc thấp hơn (chỉ số L của phần tử đầu tiên của mảng) và 4 là giới hạn cao hơn (chỉ số H - của phần tử cuối cùng của mảng). Trong trường hợp trên L = 0 và H = 4. Bây giờ 2 là chỉ mục của phần tử 18 mà bạn đang tìm kiếm tìm thấy. Chơi lô tô! Bạn đã tìm thấy nó.

Nếu trường hợp là một mảng khác {15,16,17,18,19} nhưng bạn vẫn đang tìm kiếm 18 thì bạn sẽ không gặp may và bạn sẽ thực hiện N / 2 đầu tiên (đó là ⌊ (0 + 4) / 2⌋ = 2 và sau đó nhận ra phần tử 17 ở chỉ số 2 không phải là số bạn đang tìm kiếm. Bây giờ bạn biết rằng bạn không phải tìm kiếm ít nhất một nửa mảng trong lần thử tiếp theo để tìm kiếm cách lặp. Vì vậy, về cơ bản, bạn không tìm kiếm một nửa danh sách các yếu tố mà bạn đã tìm kiếm trước đó, mỗi khi bạn cố gắng tìm yếu tố mà bạn không thể tìm thấy trong lần thử trước.

Vì vậy, trường hợp xấu nhất sẽ là

[N] / 2 + [(N / 2)] / 2 + [((N / 2) / 2)] / 2 .....
tức là:
N / 2 1 + N / 2 2 + N / 2 3 + ..... + N / 2 x ' ..

cho đến khi bạn đã hoàn thành việc tìm kiếm, trong đó phần tử bạn đang cố gắng tìm ở cuối danh sách.

Điều đó cho thấy trường hợp xấu nhất là khi bạn đạt N / 2 x trong đó x sao cho 2 x = N

Trong các trường hợp khác N / 2 x trong đó x sao cho 2 x <N Giá trị tối thiểu của x có thể là 1, đây là trường hợp tốt nhất.

Bây giờ vì trường hợp xấu nhất về mặt toán học là khi giá trị của
2 x = N
=> log 2 (2 x ) = log 2 (N)
=> x * log 2 (2) = log 2 (N)
=> x * 1 = log 2 (N)
=> Chính thức hơn ⌊log 2 (N) + 1⌋


1
Làm thế nào chính xác để bạn có được phiên bản chính thức hơn?
Kalle

Một chức năng sàn được sử dụng. Các chi tiết có trong phần hiệu suất của liên kết wiki ( en.wikipedia.org/wiki/Binary_search_alacticm ) được cung cấp trong câu trả lời.
RajKon


2

Giả sử việc lặp trong Tìm kiếm nhị phân chấm dứt sau k lần lặp. Ở mỗi lần lặp, mảng được chia cho một nửa. Vì vậy, hãy nói rằng độ dài của mảng tại bất kỳ lần lặp nào là n Ở lần lặp 1,

Length of array = n

Ở lần lặp 2,

Length of array = n⁄2

Ở lần lặp 3,

Length of array = (n⁄2)⁄2 = n⁄22

Do đó, sau khi lặp k,

Length of array = n⁄2k

Ngoài ra, chúng ta biết rằng Sau khi chia k, độ dài của mảng trở thành 1 Do đó

Length of array = n⁄2k = 1
=> n = 2k

Áp dụng chức năng đăng nhập ở cả hai bên:

=> log2 (n) = log2 (2k)
=> log2 (n) = k log2 (2)
As (loga (a) = 1)

Vì thế,

As (loga (a) = 1)
k = log2 (n)

Do đó độ phức tạp thời gian của Tìm kiếm nhị phân là

log2 (n)

1

Một tìm kiếm nhị phân hoạt động bằng cách chia đôi vấn đề liên tục, một cái gì đó như thế này (chi tiết bị bỏ qua):

Ví dụ tìm kiếm 3 trong [4,1,3,8,5]

  1. Sắp xếp danh sách các mặt hàng của bạn [1,3,4,5,8]
  2. Nhìn vào mục giữa (4),
    • Nếu đó là những gì bạn đang tìm kiếm, hãy dừng lại
    • Nếu nó lớn hơn, hãy nhìn vào nửa đầu
    • Nếu nó ít hơn, hãy nhìn vào nửa thứ hai
  3. Lặp lại bước 2 với danh sách mới [1, 3], tìm 3 và dừng lại

Nó là một bi tìm kiếm năm khi bạn chia vấn đề thành 2.

Việc tìm kiếm chỉ yêu cầu các bước log2 (n) để tìm giá trị chính xác.

Tôi muốn giới thiệu Giới thiệu về Thuật toán nếu bạn muốn tìm hiểu về độ phức tạp của thuật toán.


1

Vì chúng tôi cắt giảm một nửa danh sách mỗi lần, do đó chúng tôi chỉ cần biết có bao nhiêu bước chúng tôi nhận được 1 khi chúng tôi tiếp tục chia danh sách cho hai. Trong phép tính dưới đây x biểu thị số thời gian chúng ta chia một danh sách cho đến khi chúng ta có được một phần tử (Trong trường hợp xấu nhất).

1 = N / 2x

2x = N

Lấy log2

log2 (2x) = log2 (N)

x * log2 (2) = log2 (N)

x = log2 (N)


1

T (N) = T (N / 2) + 1

T (N) = T (N / 2) + 1 = (T (N / 4) + 1) + 1

...

T (N) = T (N / N) + (1 + 1 + 1 + ... + 1) = 1 + logN (log 2 cơ sở) = 1 + logN

Vì vậy, độ phức tạp thời gian của tìm kiếm nhị phân là O (logN)


0
ok see this
for(i=0;i<n;n=n/2)
{
i++;
}
1. Suppose at i=k the loop terminate. i.e. the loop execute k times.

2. at each iteration n is divided by half.

2.a n=n/2                   .... AT I=1
2.b n=(n/2)/2=n/(2^2)
2.c n=((n/2)/2)/2=n/(2^3)....... aT I=3
2.d n=(((n/2)/2)/2)/2=n/(2^4)

So at i=k , n=1 which is obtain by dividing n  2^k times
n=2^k
1=n/2^k 
k=log(N)  //base 2

0

Hãy để tôi làm cho nó dễ dàng cho tất cả các bạn với một ví dụ.

Để đơn giản, giả sử có 32 phần tử trong một mảng theo thứ tự được sắp xếp mà chúng tôi đang tìm kiếm một phần tử bằng cách sử dụng tìm kiếm nhị phân.

1 2 3 4 5 6 ... 32

Giả sử chúng ta đang tìm kiếm 32. sau lần lặp đầu tiên, chúng ta sẽ bị bỏ lại với

17 18 19 20 .... 32

sau lần lặp thứ hai, chúng ta sẽ bị bỏ lại với

25 26 27 28 .... 32

sau lần lặp thứ ba, chúng ta sẽ bị bỏ lại

29 30 31 32

sau lần lặp thứ tư, chúng ta sẽ bị bỏ lại

31 32

Trong lần lặp thứ năm, chúng ta sẽ tìm thấy giá trị 32.

Vì vậy, nếu chúng ta chuyển đổi nó thành một phương trình toán học, chúng ta sẽ nhận được

(32 X (1/2 5 )) = 1

=> n X (2 -k ) = 1

=> (2 k ) = n

=> k log 2 2 = log 2 n

=> k = log 2 n

Do đó bằng chứng.


0

Đây là giải pháp sử dụng định lý chủ, với LaTeX có thể đọc được.

Đối với mỗi lần lặp lại trong mối quan hệ lặp lại cho tìm kiếm nhị phân, chúng tôi chuyển đổi vấn đề thành một bài toán con, với thời gian chạy T (N / 2). Vì thế:

T (n) = T (n / 2) +1

Thay vào định lý tổng thể, chúng ta nhận được:

T (n) = aT (n / b) + f (n)

Bây giờ, vì logba0 và f (n) là 1, chúng ta có thể sử dụng trường hợp thứ hai của định lý chủ vì:

f (n) = O (1) = O (n0) = O (nlogba)

Điều này có nghĩa rằng:

T (n) = O (nlogbalogn) = O (n0logn) = O (logn)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.