เหตุใดจึงแทรกกลางรายการที่เชื่อมโยง O (1)


106

ตามบทความ Wikipedia เกี่ยวกับรายการที่เชื่อมโยงการแทรกกลางรายการที่เชื่อมโยงถือเป็น O (1) ฉันคิดว่ามันจะเป็น O (n) คุณไม่จำเป็นต้องค้นหาโหนดที่อาจอยู่ใกล้ท้ายรายการหรือไม่?

การวิเคราะห์นี้ไม่ได้อธิบายถึงการค้นหาการทำงานของโหนด (แม้ว่าจะจำเป็น) และเป็นเพียงแค่การแทรกเท่านั้นเอง?

แก้ไข :

รายการที่เชื่อมโยงมีข้อดีหลายประการเหนืออาร์เรย์ การแทรกองค์ประกอบที่จุดเฉพาะของรายการเป็นการดำเนินการที่มีเวลาคงที่ในขณะที่การแทรกในอาร์เรย์อาจต้องการการเคลื่อนย้ายองค์ประกอบครึ่งหนึ่งหรือมากกว่านั้น

ข้อความข้างต้นทำให้ฉันเข้าใจผิดเล็กน้อย แก้ไขฉันถ้าฉันผิด แต่ฉันคิดว่าข้อสรุปควรเป็น:

อาร์เรย์:

  • การหาจุดแทรก / ลบ O (1)
  • การดำเนินการแทรก / ลบ O (n)

รายการที่เชื่อมโยง:

  • การหาจุดแทรก / ลบ O (n)
  • การดำเนินการแทรก / ลบ O (1)

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

คำตอบ:


113

คุณถูกต้องบทความนี้ถือว่า "การจัดทำดัชนี" เป็นการดำเนินการแยกต่างหาก ดังนั้นการแทรกจึงเป็น O (1) แต่การไปยังโหนดกลางนั้นคือ O (n)


3
ซึ่งสร้างความแตกต่างได้มากขึ้นเมื่อใส่วัตถุมากกว่า 1 ชิ้นในตำแหน่งเดียวกัน ...
มี QUIT - Anony-Mousse

@ Anony-Mousse ช่วยอธิบายอีกหน่อยได้ไหม? เช่นเราต้องหาตำแหน่งแทรกเพียงครั้งเดียวเมื่อแทรกวัตถุหลายชิ้น?
MyTitle

2
เป็น O (n) ในขนาดของรายการที่มีอยู่ไม่ใช่จำนวนส่วนแทรกที่คุณวางแผนจะทำที่นั่น
Has QUIT - Anony-Mousse


26

ไม่เมื่อคุณตัดสินใจว่าต้องการแทรกก็ถือว่าคุณอยู่ในระหว่างการทำซ้ำในรายการ

การดำเนินการกับรายการที่เชื่อมโยงมักจะทำในลักษณะที่ไม่ถือว่าเป็น "รายการ" ทั่วไป แต่เป็นชุดของโหนดให้คิดว่าโหนดนั้นเป็นตัววนซ้ำสำหรับลูปหลักของคุณ ดังนั้นเมื่อคุณสำรวจรายการคุณสังเกตเห็นว่าเป็นส่วนหนึ่งของตรรกะทางธุรกิจของคุณว่าจำเป็นต้องเพิ่มโหนดใหม่ (หรือลบโหนดเก่า) แล้วคุณก็ทำเช่นนั้น คุณสามารถเพิ่ม 50 โหนดในการทำซ้ำครั้งเดียวและแต่ละโหนดมีค่าเพียง O (1) เวลาในการยกเลิกการเชื่อมโยงสองโหนดที่อยู่ติดกันและใส่โหนดใหม่ของคุณ ..

แก้ไข: ผู้ชายคุณพิมพ์ย่อหน้าที่สองและทันใดนั้นแทนที่จะเป็นผู้ตอบคนแรกคุณเป็นคนที่ 5 พูดแบบเดียวกับ 4 คนแรก!


1
ใช่แล้วที่แย่ ... ฉัน +1 ของคุณเพราะมันคุ้มค่าที่ระบุว่าความซับซ้อนของการแทรกรายการที่เชื่อมโยงนั้นได้รับการพิจารณาในบริบทของการอยู่ในตัวชี้ที่ต้องการแล้ว
Daniel Macias

6

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

ใช่พวกเขาสมมติว่าคุณมีตัวชี้ไปยังโหนดนั้นอยู่แล้วหรือการได้รับตัวชี้เป็นเรื่องเล็กน้อย กล่าวอีกนัยหนึ่งคือปัญหาระบุ: " โหนดที่กำหนดไว้ที่ Xโค้ดที่จะแทรกหลังจากโหนดนี้คืออะไร" คุณจะเริ่มต้นที่จุดแทรก


5

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


3

เนื่องจากไม่เกี่ยวข้องกับการวนซ้ำใด ๆ .

การแทรกเป็นเหมือน:

  • แทรกองค์ประกอบ
  • ลิงก์ไปยังหน้าที่แล้ว
  • ลิงก์ไปยังถัดไป
  • เสร็จแล้ว

นี่เป็นเวลาคงที่ไม่ว่าในกรณีใด ๆ

ดังนั้นการแทรกองค์ประกอบ n ทีละรายการคือ O (n)


3

การวิเคราะห์นี้ไม่ได้อธิบายถึงการค้นหาการทำงานของโหนด (แม้ว่าจะจำเป็น) และเป็นเพียงแค่การแทรกเท่านั้นเอง?

คุณเข้าใจแล้ว การแทรกในจุดที่กำหนดจะถือว่าคุณถือตัวชี้ไปยังรายการที่คุณต้องการแทรกหลังจาก:

InsertItem(item * newItem, item * afterItem)


2

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

หากคุณต้องค้นหาคุณจะต้องเพิ่มเวลาในการค้นหาซึ่งควรเป็น O (n)


0

บทความนี้เกี่ยวกับการเปรียบเทียบอาร์เรย์กับรายการ การค้นหาตำแหน่งแทรกสำหรับทั้งอาร์เรย์และรายการคือ O (N) ดังนั้นบทความจึงไม่สนใจ


1
จะไม่พบจุดแทรกของอาร์เรย์เป็น O (1)? เนื่องจากอาร์เรย์ถูกเก็บไว้ในหน่วยความจำที่อยู่ติดกันสิ่งที่ต้องทำคือเพิ่มออฟเซ็ต
Rob Sobers

@ vg1890 - คุณต้องหาออฟเซ็ตก่อน

0

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


0

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


0

หากคุณมีการอ้างอิงของโหนดที่จะแทรกหลังจากการดำเนินการคือ O (1) สำหรับรายการที่เชื่อมโยง
สำหรับอาร์เรย์จะยังคงเป็น O (n) เนื่องจากคุณต้องย้ายโหนด consequtive ทั้งหมด


0

กรณีที่พบบ่อยที่สุดน่าจะเป็นการแทรกที่จุดเริ่มต้นหรือตอนท้ายของรายการ (และส่วนท้ายของรายการอาจใช้เวลาค้นหาไม่นาน)

ตรงกันข้ามกับการแทรกรายการที่จุดเริ่มต้นหรือจุดสิ้นสุดของอาร์เรย์ (ซึ่งต้องมีการปรับขนาดอาร์เรย์หากอยู่ท้ายสุดหรือปรับขนาดและย้ายองค์ประกอบทั้งหมดหากเป็นจุดเริ่มต้น)


เป็นไปได้ที่จะทำให้การแทรกรายการในส่วนท้ายของอาร์เรย์เป็น O (1) หากคุณเก็บบัฟเฟอร์ขององค์ประกอบว่างไว้ที่ส่วนท้ายแม้ว่าในบางครั้งส่วนแทรกจะยังคงเป็น O (1) คอลเลกชันส่วนใหญ่ทำเช่นนี้ นอกจากนี้ยังเป็นไปได้ที่จะทำให้รายการเฉื่อยในจุดเริ่มต้นของอาร์เรย์เป็น O (1) โดยเปลี่ยนตัวดำเนินการดัชนีของคุณเพื่อส่งคืนหมายเลของค์ประกอบ (n + x)% len โดยที่ x คือจำนวนครั้งที่คุณแทรกรายการในจุดเริ่มต้น ของรายการ บางครั้งมีการนำ Deques มาใช้เช่นนี้ (แต่บางครั้งก็มีการใช้งานกับรายการที่เชื่อมโยงกันเป็นสองเท่า
Brian
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.