อัลกอริทึมแบบไหนที่ใช้?


24

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

(sort (cons newelt list) #'<)

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

ดังนั้นอัลกอริทึมที่sortใช้คืออะไร

ฉันจะทำสิ่งต่อไปนี้ดีขึ้นไหม

(let ((tail list))
  ;; The first element is never less-than
  (while (and tail (< newelt (cadr tail)))
    (setq tail (cdr tail)))
  (setcdr tail (cons newelt (cdr tail)))
  list)

1
ฉันจะใช้ binary heap (เช่นheap.el ) หากเป็นการดำเนินการบ่อยครั้งในรหัสของฉัน
Lunaryorn

อนุญาตให้Bเริ่มต้นเรียงแล้วlistและAและCรายการว่างเปล่าเริ่มต้น สปลิตBในสองส่วนB1, B2ความยาวmและmหรือm+1และmการเปรียบเทียบกับองค์ประกอบแรกของnewelt B2ถ้าneweltเป็นขยายAไปทางขวาด้วยB1และแทนที่Bด้วยB2อื่นขยายCไปทางซ้ายด้วยB2และแทนที่ด้วยB B1หลังจากขั้นตอนดังกล่าวไม่มีอะไรเหลือในO(log n) Bจากนั้นAมีสิ่งต่าง ๆ≤ neweltและสิ่งCเหล่านั้น> neweltและการต่อข้อมูลจะสร้างรายการที่เรียงลำดับแบบขยาย ขอโทษที่ไม่e-lispชอบภาษา
jfbu

คำตอบ:


26

หากคุณมีรหัสที่มา Emacs ติดตั้งคุณสามารถค้นหารหัสแหล่งที่มาสำหรับกับsortM-x find-function

คุณจะเห็นว่าsortมีการเรียงลำดับการผสาน ตรวจสอบความยาวของรายการแบ่งรายการออกเป็นครึ่งเรียงเรียงส่วน "ด้านหน้า" และ "ย้อนกลับ" แยกจากกันผ่านการเรียกซ้ำแล้วจึงผสานสองรายการเข้าด้วยกัน

สำหรับว่าการใช้งานของคุณจะเร็วขึ้นหรือไม่ - วัดได้! มันมีประสิทธิภาพมากกว่าในทางทฤษฎี (O (n) vs O (n log n)) แต่sortมีความได้เปรียบในการเขียนใน C ดังนั้นผลลัพธ์อาจไปในทิศทางใดทางหนึ่ง (แน่นอนอย่าลืมรวบรวมฟังก์ชั่นของคุณด้วยไบต์)


@Malabarba สำหรับบันทึกคุณทดสอบความยาวเท่าไหร่?
ต. Verron

8
ผ่านการทดสอบ 1,000 ครั้งโดยใส่หมายเลขสุ่มลงในรายการ 1,000 หมายเลขสุ่ม (ทุกรุ่นถูกสร้างขึ้นล่วงหน้า) วิธีการด้วยตนเองเร็วขึ้น 6 เท่า
Malabarba
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.