อัลกอริทึม / โครงสร้างข้อมูลใดที่ฉันควร "รู้จัก" และรู้จักด้วยชื่อ? [ปิด]


69

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

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

คุณจัดการชุดล็อกเกอร์ที่มีข้อความ 0-999 ผู้คนมาหาคุณเพื่อเช่าตู้เก็บของและจากนั้นกลับมาเพื่อส่งคืนกุญแจตู้เก็บของ คุณจะสร้างซอฟต์แวร์ชิ้นหนึ่งเพื่อจัดการกับการรู้ว่าตู้เก็บของฟรีและที่ใช้อยู่อย่างไร

การแก้ปัญหาจะเป็นคิวหรือสแต็ค

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

ฉันลองดูรายการโครงสร้างข้อมูลและอัลกอริทึมของ Wikipedia แต่ฉันคิดว่ามันเกินความจริงเล็กน้อย ดังนั้นฉันจึงมองหาสิ่งสำคัญที่ฉันควรรู้


10
การลงคะแนนให้ปิดเป็น "ไม่สร้างสรรค์" คำตอบใด ๆ จะเป็นอัตนัยทั้งหมด - ไม่มีความเห็นพ้องกับสิ่งที่ "ควร" รู้
Oded

2
ส่วนใดของปัญหาตู้เก็บของที่ต้องใช้การสั่งซื้ออินพุต / เอาท์พุต [คำใบ้!]
Telastyn

5
@ เกินมีรายการที่ฉันคิดว่าคนส่วนใหญ่จะเห็นด้วยกับสิ่งที่โครงสร้างข้อมูลและอัลกอริทึมโปรแกรมเมอร์รอบรู้ควรรู้
David Cowden

6
@Oded ไม่มีฉันทามติ? หลักสูตรของหลักสูตรเบื้องต้นเกี่ยวกับอัลกอริทึมและโครงสร้างข้อมูลในวิทยาศาสตร์คอมพิวเตอร์เป็นอย่างไร มาตรฐานค่อนข้างดีและทบทวน จุดเริ่มต้นที่ดี
MarkJ

3
ทางเลือกอื่น สมมติว่าคุณเรียกเก็บเงินเป็นรายวันและมีค่าใช้จ่ายสูงสุด ติดแท็กกระดาษเข้ากับกุญแจเมื่อคุณปล่อยให้ตู้เก็บของและเขียนหมายเลขวัน Julian ลงไป เมื่อคีย์ถูกส่งคืนให้ดูที่แท็กเพื่อคำนวณค่าเช่าที่ถึงกำหนด แท็กที่ขาดหายไปหรือแท็กที่ดึงดูดจะดึงดูดการชาร์จสูงสุด คีย์ที่ไม่ได้ใช้จะถูกเก็บไว้ในกระเป๋า (เนื่องจากไม่จำเป็นต้องเลือกคีย์ใด ๆ จากคีย์ฟรีเมื่อปล่อยให้ตู้เก็บของ) ขนาดโครงสร้างข้อมูลทั้งหมด: ศูนย์บิต ทุกส่วนของอัลกอริทึมคือ O (1)
James Youngman

คำตอบ:


78

การตอบสนองวัตถุประสงค์:

ในขณะที่การตอบคำถามเริ่มแรกของฉันนั้นขึ้นอยู่กับประสบการณ์เชิงประจักษ์ของฉันในฐานะนักศึกษา CS ที่สำเร็จการศึกษาในไม่ช้าและความเห็นที่คาดการณ์ของฉันเกี่ยวกับประเภทของคนที่ฉันต้องการทำงานด้วยในสาขา CS จริงๆแล้วมีวัตถุประสงค์ (ด้วยความเคารพต่อความคิดเห็นส่วนตัวของคำตอบ ACM SIGCSE และ IEEE computing community) ทุก ๆ 10 ปีACMและหน่วยงานIEEEร่วมมือกันในการจัดพิมพ์ร่วมที่ให้รายละเอียดข้อเสนอแนะสำหรับหลักสูตรวิทยาศาสตร์คอมพิวเตอร์ระดับปริญญาตรีจากความรู้ทางวิชาชีพของรัฐของอุตสาหกรรมคอมพิวเตอร์ ข้อมูลเพิ่มเติมสามารถพบได้ที่cs2013.org คณะกรรมการเผยแพร่รายงานขั้นสุดท้ายในรายการข้อเสนอแนะหลักสูตรของพวกเขา

ที่กล่าวว่าฉันยังคงคิดว่ารายการของฉันค่อนข้างดี

คำตอบเดิมด้านล่าง


ฉันควรรู้อะไร

ขั้นต่ำ

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

เพื่อตอบคำถามชื่อนี่คือสิ่งที่นักเรียน CS ระดับปริญญาตรี (รากฐานสำหรับโปรแกรมเมอร์ผู้เชี่ยวชาญ) ควรรู้เมื่อสำเร็จการศึกษา:

โครงสร้างข้อมูล

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

อัลกอริทึม

  • เรียงลำดับ:
    • Bubble Sort (รู้ว่าทำไมมันถึงไม่ดี)
    • เรียงลำดับการแทรก
    • รวมการเรียงลำดับ
    • จัดเรียงด่วน
    • เรียงลำดับสไตล์ Radix เรียงลำดับการนับและเรียงลำดับ Bucket
    • เรียงลำดับกอง
    • Bogo และ Quantum Sort (=
  • ค้นหา:
    • การค้นหาเชิงเส้น
    • ค้นหาแบบทวิภาค
    • ค้นหาความลึกครั้งแรก
    • ค้นหาความกว้างครั้งแรก
  • การจัดการสตริง
  • การย้ำ
  • Tree Traversal
  • รายการสำรวจเส้นทาง
  • ฟังก์ชั่นคร่ำเครียด
  • การนำไปใช้อย่างเป็นรูปธรรมของตารางแฮชต้นไม้รายการลิสคิวคิวอาร์เรย์และชุดหรือการรวบรวม
  • อัลกอริทึมการจัดตารางเวลา
  • การข้ามผ่านระบบไฟล์และการจัดการ (ในinodeหรือระดับที่เทียบเท่า)

รูปแบบการออกแบบ

  • modularization
  • โรงงาน
  • ผู้ก่อสร้าง
  • ซิงเกิล
  • อะแดปเตอร์
  • มัณฑนากร
  • ฟลายเวท
  • ผู้สังเกตการณ์
  • iterator
  • รัฐ [เครื่องจักร]
  • Model View Controller
  • รูปแบบการเขียนโปรแกรมเธรดและขนาน

กระบวนทัศน์

  • ความจำเป็น
  • วัตถุที่มุ่งเน้น
  • การทำงาน
  • ที่เปิดเผย
  • การเขียนโปรแกรมแบบคงที่และแบบไดนามิก
  • Data Markup

ทฤษฎีความซับซ้อน

  • Complexity Spaces
  • การคำนวณ
  • ภาษาที่สมบูรณ์แบบปกติไม่มีบริบทและเครื่องทัวริงทั่วไป
  • นิพจน์ทั่วไป
  • การนับและ Combinatorics พื้นฐาน

เกิน

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

นี่คือเคล็ดลับบางส่วนสำหรับอัลกอริทึมและโครงสร้างข้อมูล:

  • การค้นหาแบบไบนารี่สามารถใช้ (และควร) กับข้อมูลที่เรียงลำดับเท่านั้น
  • ประเภทของ Radix นั้นยอดเยี่ยม แต่เฉพาะเมื่อคุณมีคลาสที่ จำกัด ของสิ่งต่าง ๆ ที่ถูกจัดเรียง
  • ต้นไม้ดีสำหรับเกือบทุกอย่างเช่นเดียวกับตารางแฮช ฟังก์ชันการทำงานของตารางแฮชสามารถคาดการณ์และใช้ในการแก้ปัญหาต่าง ๆ ในราคาที่มีประสิทธิภาพ
  • อาร์เรย์สามารถใช้เพื่อสำรองโครงสร้างข้อมูลระดับที่สูงขึ้นได้ บางครั้ง "โครงสร้างข้อมูล" ไม่ได้เป็นเพียงแค่คณิตศาสตร์ที่ชาญฉลาดสำหรับการเข้าถึงตำแหน่งในอาเรย์เท่านั้น
  • การเลือกภาษาอาจเป็นความแตกต่างระหว่างการดึงผมออกไปหรือแล่นผ่านปัญหา
  • ตาราง ASCII และอาเรย์องค์ประกอบ 128 สร้างตารางแฮชโดยนัย (=
  • นิพจน์ทั่วไปสามารถแก้ปัญหาได้มากมาย แต่ไม่สามารถใช้ในการแยกวิเคราะห์ HTMLได้
  • บางครั้งโครงสร้างข้อมูลมีความสำคัญเท่ากับอัลกอริทึม

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

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


ตอบปัญหาที่เกิดขึ้นในคำถามของคุณ

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

คุณมีตู้เก็บของ 0-999 ตอนนี้เนื่องจากคุณมีตู้เก็บของจำนวนคงที่คุณจึงสามารถตั้งค่าฟังก์ชันแฮชได้อย่างง่ายดายโดยไม่มีการชนในช่วง 0-999 ฟังก์ชั่นนี้เป็นเพียง h (x) = x mod 1000 ตอนนี้ [conceptually] สร้างตารางแฮชที่มีปุ่มจำนวนเต็มและเนื้อหาของอาร์เรย์ 1,000 องค์ประกอบถ่านเป็นค่าของคุณ หากลูกค้าต้องการจองตู้เก็บของ 78 สำหรับการใช้งานเพียงแค่ใส่ 78 ลงในฟังก์ชั่นแฮช (กลับ 78) แล้วเพิ่มหมายเลขนั้นไปที่ตัวชี้ฐานของอาร์เรย์ - เก็บค่าจริงที่ตำแหน่งที่ชี้โดยค่าออฟเซ็ต . ในทำนองเดียวกันหากคุณจำเป็นต้องตรวจสอบว่ามีการใช้งาน 78 เพียงแค่อ่านค่าที่เก็บไว้ในสถานที่นั้นและตรวจสอบกับความจริง

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

ทีนี้คุณอาจถามว่าถ้าฉันจำเป็นต้องรู้ว่าตู้เก็บของที่มีอยู่ทั้งหมดจะไม่ดีกว่าหรือไม่ หากมีตู้เก็บของ k อยู่ในคิวลำดับความสำคัญการวนซ้ำทั้งหมดจะใช้ขั้นตอน k นอกจากนี้ขึ้นอยู่กับการใช้คิวลำดับความสำคัญของคุณคุณอาจต้องสร้างคิวลำดับความสำคัญของคุณใหม่อีกครั้งในขณะที่ดูทั้งหมด .. ซึ่งจะใช้ขั้นตอน k * log (k): (k <1,000) ขั้นตอน ในโซลูชันอาร์เรย์คุณจะต้องวนซ้ำขององค์ประกอบ 1000 รายการเท่านั้นและตรวจสอบว่ารายการใดเปิดอยู่ นอกจากนี้คุณยังสามารถเพิ่มรายการที่มีอยู่หรือที่ใช้ไปยังการใช้งานเพื่อตรวจสอบในเวลา k เท่านั้น


1
คำตอบที่ดี! ฉันต้องการเพิ่มด้วยเช่นกันว่าคุณควรมั่นใจในการใช้ฟังก์ชัน / โครงสร้างข้อมูลที่กำหนดไว้ล่วงหน้าของภาษาที่คุณใช้ตัวอย่างเช่นอัลกอริทึมและโครงสร้างข้อมูล stl ใน C ++ หรือ Java API สำหรับ Java
marktani

1
ยอดเยี่ยม! โดยเฉพาะ "นิพจน์ทั่วไปสามารถแก้ปัญหาได้มากมาย แต่ไม่สามารถใช้ในการแยกวิเคราะห์ HTML"
FrustratedWithFormsDesigner

2
คำตอบนั้นดีจนกระทั่ง "ปัญหา" ปรากฏขึ้น ไม่มีเหตุผลเลยที่จะใช้ลำดับความสำคัญคิวหรือตารางแฮช สแต็กง่ายเพียงพอ เพิ่มการวนซ้ำเพื่อรับรายการตู้เก็บของฟรีหากคุณต้องการ
Matthieu M.

1
เราควรเพิ่มฐานข้อมูลเชิงสัมพันธ์ + SQL ความรู้ของต้นไม้ B + ทฤษฎีคอมไพเลอร์องค์กรฮาร์ดแวร์ความรู้ความรู้เกี่ยวกับทฤษฎีระบบปฏิบัติการความรู้เกี่ยวกับเครือข่าย TCP / IP?
dan_l

1
ฉันสงสัยเกี่ยวกับรูปแบบการออกแบบ หลายคนมีประโยชน์ในภาษาบางประเภทในขณะที่ไร้ประโยชน์และ / หรือไม่จำเป็นในภาษาอื่น ๆ คุณอาจต้องการเพิ่มการวิเคราะห์พฤติกรรมภายใต้อัลกอริทึมและโครงสร้างข้อมูล trie และ skip-list อัลกอริทึมแบบดั้งเดิม / โครงสร้างข้อมูลเข้าถึงข้อ จำกัด ในการเข้าถึงแบบซิงโครนัส แต่สามารถเอาชนะได้โดยวิธีการที่ไม่ใช่แบบดั้งเดิมอื่น ๆ โดยใช้หลายเธรดและการทำงานพร้อมกัน การวิเคราะห์พฤติกรรมสามารถลดจำนวนการค้นหาที่ต้องการได้อย่างมากในขณะที่โครงสร้างเช่นรายการข้ามจะทำให้สามารถเขียนโครงสร้างข้อมูลได้โดยไม่ต้องล็อกส่วนกลาง
Evan Plaice

6

คู่มือการออกแบบอัลกอริทึมโดย Steven S. Skiena ดูเหมือนแหล่งข้อมูลที่คุณกำลังค้นหา ส่วนที่สองคือรายการปัญหาที่เกิดขึ้นกับการทบทวนขั้นตอนวิธีที่เกี่ยวข้อง มีความเป็นเว็บรุ่น


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

@KateGregory ฉันซื้อหนังสือเล่มนี้แล้วไม่สามารถเข้าใจได้เพราะฉันรู้ภาษาระดับสูงอย่าง Ruby และ Javascript (ไม่มีต้นไม้ไบนารีรายการเชื่อมโยง ฯลฯ ) ... ในที่สุดฉันก็เลิกอ่านมัน
bigpotato

4

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

จากนั้นก็มีสิ่งที่เป็นนามธรรม แต่มีประโยชน์อย่างมาก (แม้ว่าประโยชน์จะไม่ชัดเจนในทันที): เครื่องจักรของรัฐ, ทฤษฎีกราฟ, ทฤษฎีนูน (การเขียนโปรแกรมเชิงเส้น ฯลฯ )


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

3

MIT เผยแพร่เอกสารประกอบการบรรยายฟรี, วิดีโอ, การบ้านและการสอบวัสดุสำหรับการแนะนำให้รู้จักกับอัลกอริทึม ชื่อบรรยายรายการอัลกอริทึม / โครงสร้างข้อมูลที่ครอบคลุม

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

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