การจัดเรียงแบบ Shell Sort
Shell Sort
การจัดเรียงข้อมูลแบบ Shell Sort เป็นวิธีการที่ช่วยปรับปรุง Insertion Sort ให้มีจำนวนครั้งการสับเปลี่ยนข้อมูลลดลง
เนื่องจากวิธีการ Insertion Sort อาจจะเกิด Worst-Case
ในกรณีเลวร้าย ที่ค่าตัวเลขเล็กๆ ดันไปอยู่ที่ข้างท้ายๆ
ทำให้การสแกนหาตำแหน่งที่เหมาะสม ต้องใช้วิธีนานมาก
วิธีการ Shell Sort ปรับปรุงโดยทำการจัดเรียงชุดย่อย
โดยแต่ละชุดย่อยเรียกว่า k-sorted โดย k จะเป็นเลขลำดับที่เพิ่มมากขึ้นเรื่อยๆ เช่น k อาจจะเป็นเลข
{1, 3, 5} หมายถึง ครั้งแรกที่ทำ 5-sorted จะจัดเรียงตัวเลขทุกตัวที่ห่างกันทีละ 5 ช่อง เมื่อเรียงเสร็จแล้วจะทำ 3-sorted โดยจัดเรียงตัวเลขทุกตัวที่ห่างกันทีละ 3 ช่อง
และสุดท้ายจะทำ 1-sorted โดยจัดเรียงตัวเลขทุกตัวที่ติดกันอยู่
ซึ่งในรอบสุดท้ายที่ 1-sorted จะเป็นวิธีการเดียวกับ Insertion
Sort นั่นเอง
เราเรียกค่า k = {1, 3, 5} นี้ว่า
increment sequence และบางครั้งเรียกวิธีการจัดเรียง Shell
Sort นี้ว่า diminishing increment sort
ตัวอย่างเช่น ถ้ามีเลขอยู่ 13 ตัวดังนี้ และให้ k = {1, 3, 5}
ถ้าจะจัดเรียงแบบ Shell Sort รอบแรกเราจะทำ 5-sorted ก่อน
โดยจัดเรียงเฉพาะเลขที่ห่างกันไปทีละ 5 ดังนี้
ในแต่ละรอบย่อย เราจัดเรียงแบบ Insertion
Sort เช่น ในรอบบนสุด เราจัดเรียงเลข 81, 35, 41 แบบ Insertion Sort และใช้จำนวนครั้งในการสับเปลี่ยนตำแหน่งเป็น
2 ครั้ง
ในรอบย่อยต่อมาเราจัดเรียงเลข 94, 17, 75 และใช้จำนวนครั้งที่สับเปลี่ยนตำแหน่งเป็น 2 ครั้งเช่นกัน
เมื่อทำไปเรื่อยๆจนกระทั่งไม่ตัวให้เปรียบเทียบจะถือว่าเสร็จสิ้น
5-sorted ซึ่งจะได้ตามค่าแถวล่างสุด
และมีจำนวนครั้งการสับเปลี่ยนทั้งหมดรวม 5 ครั้ง
เมื่อขึ้นรอบใหม่ของ 3-sorted เราจะแบ่งกลุ่มเลขทีละ 3 ตำแหน่ง และนำมาจัดเรียงแบบ
Insertion Sort เช่นเดิม ซึ่งจะได้ผลลัพธ์ดังนี้
เมื่อเสร็จสิ้น 3-sorted เราจะได้จำนวนครั้งการสับเปลี่ยน
รวมทั้งหมด 5 ครั้ง และตัวเลขทั้งหมดเกือบจะเรียงกันหมดแล้ว
สังเกตว่าวิธีการของ Shell Sort จะทำให้เลขใกล้สู่การเรียงลำดับขึ้นสุดท้ายมากยิ่งขึ้นเรื่อยๆ
ทุกครั้งที่ผ่าน k-sorted ตามหลักการของ Insertion
Sort ปกติแล้วถ้าไพ่ในมือในจัดเรียงไว้ดีอยู่แล้ว
การรับไพ่ใบใหม่เข้ามาเพื่อแทรกเข้าไปในกองจะทำใช้เวลาลดลงเรื่อยๆ
ด้วยเหตุผลนี่เอง Shell Sort จึงพยายามทำให้เลขเรียงลำดับดีขึ้นเรื่อยๆ
เมื่อมาถึง 1-sorted ก็เกือบจะเรียงกันหมดแล้ว
ซึ่งจะมีผลทำให้ Insertion Sort ใช้เวลาน้อยมากกว่า Insertion
Sort ปกติ
เราจะจัดเรียงเลขชุดนี้ใน 1-sorted ตามแบบ Insertion Sort ปกติ ดังนี้
สังเกตว่าเมื่อจบ 1-sorted เราใช้จำนวนครั้งการสับเปลี่ยนไปทั้งหมด
12 ครั้ง เมื่อรวมการสับเปลี่ยนทั้งหมด ตั้งแต่ 5-sorted,
3-sorted และ 1-sorted เราใช้การสับเปลี่ยนไปทั้งหมด
5+5+12 = 22 ครั้ง
เทียบกับ Insertion Sort แบบปกติ
จากชุดข้อมูลข้างต้นถ้าเรานำตัวเลขมาจัดเรียงแบบ Insertion
Sort ตามปกติจะได้ขั้นตอนดังนี้
สังเกตว่า Insertion Sort ปกติ
จะใช้การสับเปลี่ยนทั้งหมด 39 ครั้ง ซึ่งเมื่อเทียบกับ Shell
Sort ที่ใช้เพียง 22 ครั้ง ถือว่า Shell
Sort มีประสิทธิภาพสูงกว่า
การเลือก Increment Sequence
ถ้าเราเลือก Increment Sequence ไม่ดีพออาจจะทำให้ Shell Sort ใช้ Big O ถึง O(N2) แต่ถ้าเราเลือก sequence
ที่ดีพอจะทำให้ได้ Big O ที่ต่ำกว่า
ตัวอย่างของนักคิดที่ให้ Increment
Sequence ไว้ดังนี้
o
Hibbard’s increment อ้างว่าสามารถทำได้ที่
O(N5/4)
o
Pratt แสดงให้เห็นว่าสามารถทำได้ที่
O(N3/2) ด้วยชุด increment sequence ที่กว้างมาก
o
Sedgewick ให้ sequence ไว้ที่ {1, 5, 19, 41, 109, ... } ซึ่งมาจากสูตร 9(4i)
– 9(2i) + 1 หรือ 4i – 3(2i)
+ 1 ซึ่งจะทำให้ได้ Worst-Case ที่ O(N4/3)
และคาดว่าโดยเฉลี่ยอาจจะได้ถึง O(N7/6)
ความคิดเห็น
แสดงความคิดเห็น