วิธีการคำนวณความซับซ้อนของการค้นหาแบบไบนารี


144

ฉันได้ยินบางคนบอกว่าเนื่องจากการค้นหาแบบไบนารีจะลดการป้อนข้อมูลลงในการค้นหาจึงเป็นอัลกอริธึม log (n) เนื่องจากฉันไม่ได้มาจากภูมิหลังทางคณิตศาสตร์ฉันจึงไม่สามารถเกี่ยวข้องกับมันได้ บางคนสามารถอธิบายรายละเอียดเพิ่มเติมได้หรือไม่ มันต้องทำอะไรกับซีรี่ส์ลอการิทึมหรือไม่?


1
สิ่งนี้อาจช่วยคุณได้: stackoverflow.com/a/13093274/550393
2cupsOfTech

คำตอบ:


385

นี่คือวิธีการทางคณิตศาสตร์มากขึ้นในการมองเห็นแม้ว่าจะไม่ซับซ้อนจริงๆ IMO มีความชัดเจนมากยิ่งขึ้น

คำถามคือคุณสามารถหาร N ด้วย 2 ได้กี่ครั้งจนกว่าคุณจะมี 1 นี่เป็นการบอกว่าให้ทำการค้นหาแบบไบนารี่ (องค์ประกอบครึ่งหนึ่ง) จนกว่าคุณจะพบมัน ในสูตรนี้จะเป็นเช่นนี้:

1 = N / 2 x

คูณด้วย 2 x :

2 x = N

ตอนนี้ทำบันทึก2 :

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

นี่หมายความว่าคุณสามารถแบ่งบันทึก N ครั้งจนกว่าคุณจะแบ่งทุกอย่างได้ ซึ่งหมายความว่าคุณต้องแบ่งบันทึก N ("ทำตามขั้นตอนการค้นหาแบบไบนารี") จนกว่าคุณจะพบองค์ประกอบของคุณ


ฉันเพิ่งคำนวณมันเป็น t (n) = (2 ^ 2) * K วิธีที่จะทำให้มันเข้าสู่ระบบแบบฟอร์ม?
Shan Khan

1
แนวคิดเดียวกันอธิบายแบบกราฟิก: stackoverflow.com/a/13093274/550393
2cupsOfTech

ส่วนที่ฉันขาดไปคือถ้าคุณมี BST ที่มี 7 รายการสูตรของมันคืออะไร? log2 (7)? ฉันทำการคำนวณแบบเดรัจฉานกับผลลัพธ์ที่เป็นไปได้ทั้งหมดและได้คำตอบที่ไม่เท่ากับ log2 (7) ดังนั้นฉันทำอะไรผิด
Perry Monschau

1
ง่ายกว่าคำอธิบายต้นไม้ไบนารี
NoName

1
คำตอบที่ดีมาก
VHS

22

สำหรับการค้นหาแบบทวิภาค T (N) = T (N / 2) + O (1) // ความสัมพันธ์ที่เกิดซ้ำ

ใช้ทฤษฎีบทของโทสำหรับการคำนวณความซับซ้อนของเวลารันไทม์ของความสัมพันธ์ที่เกิดซ้ำ: T (N) = aT (N / b) + f (N)

นี่คือ a = 1, b = 2 => log (a base b) = 1

เช่นกันที่นี่ f (N) = n ^ c บันทึก ^ k (n) // k = 0 & c = บันทึก (ฐาน b)

ดังนั้น T (N) = O (N ^ c บันทึก ^ (k + 1) N) = O (บันทึก (N))

ที่มา: http://en.wikipedia.org/wiki/Master_theorem


1
เหตุใดบันทึก (ฐาน b) คือ 1 เมื่อ a = 1 และ b = 2 ไม่ควรเป็น 0
GAURANG VYAS

16

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

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

ใส่ค่าของ The (n / 2) ข้างบนดังนั้น T (n) = T (n / 4) + 1 + 1 . . . T (n / 2 ^ k) + 1 + 1 + 1 + 1 .....

= T (2 ^ k / 2 ^ k) + 1 + 1 .... + 1 สูงสุด k

= T (1) + K

ในขณะที่เราถ่าย 2 ^ k = n

K = log n

ดังนั้นเวลาที่ซับซ้อนคือ O (log n)


10

ไม่ต้องใช้เวลาค้นหาครึ่งหนึ่งซึ่งจะไม่ทำให้บันทึก (n) มันลดลงแบบลอการิทึม ลองคิดดูสักครู่ หากคุณมี 128 รายการในตารางและต้องค้นหาค่าของคุณเชิงเส้นอาจจะใช้เวลาประมาณ 64 รายการโดยเฉลี่ยเพื่อค้นหาค่าของคุณ นั่นคือ n / 2 หรือเวลาเชิงเส้น ด้วยการค้นหาแบบไบนารี่คุณสามารถกำจัด 1/2 รายการที่เป็นไปได้ในแต่ละการวนซ้ำซึ่งอย่างมากมันจะใช้เวลาเพียง 7 เปรียบเทียบเพื่อค้นหาค่าของคุณ (บันทึกฐาน 2 จาก 128 คือ 7 หรือ 2 ถึง 7 กำลังเป็น 128) นี่คือ พลังของการค้นหาแบบไบนารี


ขออภัยสำหรับเนโครโพสต์ แต่ 128 ไม่ได้เป็นต้นไม้ที่สมบูรณ์เท่า ๆ กัน ฉันใช้ตัวอย่างพื้นฐานเพื่อทำความเข้าใจสิ่งนี้และฉันพบว่า 7 รายการเติมต้นไม้ด้วย 3 ชั้นอย่างสม่ำเสมอ ฉันคำนวณว่าความซับซ้อนควรเป็น 17/7 (ค่าเฉลี่ยของผลรวมการเปรียบเทียบ) ซึ่งเท่ากับ 2.43 แต่ log2 (7) คือ 2.81 ดังนั้นสิ่งที่ฉันหายไปที่นี่
Perry Monschau

สองคำตอบ - คำตอบแรกที่นี่: แม้ว่าจะไม่มีข้อผิดพลาดในคณิตศาสตร์เราสามารถเห็นได้ว่าค่าเฉลี่ย 2.43 ยังคงดีกว่าค่าเฉลี่ย 3.5 สำหรับเส้นตรงและนี่เป็นค่าที่ต่ำ เมื่อคุณเข้าสู่ 100s ของรายการ log2 () ดีกว่าเชิงเส้นมาก ฉันคิดว่าคุณเห็นสิ่งนี้แม้ว่าดังนั้นต่อไป
Michael Dorgan

1
คำตอบที่สอง: ฉันไม่แน่ใจว่าคุณมีต้นไม้ชนิดไหนที่ 7 มีทุกสิ่งที่กรอก เมื่อฉันคิดเกี่ยวกับต้นไม้ที่สมบูรณ์แบบของ 8 รายการฉันเห็นต้นไม้ลึก 3 ระดับพร้อมใบไม้ทั้งหมด 8 ใบ ในต้นไม้ต้นนี้ไม่ว่าคุณจะค้นหาด้วยหมายเลขใดจะใช้การเปรียบเทียบทั้งหมด 3 ครั้งเพื่อรับจากรูตถึงลีฟ สำหรับ 7 รายการหนึ่งในพา ธ จะเปรียบเทียบน้อยลงหนึ่งรายการดังนั้น 20/7 (6 โหนด 3 รายการเปรียบเทียบ 1 โหนด 2 เปรียบเทียบ) ซึ่งเป็น ~ 2.85 Log2 (7) คือ ~ 2.81 ฉันไม่มีภูมิหลังทางคณิตศาสตร์ที่จะอธิบายความแตกต่าง. 04 แต่ฉันเดาว่ามันเกี่ยวข้องกับการไม่มีบิตเศษส่วนหรือเวทมนตร์อื่น :)
Michael Dorgan

ตัวเลขคือจำนวนใบไม้! ไม่ใช่จำนวนโหนด? นั่นเป็นข้อมูลชิ้นใหญ่ที่ฉันหายไป .. ดูเหมือนแปลกสำหรับฉันว่าฟังก์ชั่นนั้นอิงตามใบไม้เมื่อแต่ละโหนดการแตกกิ่งเป็นจุดหยุดที่มีศักยภาพ อย่างไรก็ตามขอบคุณที่ยืดออกสำหรับฉัน!
Perry Monschau

5

ความซับซ้อนของเวลาของอัลกอริทึมการค้นหาแบบไบนารีอยู่ในคลาส O (บันทึก n) นี้เรียกว่าสัญกรณ์โอใหญ่ วิธีที่คุณควรจะแปลความหมายนี้ก็คือการเจริญเติบโต asymptotic ของเวลาการทำงานจะใช้เวลาในการดำเนินการให้ชุดที่ใส่ของขนาด n log nจะไม่เกิน

นี่เป็นศัพท์แสงทางคณิตศาสตร์ที่เป็นทางการเพื่อที่จะสามารถพิสูจน์ข้อความ ฯลฯ ได้มันมีคำอธิบายที่ตรงไปตรงมามาก เมื่อ n โตขึ้นมากฟังก์ชั่น log n จะโตขึ้นตามเวลาที่ใช้ในการเรียกใช้ฟังก์ชัน ขนาดของ "input set", n, เป็นเพียงความยาวของรายการ

ใส่เพียงเหตุผลการค้นหาแบบไบนารีอยู่ใน O (log n) คือมันลดการตั้งค่าการป้อนข้อมูลลงครึ่งหนึ่งในแต่ละครั้ง ง่ายกว่าที่จะคิดในสถานการณ์ย้อนกลับ ในการวนซ้ำ x อัลกอริธึมการค้นหาแบบไบนารี่สามารถตรวจสอบได้สูงสุดเท่าไร คำตอบคือ 2 ^ x จากนี้เราจะเห็นได้ว่าสิ่งที่ตรงกันข้ามคือโดยเฉลี่ยแล้วอัลกอริทึมการค้นหาแบบไบนารีต้องการการวนซ้ำ log2 n สำหรับรายการความยาว n

ถ้าทำไมมันถึงเป็น O (log n) และไม่ใช่ O (log2 n) ก็เป็นได้เพราะใส่ใหม่อีกครั้ง - การใช้ค่าคงที่ O ใหญ่จะไม่นับ


4

นี่คือรายการวิกิพีเดีย

ถ้าคุณดูวิธีการทำซ้ำอย่างง่าย คุณเพียงแค่กำจัดองค์ประกอบครึ่งหนึ่งที่จะค้นหาจนกว่าคุณจะพบองค์ประกอบที่คุณต้องการ

นี่คือคำอธิบายวิธีที่เราคิดสูตร

พูดในตอนแรกว่าคุณมีองค์ประกอบจำนวน N แล้วสิ่งที่คุณทำคือ⌊N / 2⌋เป็นความพยายามครั้งแรก โดยที่ N คือผลรวมของขอบเขตล่างและขอบเขตบน ค่าครั้งแรกของ N จะเท่ากับ (L + H) โดยที่ L คือดัชนีแรก (0) และ H คือดัชนีสุดท้ายของรายการที่คุณกำลังค้นหา หากคุณโชคดีองค์ประกอบที่คุณพยายามค้นหาจะอยู่ตรงกลาง [เช่น คุณกำลังค้นหา 18 ในรายการ {16, 17, 18, 19, 20} จากนั้นคุณคำนวณ⌊ (0 + 4) / 2⌋ = 2 โดยที่ 0 คือขอบเขตที่ต่ำกว่า (L - ดัชนีขององค์ประกอบแรกของอาร์เรย์) และ 4 คือขอบเขตที่สูงขึ้น (H - ดัชนีขององค์ประกอบสุดท้ายของอาร์เรย์) ในกรณีข้างต้น L = 0 และ H = 4 ตอนนี้ 2 เป็นดัชนีขององค์ประกอบ 18 ที่คุณกำลังค้นหา บิงโก! คุณพบมัน

หากกรณีเป็นอาร์เรย์ที่แตกต่างกัน {15,16,17,18,19} แต่คุณยังคงค้นหา 18 คุณจะไม่โชคดีและคุณจะทำ N / 2 คนแรก (ซึ่งคือ⌊ (0 + 4) / 2⌋ = 2 จากนั้นให้ตระหนักถึงองค์ประกอบที่ 17 ที่ดัชนี 2 ไม่ใช่หมายเลขที่คุณต้องการตอนนี้คุณรู้แล้วว่าคุณไม่ต้องมองหาอาร์เรย์อย่างน้อยครึ่งหนึ่งในความพยายามครั้งถัดไปเพื่อค้นหาลักษณะวนซ้ำ ความพยายามในการค้นหาลดลงครึ่งหนึ่งดังนั้นโดยพื้นฐานแล้วคุณไม่ต้องค้นหารายการองค์ประกอบครึ่งหนึ่งที่คุณค้นหาก่อนหน้านี้ทุกครั้งที่คุณพยายามค้นหาองค์ประกอบที่คุณไม่สามารถค้นหาได้ในความพยายามครั้งก่อน

ดังนั้นกรณีที่เลวร้ายที่สุดก็คือ

[N] / 2 + [(N / 2)] / 2 + [((N / 2) / 2)] / 2 .....
เช่น:
N / 2 1 + N / 2 2 + N / 2 3 + ..... + N / 2 x … ..

จนกระทั่ง ... คุณค้นหาเสร็จแล้วโดยที่องค์ประกอบที่คุณพยายามค้นหาอยู่ท้ายรายการ

นั่นแสดงว่ากรณีที่เลวร้ายที่สุดคือเมื่อคุณไปถึง N / 2 x โดยที่ x เป็นเช่นนั้น 2 x = N

ในกรณีอื่น N / 2 x โดยที่ x เป็นเช่นนั้น 2 x <N ค่าต่ำสุดของ x สามารถเป็น 1 ซึ่งเป็นกรณีที่ดีที่สุด

ขณะนี้เนื่องจากกรณีที่แย่ที่สุดทางคณิตศาสตร์คือเมื่อค่า
2 x = N
=> log 2 (2 x ) = log 2 (N)
=> x * log 2 (2) = log 2 (N)
=> x * 1 = log 2 (N)
=> เพิ่มเติมอย่างเป็นทางการ⌊log 2 (N) + 1⌋


1
คุณได้รับเวอร์ชั่นที่เป็นทางการมากขึ้นเพียงใด?
Kalle

ใช้ฟังก์ชั่นตั้งพื้น รายละเอียดอยู่ในส่วนประสิทธิภาพของลิงค์ wiki ( en.wikipedia.org/wiki/Binary_search_algorithm ) ที่ให้ไว้ในคำตอบ
RajKon

3

Log2 (n) คือจำนวนสูงสุดของการค้นหาที่ต้องการค้นหาบางสิ่งในการค้นหาแบบไบนารี กรณีเฉลี่ยเกี่ยวข้องกับการค้นหา log2 (n) -1 นี่คือข้อมูลเพิ่มเติม:

http://en.wikipedia.org/wiki/Binary_search#Performance


2

สมมติว่าการวนซ้ำในการค้นหาแบบไบนารีสิ้นสุดลงหลังจากทำซ้ำ k ในการวนซ้ำแต่ละครั้งอาร์เรย์จะถูกหารครึ่ง สมมุติว่าความยาวของอาร์เรย์ที่การวนซ้ำใด ๆ คือ n ที่การวนซ้ำ 1

Length of array = n

ที่ Iteration 2

Length of array = n⁄2

ที่ Iteration 3

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

ดังนั้นหลังจากการพูดซ้ำ k

Length of array = n⁄2k

นอกจากนี้เรายังรู้ว่าหลังจากหลังจากการหาร k ความยาวของอาร์เรย์จะกลายเป็น 1 ดังนั้น

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

การใช้ฟังก์ชั่นบันทึกทั้งสองด้าน:

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

ดังนั้น,

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

ดังนั้นความซับซ้อนของเวลาของการค้นหาแบบไบนารีคือ

log2 (n)

1

การค้นหาแบบไบนารี่ทำงานโดยแบ่งปัญหาออกเป็นสองครั้งซ้ำ ๆ กันสิ่งนี้ (ละเว้นรายละเอียด):

ตัวอย่างค้นหา 3 ใน [4,1,3,8,5]

  1. สั่งซื้อรายการของคุณ [1,3,4,5,8]
  2. ดูรายการกลาง (4)
    • หากเป็นสิ่งที่คุณกำลังมองหาหยุด
    • ถ้ายิ่งใหญ่กว่าให้ดูที่ครึ่งแรก
    • ถ้ามันน้อยกว่าให้ดูที่ครึ่งหลัง
  3. ทำซ้ำขั้นตอนที่ 2 ด้วยรายการใหม่ [1, 3], ค้นหา 3 และหยุด

เป็นการค้นหาแบบสองชั้นเมื่อคุณแบ่งปัญหาใน 2

การค้นหาต้องการเพียงขั้นตอน log2 (n) เพื่อค้นหาค่าที่ถูกต้อง

ฉันจะแนะนำIntroduction to Algorithmsหากคุณต้องการเรียนรู้เกี่ยวกับความซับซ้อนของอัลกอริทึม


1

เนื่องจากเราลดรายการลงครึ่งหนึ่งทุกครั้งดังนั้นเราแค่ต้องรู้ว่ามีกี่ขั้นตอนที่เราได้ 1 เมื่อเราแบ่งรายชื่อออกเป็นสองรายการ ในการคำนวณที่กำหนด x แสดงถึงจำนวนเวลาที่เราแบ่งรายการจนกว่าเราจะได้รับหนึ่งองค์ประกอบ (ในกรณีที่แย่ที่สุด)

1 = N / 2x

2x = N

จด 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 (บันทึกฐาน 2) = 1 + logN

ดังนั้นความซับซ้อนของเวลาในการค้นหาแบบไบนารีคือ 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

ให้ฉันทำให้มันง่ายสำหรับคุณทุกคนด้วยตัวอย่าง

เพื่อความเรียบง่ายสมมติว่ามี 32 องค์ประกอบในอาเรย์เรียงตามลำดับที่เรากำลังค้นหาองค์ประกอบโดยใช้การค้นหาแบบไบนารี

1 2 3 4 5 6 ... 32

สมมติว่าเรากำลังค้นหา 32 หลังจากการทำซ้ำครั้งแรกเราจะเหลือ

17 18 19 20 .... 32

หลังจากการทำซ้ำครั้งที่สองเราจะเหลือ

25 26 27 28 .... 32

หลังจากการทำซ้ำครั้งที่สามเราจะเหลือ

29 30 31 32

หลังจากการทำซ้ำครั้งที่สี่เราจะถูกทิ้งให้อยู่กับ

31 32

ในการทำซ้ำครั้งที่ห้าเราจะพบค่า 32

ดังนั้นถ้าเราแปลงมันเป็นสมการทางคณิตศาสตร์เราจะได้

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

=> n X (2 -k ) = 1

=> (2 k ) = n

=> k log 2 2 = log 2 n

=> k = บันทึก2 n

ดังนั้นการพิสูจน์


0

นี่คือวิธีแก้ปัญหาโดยใช้ทฤษฎีบทหลักพร้อม LaTeX ที่อ่านได้

สำหรับการเกิดซ้ำแต่ละครั้งในความสัมพันธ์ที่เกิดซ้ำสำหรับการค้นหาแบบไบนารีเราแปลงปัญหาเป็นหนึ่งในปัญหาย่อยด้วยรันไทม์ T (N / 2) ดังนั้น:

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

เราได้รับ:

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

ตอนนี้เนื่องจากlogbaเป็น 0 และ f (n) คือ 1 เราสามารถใช้กรณีที่สองของทฤษฎีบทหลักเพราะ:

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

ซึ่งหมายความว่า:

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.