อัปเดต: ดูด้านล่างสำหรับการอัปเดตเกี่ยวกับความไม่ถูกต้องของการดำเนินการเข้าร่วมนี้
นี่เป็นภาพร่างคร่าวๆของโซลูชันที่เป็นไปได้:
ฉันคิดว่าฉันอาจมีวิธีแก้ปัญหานี้โดยใช้ B + -tree-balanced แบบสุ่ม ต้นไม้เหล่านี้มีรูปแบบที่ไม่เหมือนใคร พวกเขาเก็บกุญแจไว้หลายครั้งไม่เหมือนทรี อาจเป็นไปได้ที่จะแก้ไขด้วยการใช้เล่ห์เหลี่ยมจาก "Biased Search Trees" ของ Bent et al ในการจัดเก็บแต่ละคีย์เฉพาะในระดับสูงสุด (นั่นคือใกล้เคียงกับรูต) ที่ปรากฏขึ้น)
ต้นไม้สำหรับชุดของค่าที่ไม่ซ้ำกันที่สั่งซื้อจะถูกสร้างขึ้นโดยการเชื่อมโยงแต่ละค่ากับกระแสของบิตคล้ายกับวิธีที่แต่ละค่าใน treap เชื่อมโยงกับลำดับความสำคัญ แต่ละโหนดในทรีมีทั้งคีย์และบิตสตรีม นอกจากนี้โหนดที่ไม่ใช่ใบไม้จะมีจำนวนธรรมชาติที่ระบุความสูงของต้นไม้ที่รากที่โหนดนั้น โหนดภายในอาจมีจำนวนชายน์ที่ไม่เป็นศูนย์ เช่น B + -trees เส้นทางที่ไม่ตัดกันของตัวเองจากรูตไปยังลีฟนั้นมีความยาวเท่ากัน
ทุกโหนดภายในมี (เช่นใน B + -trees) คีย์k ที่ใหญ่ที่สุดของการสืบทอดสืบทอด แต่ละคนยังมีจำนวนธรรมชาติฉันแสดงความสูงของต้นไม้ที่รากที่vและกระแสของบิตที่เกี่ยวข้องกับkจากi + 1บิตเป็นต้นไป ถ้าคีย์ในต้นไม้ที่หยั่งรากทุกที่โวลต์มีบิตแรกเหมือนกันในกระแสบิตของเด็กของทุกวีเป็นใบและฉันเป็น1 มิฉะนั้น children ของvคือโหนดภายในซึ่งทั้งหมดนี้มีiบิตเดียวกันในบิตสตรีมที่เชื่อมโยงกับคีย์ของพวกเขาvkivki+1vvi1vi
ในการสร้างทรีจากรายการที่เรียงลำดับของคีย์ที่มีสตรีมบิตที่เกี่ยวข้องอันดับแรกให้รวบรวมคีย์เป็นกลุ่มที่อยู่ติดกันโดยอิงจากบิตแรกในสตรีม สำหรับแต่ละกลุ่มเหล่านี้ให้สร้างพาเรนต์ด้วยคีย์และบิตสตรีมของคีย์ที่ใหญ่ที่สุดในกลุ่ม แต่จะลบบิตแรกของสตรีม ตอนนี้ทำขั้นตอนการจัดกลุ่มเดียวกันกับผู้ปกครองใหม่เพื่อสร้างปู่ย่าตายาย ทำต่อไปจนกระทั่งเหลือเพียงโหนดเดียวเท่านั้น นี่คือรากของต้นไม้
รายการของคีย์และกระแสบิต (เริ่มต้น) ต่อไปนี้จะแสดงเป็นต้นไม้ด้านล่าง ในส่วนนำหน้าบิตสตรีม a '.' หมายถึงบิตใด ๆ นั่นคือบิตสตรีมใด ๆ สำหรับคีย์ A ที่มี 0 ในตอนแรกที่สร้างทรีเดียวกันกับอื่น ๆ โดยสมมติว่าไม่มีบิตสตรีมของคีย์อื่นที่แตกต่างกัน
A 0...
B 00..
C 10..
D 0...
E 0011
F 1...
G 110.
H 0001
____H____
/ \
E H
| / \
__E__ G H
/ | \ | |
B C E G H
/ \ | / \ / \ |
A B C D E F G H
เด็กทุกคนของโหนดภายในโดยเฉพาะมีบิตเดียวกันในสถานที่แรกของบิตสตรีม สิ่งนี้เรียกว่า "สี" ของพาเรนต์ - 0 คือสีแดง 1 เป็นสีเขียว เด็กมี "รสชาติ" ขึ้นอยู่กับบิตแรกของกระแสบิต - 0 คือเชอร์รี่และ 1 คือสะระแหน่ ใบมีรสชาติ แต่ไม่มีสี ตามนิยามแล้วโหนดเชอร์รี่ไม่สามารถมีพาเรนต์สีเขียวและโหนดมินต์ไม่สามารถมีพาเรนต์สีแดงได้
สมมติว่าบิตในสตรีมบิตเป็น IID จากการแจกแจงแบบสม่ำเสมอ PMF ของจำนวนพาเรนต์ของโหนดคือ
2 1 - n ( n - 1n21−n
และมูลค่าที่คาดว่าจะเป็น(n+1)/2 สำหรับn≥2ทั้งหมดนี่คือ≤3(n−1i−1)(n+1)/2n≥2ดังนั้นความสูงของต้นไม้ที่คาดไว้คือO(LGn)≤34nO(lgn)
หากต้องการเข้าร่วมสองต้นที่มีความสูงเท่ากันให้ตรวจสอบก่อนเพื่อดูว่ารากของพวกเขามีสีเดียวกันหรือไม่ หากเป็นเช่นนั้นให้ตัดจากรูทซ้ายของเด็กที่อยู่ด้านขวาสุดและจากรูทขวาของเด็กที่อยู่ซ้ายสุดจากนั้นให้เข้าร่วมต้นไม้สองต้นนี้ซ้ำ ผลที่ได้จะเป็นต้นไม้ที่มีความสูงเท่ากันหรือสูงกว่าหนึ่งต้นเนื่องจากต้นไม้มีรสชาติเดียวกัน (ดูด้านล่าง) หากผลของการรวมต้นไม้สองต้นซ้ำมีความสูงเท่ากับเด็กสองคนที่ถูกตัดขาดให้เป็นเด็กกลางของรากที่มีลูกที่เหลืออยู่ของรากซ้ายก่อนมันและลูกที่เหลือของรากที่ถูกต้องหลังจากนั้น ถ้ามันสูงกว่า 1 ให้เด็ก ๆ อยู่กลางรูทกับลูกที่เหลืออยู่ของรูทซ้ายก่อนมันและเด็กที่เหลือของรูทด้านขวาหลังจากนั้น ถ้ารากมีสีต่างกันให้ตรวจดูว่ามีรสชาติเหมือนกันหรือไม่ ถ้าพวกเขาทำ ให้ผู้ปกครองใหม่ด้วยคีย์และสตรีมบิตของรูตที่ถูกต้องโดยจะทำการบิตแรก หากพวกเขาทำไม่ได้ให้แต่ละผู้ปกครองใหม่รากกับคีย์และกระแสบิตของรากเก่า (eliding แต่ละบิตแรก) จากนั้นเข้าร่วมต้นไม้ซ้ำ
มีการเรียกซ้ำสองครั้งในอัลกอริทึมนี้ อย่างแรกคือเมื่อรากมีสีเดียวกันส่วนที่สองคือเมื่อรากมีสีและรสชาติที่แตกต่างกัน รากมีสีเดียวกันกับความน่าจะเป็น 2 การเรียกซ้ำในกรณีนี้จะเห็นรากที่มีรสชาติเหมือนกันเสมอดังนั้นการเรียกซ้ำครั้งที่สองจะไม่เกิดขึ้นหลังจากครั้งแรก แต่คนแรกที่สามารถเกิดขึ้นได้ซ้ำ ๆ แต่ทุกครั้งที่มีความน่าจะเป็น1 / 2ดังนั้นเวลาทำงานคาดว่ายังคงเป็นO ( 1 ) โทร recursive ที่สองที่เกิดขึ้นกับความน่าจะเป็น1 / 41/21/2O(1)1/4และการเรียกซ้ำที่ตามมามักจะอยู่บนต้นไม้ที่มีสีต่างกันเสมอ
หากต้องการเข้าร่วมสองต้นที่มีความสูงไม่เท่ากันก่อนอื่นให้ติดตามกระดูกสันหลังด้านซ้ายของต้นไม้ที่ถูกต้องก่อนโดยสมมติว่าต้นไม้ที่ถูกต้องนั้นสูงกว่า (อีกกรณีคือสมมาตร) เมื่อถึงต้นไม้สองต้นที่มีความสูงเท่ากันให้ดำเนินการเข้าร่วมสำหรับต้นไม้สองต้นที่มีความสูงเท่ากันแก้ไขดังนี้: ถ้าผลลัพธ์มีความสูงเท่ากันให้เปลี่ยนต้นไม้ที่เป็นลูกด้วยผลลัพธ์ ของการเข้าร่วม หากผลลัพธ์นั้นสูงขึ้นให้รวมพาเรนต์ของต้นไม้ทางด้านขวาไปที่รูทของอีกต้นหลังจากนั้นจะถูกทำให้สูงขึ้นโดยหนึ่งโดยการเพิ่มพาเรนต์สำหรับราก ต้นไม้จะสูงเช่นเดียวกับความน่าจะเป็นเพื่อให้ยุติเรื่องนี้ในO ( 1 )คาดว่า
1/2O(1)
O(1)
a 01110
b 110..
c 10...
d 00000
ต้นไม้ที่ทำโดย[a,b]
มีความสูง 2 ต้นไม้ที่ทำโดย[c,d]
มีความสูง 2 และต้นไม้ที่ทำโดยjoinEqual (tree [a,b]) (tree [c,d])
มีความสูง 3 อย่างไรก็ตามต้นไม้ที่ทำโดยมีความสูง 3 อย่างไรก็ตามต้นไม้ที่ทำโดย[a,b,c,d]
มีความสูง 2
นี่คือรหัสที่ฉันใช้เพื่อค้นหาข้อผิดพลาดนี้