คำตอบสั้น ๆ : คุณทำไม่ได้
ตอบอีกเล็กน้อย:
คุณจะต้องใช้พื้นที่เพิ่มพื้นที่ในการจัดเก็บ "อายุ" ของผลงานของคุณซึ่งจะทำให้คุณสามารถแยกแยะระหว่างลำดับความสำคัญที่เหมือนกัน และคุณจะต้องใช้พื้นที่Ω ( n )สำหรับข้อมูลที่จะช่วยให้การแทรกและดึงข้อมูลรวดเร็ว บวกน้ำหนักบรรทุกของคุณ (ค่าและลำดับความสำคัญ)Ω ( n )Ω ( n )
และสำหรับแต่ละส่วนของข้อมูลที่คุณเก็บคุณจะสามารถที่จะ "ซ่อน" ข้อมูลบางอย่างในที่อยู่ (เช่นd d R ( X ) < d d R ( Y )หมายถึง Y เก่ากว่า X) แต่ในข้อมูลที่ "ซ่อนอยู่" คุณจะซ่อนข้อมูล "อายุ" หรือข้อมูล "เรียกคืนอย่างรวดเร็ว" ไม่ใช่ทั้งคู่ddr ( X) < a ddr ( Y))
คำตอบที่ยาวมากด้วยการหลอกคณิตศาสตร์ที่ไม่แน่นอน:
หมายเหตุ: ส่วนท้ายสุดของส่วนที่สองเป็นภาพร่างดังที่กล่าวไว้ หากนักคณิตศาสตร์บางคนสามารถจัดให้มีเวอร์ชั่นที่ดีกว่านี้ฉันจะขอบคุณ
ลองคิดเกี่ยวกับปริมาณข้อมูลที่เกี่ยวข้องกับเครื่อง X-bit (เช่น 32 หรือ 64 บิต) ด้วยเรกคอร์ด (ค่าและลำดับความสำคัญ) คำกว้างP
คุณมีชุดของระเบียนที่เป็นไปได้ที่สั่งบางส่วน: และ( a , 1 ) = ( a , 1 )แต่คุณไม่สามารถเปรียบเทียบ( a , 1 )และ( b , 1 )( a , 1 ) < ( a , 2 )(a,1)=(a,1)(a,1)(b,1)
อย่างไรก็ตามคุณต้องการเปรียบเทียบสองค่าที่ไม่สามารถเทียบเคียงได้กับชุดของระเบียนของคุณ ดังนั้นคุณได้ที่นี่ชุดของค่าอื่น: ผู้ที่ได้รับการแทรกและคุณต้องการที่จะเพิ่มความมันด้วยการสั่งซื้อบางส่วน: IFF Xถูกแทรกก่อนYX<YXY
ในกรณีที่เลวร้ายที่สุดหน่วยความจำของคุณจะถูกบันทึกไว้ในแบบฟอร์ม (ด้วย?แตกต่างกันสำหรับแต่ละคน) ดังนั้นคุณจะต้องพึ่งพาเวลาแทรกทั้งหมดเพื่อตัดสินใจว่าจะไปที่ใด ออกก่อน(?,1)?
- เวลาแทรก (สัมพันธ์กับบันทึกอื่น ๆ ที่ยังอยู่ในโครงสร้าง) ต้องใช้บิตข้อมูล (ด้วย P-byte payload และ2 Xไบต์ที่เข้าถึงได้ของหน่วยความจำ)X−log2(P)2X
- เพย์โหลด (ค่าบันทึกและลำดับความสำคัญของคุณ) ต้องใช้คำพูดของเครื่องP
นั่นหมายความว่าคุณจะต้องอย่างใดเก็บบิตพิเศษของข้อมูลสำหรับแต่ละระเบียนคุณเก็บ และนั่นคือO ( n )สำหรับnบันทึกX−log2(P)O ( n )n
ทีนี้แต่ละหน่วยความจำ "เซลล์" ของข้อมูลมีหน่วยเป็นเท่าใด?
- บิต Wของข้อมูล ( Wเป็นความกว้างของเครื่องคำ)WW
- บิตX
ทีนี้สมมติว่า (payload มีความกว้างเครื่องอย่างน้อยหนึ่งคำ (โดยปกติจะเป็นหนึ่ง octet)) ซึ่งหมายความว่าX - l o g 2 ( P ) < Xเพื่อให้เราสามารถใส่ข้อมูลคำสั่งแทรกในที่อยู่ของเซลล์ นั่นคือสิ่งที่เกิดขึ้นในสแต็ก: เซลล์ที่มีที่อยู่ต่ำสุดป้อนสแต็กก่อน (และจะออกล่าสุด)P≥ 1X- l o g2( P) < X
ดังนั้นในการจัดเก็บข้อมูลทั้งหมดของเราเรามีความเป็นไปได้สองประการ:
- เก็บคำสั่งแทรกในที่อยู่และเพย์โหลดในหน่วยความจำ
- เก็บทั้งในหน่วยความจำและปล่อยให้ที่อยู่ฟรีสำหรับการใช้งานอื่น
เห็นได้ชัดว่าเพื่อหลีกเลี่ยงของเสียเราจะใช้วิธีแก้ปัญหาแรก
ตอนนี้สำหรับการดำเนินงาน ฉันคิดว่าคุณต้องการที่จะมี:
- กับ O ( L o กรัมn )ความซับซ้อนเวลาผมn s e r t ( t a s k , p r i o r i t y)O ( l o gn )
- กับ O ( L o กรัมn )ความซับซ้อนเวลาSt ขลิตรอี Ex t r a c tMฉันn ( )O ( l o gn )
ดู Let 's ที่ :St a b l e Ex t r a c t Mฉันn ( )
อัลกอริทึมทั่วไปที่แท้จริงจริงๆจะเป็นดังนี้:
- พบระเบียนที่มีลำดับความสำคัญขั้นต่ำและขั้นต่ำ "เวลาแทรก" ใน )O ( l o gn )
- ลบออกจากโครงสร้างใน )O ( l o gn )
- ส่งคืนได้
ตัวอย่างเช่นในกรณีของ heap มันจะถูกจัดระเบียบแตกต่างกันเล็กน้อย แต่งานเหมือนกัน: 1. ค้นหาระเบียนขั้นต่ำใน
2. ลบออกจากโครงสร้างในO ( 1 )
3. แก้ไข ทุกอย่างเพื่อที่ครั้งต่อไป # 1 และ # 2 ยังคงเป็นO ( 1 )นั่นคือ "ซ่อมแซมกอง" สิ่งนี้จะต้องทำใน "O (log n)" 4. ส่งคืนองค์ประกอบ0 (1)O ( 1 )O ( 1 )
กลับไปที่อัลกอริทึมทั่วไปเราจะเห็นว่าการค้นหาระเบียนในเวลาเราต้องการวิธีที่รวดเร็วในการเลือกหนึ่งที่เหมาะสมระหว่างผู้สมัครที่2 ( X - l o g 2 ( P ) ) (แย่ที่สุด) กรณีหน่วยความจำเต็ม)O ( l o gn )2(X- l o g2( P) )
ซึ่งหมายความว่าเราจำเป็นต้องเก็บบิตของข้อมูลเพื่อดึงองค์ประกอบนั้น (แต่ละบิตแบ่งพื้นที่ผู้สมัครออกเป็นสองส่วนดังนั้นเราจึงมีO ( l o g n ) bisections หมายถึงO ( l o g n )ความซับซ้อนของเวลา)X- l o g2( P)O ( l o gn )O ( l o gn )
บิตของข้อมูลเหล่านี้อาจถูกเก็บไว้เป็นที่อยู่ขององค์ประกอบ (ในฮีป, min คือที่ที่อยู่คงที่) หรือด้วยพอยน์เตอร์เช่น (ในแผนภูมิการค้นหาแบบไบนารี่ (ที่มีพอยน์เตอร์) คุณต้องติดตามโดยเฉลี่ยเพื่อไปยังนาที)O ( l o gn )
O ( l o gn )X- l o g2( P)
O ( l o gn )
X- l o g2( P)O ( l o gn )
อัลกอริทึมการแทรกมักจะต้องอัปเดตบางส่วนของข้อมูลนี้ฉันไม่คิดว่ามันจะมีค่าใช้จ่ายมากขึ้น (หน่วยความจำที่ชาญฉลาด) เพื่อให้ทำงานได้อย่างรวดเร็ว
X- l o g2( P)
- X- l o g2( P)
- P
- X- l o g2( P)
Ω ( n )