อะไรคือกฎเกณฑ์ที่เป็นรูปธรรมสำหรับการใช้รายการที่เชื่อมโยงแทนที่จะเป็นอาร์เรย์


18

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

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


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

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

คำตอบ:


37

นี่คือบางส่วนของวิธีระหว่างตัวอย่างและการเปรียบเทียบ คุณมีธุระที่ต้องทำดังนั้นคุณหยิบกระดาษแล้วเขียน:

  • ธนาคาร
  • ร้านขายของชำ
  • ย่อหย่อน

จากนั้นคุณจำได้ว่าคุณต้องซื้อแสตมป์ด้วย เนื่องจากภูมิศาสตร์ของเมืองของคุณคุณต้องทำเช่นนั้นหลังจากธนาคาร คุณสามารถคัดลอกรายการทั้งหมดของคุณไปยังกระดาษแผ่นใหม่:

  • ธนาคาร
  • แสตมป์
  • ร้านขายของชำ
  • ย่อหย่อน

หรือคุณสามารถเขียนลวก ๆ ในสิ่งที่คุณมี:

  • ธนาคาร ....... STAMPS
  • ร้านขายของชำ
  • ย่อหย่อน

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

จากนั้นโทรศัพท์มือถือของคุณดังขึ้นในขณะที่คุณอยู่ที่ธนาคาร "เฮ้ฉันได้รับแสตมป์ไม่ต้องไปรับอีกแล้ว" คุณเพิ่งลบ STAMPS ออกจากรายการคุณไม่ต้องเขียนใหม่ทั้งหมดโดยไม่ต้องติดตั้ง STAMPS

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


3
ตาม Bjarne Stroustrup, LLS อาจจะไม่เป็นเรื่องง่ายและรวดเร็วสำหรับการคัดลอกรายชื่อทั้งหมดที่คุณคิดว่า
เดนนิส

@ เดนนิสใช่ฉันรู้ขอบคุณด้วยการย้ายซีแมนทิกส์ อย่างไรก็ตามสิ่งนี้ไม่เป็นความจริงสำหรับทุกภาษา
Kate Gregory

1
@KateGregory ยุติธรรมเพียงพอ แต่ก็ยังดีที่ชี้ให้เห็นว่าโครงสร้างข้อมูล "พื้นฐาน" มักจะดีกว่าโครงสร้างข้อมูลที่เราเรียนรู้ในโรงเรียน (หรือที่อื่น ๆ ) ฉันไม่ต้องการให้จบใหม่ใช้ LLs ทุกแห่งเพราะมันเหมาะสมในทางทฤษฎีในขณะที่อาจเป็นทางเลือกที่แย่ การใช้โครงสร้างข้อมูลที่ถูกต้องเป็นสิ่งสำคัญและบางครั้งผู้คนจะเข้าใจมันมากเกินไป ที่เกี่ยวข้องกันเล็กน้อยคือการพูดคุยนี้โดยโจนาธานเป่า (ผู้สร้างของ "เปีย") บนโครงสร้างข้อมูล
Dennis

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

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

18
  • Hashtables ที่ใช้การเชื่อมโยงเพื่อแก้ไขการชนกันของแฮชจะมีรายการที่เชื่อมโยงหนึ่งรายการต่อที่เก็บข้อมูลสำหรับองค์ประกอบในที่เก็บข้อมูลนั้น
  • ตัวจัดสรรหน่วยความจำอย่างง่ายใช้รายการพื้นที่หน่วยความจำที่ไม่ได้ใช้งานฟรีโดยทั่วไปเป็นรายการที่เชื่อมโยงกับตัวชี้รายการภายในหน่วยความจำอิสระ
  • ในระบบไฟล์ FATเมตาดาต้าของไฟล์ขนาดใหญ่จะถูกจัดระเบียบเป็นรายการที่เชื่อมโยงของรายการ FAT

12

C-language "call stack" ถูกนำไปใช้เป็นรายการที่เชื่อมโยงใน API ไบนารี x86 (และอื่น ๆ ส่วนใหญ่)

นั่นคือการเรียกใช้โพรซีเดอร์ภาษา C เป็นไปตามวินัยเข้าก่อนออกก่อน ผลลัพธ์ของการเรียกใช้ฟังก์ชัน (อาจเรียกซ้ำ) เรียกว่า "สแตกการเรียก" หรือบางครั้งแม้แต่ "สแต็ก"

CALLคำสั่ง x86 จบลง implmenting รายการที่เชื่อมโยงโดยใช้ "โทรกอง" CALLคำแนะนำและผลักดันให้เนื้อหาของ% EIP ลงทะเบียนที่อยู่ของการเรียนการสอนที่หลังจากCALLบนหน่วยความจำสแต็ค Prolog ที่เรียกว่า fuction จะผลักเนื้อหาของการลงทะเบียน% EBP ซึ่งเป็นที่อยู่ที่ต่ำที่สุดของตัวแปรโลคัลในการเรียกฟังก์ชันลงในหน่วยความจำสแต็ก จากนั้นฟังก์ชันที่เรียกว่า prolog จะตั้งค่า% EBP เป็นฐานสแต็กของฟังก์ชันปัจจุบัน

นั่นหมายความว่า% EBP เป็นตัวชี้ไปยังตำแหน่งหน่วยความจำที่เก็บที่อยู่ของค่า% EBP ของฟังก์ชันการโทร CALLนั่นเป็นอะไรมากไปกว่ารายการเชื่อมโยงการดำเนินการในส่วนของฮาร์ดแวร์ผ่าน

เท่าที่สิ่งนี้ดีสำหรับมันเป็นวิธีที่ x86 ซีพียูใช้การเรียกใช้ฟังก์ชั่นโดยเฉพาะอย่างยิ่งการเรียกใช้ฟังก์ชั่นที่ฟังก์ชั่นมีสำเนาของตัวเองขัดแย้งและตัวแปรท้องถิ่นเพื่อฟังก์ชั่น การเรียกใช้ฟังก์ชันทุกครั้งจะส่งข้อมูลบางอย่างเกี่ยวกับ "call stack" ที่ทำให้ CPU สามารถรับตำแหน่งที่ค้างไว้ในฟังก์ชั่นการโทรโดยไม่มีสัญญาณรบกวนจากฟังก์ชันที่เรียกหรือฟังก์ชั่นการโทร


3

รายการที่เชื่อมโยงสามารถใช้ในการใช้คิวข้อความ

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

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

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

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