1 of 15

การจัดเรียงข้อมูล (sorting)

อาจารย์สุวิชยะ รัตตะรมย์

สำนักวิชาเทคโนโลยีสารสนเทศและการสื่อสาร

2 of 15

หัวข้อวันนี้

  • ขั้นตอนวิธี (Algorithm) การจัดเรียงแบบต่างๆ
    • Insertion sort (เรียนแล้ว)
    • Selection sort (เรียนแล้ว)
    • Bubble sort (เรียนแล้ว)
    • Merge sort (เรียนแล้ว)
    • Quick sort (ครั้งนี้)

2

3 of 15

Quick sort

  • ี่เหมาะกับข้อมูลที่มีขนาดใหญ่
  • จัดเรียงโดยแบ่งข้อมูลออกเป็นสองส่วนเพื่อใช้ในการจัดเรียง
    • คล้ายกับ merge sort
    • จัดอยู่ในกลุ่ม Divide and Conquer เช่นเดียวกัน
  • ได้ชื่อว่าเร็ว เพราะส่วนใหญ่จะทำงานได้เร็วที่สุด

3

4 of 15

Quick sort

  • quick sort จะเรียงข้อมูลพร้อมกับการแบ่งข้อมูล
  • โดยจะสุ่มเลือกข้อมูลขึ้นมา 1 ตัว เรียกว่า pivot
    • ส่วนมากเลือกจากข้อมูลตัวแรกหรือกึ่งกลางของกลุ่ม
  • จัดข้อมูลให้ด้านซ้ายเป็นข้อมูลที่มีค่าน้อยกว่า pivot
  • ด้านขวาเป็นข้อมูลที่มีค่ามากกว่า pivot
  • จะได้ข้อมูล 2 ส่วนซึ่งแยกกันด้วย pivot
  • นำแต่ละส่วนมาทำการ quick sort ไปเรื่อยๆ จนข้อมูลจัดเรียงอย่างถูกต้อง

4

5 of 15

  • MERGE SORT
    • แยกจนถึงที่สุด แล้วจึงประสานพร้อมกับจัดเรียง
  • QUICK SORT
    • แยกพร้อมกับจัดเรียง

5

6 of 15

6

(a[1] , a[2] , … , a[p] … , a[p-1] , a[n])

กลุ่มของข้อมูลที่มีค่าน้อยกว่า pivot

กลุ่มของข้อมูลที่มีค่ามากกว่า pivot

pivot ( a[p] )

quick sort

quick sort

quick sort

7 of 15

7

(4 , 10 , 2 , 6 , 5 , 8 , 7 , 3 , 9 , 1)

(4 , 2 , 3, 1)

( 10 , 6 , 8 , 7 , 9)

(1)

(4 , 3)

(6 , 7)

(10 , 9)

(5)

(2)

(3)

(4)

(-)

(8)

(-)

(6)

(7)

(9)

(10)

(-)

(1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10)

8 of 15

Quick sort : Choose the pivot

  • นิยมเลือก pivot จากข้อมูลตัวแรกของอาร์เรย์ หรือ ข้อมูลตัวที่อยู่กึ่งกลางของอาร์เรย์
    • เป็นการสุ่มอย่างหนึ่ง
  • ถ้าสุ่มเลือก pivot ได้ดี -> quick sort ทำงานได้เร็วมาก (เลือก pivot ที่แบ่งข้อมูลออกเป็น 2 ส่วนที่เท่ากัน)
  • ถ้าสุ่มเลือก pivot ได้ไม่ดี -> quick sort จะทำงานได้ช้า (เลือก pivot ที่แบ่งข้อมูลแล้วส่วนใดส่วนหนึ่งไม่มีข้อมูล – pivot เป็นข้อมูลที่มีค่ามากหรือน้อยที่สุด)
  • pivot กำหนดความเร็วของอัลกอริทึม

8

9 of 15

9

( ข้อมูลเริ่มต้น 10 ตัว )

(9 ตัว)

(8 ตัว)

pivot

pivot

(...)

pivot

(1 ตัว)

pivot

ทำ quick sort 9 ครั้ง

ตัวอย่างการเลือก pivot ที่ไม่ดี

เลือก pivot ที่แบ่งข้อมูลแล้วส่วนใดส่วนหนึ่งไม่มีข้อมูล – pivot เป็นข้อมูลที่มีค่ามากหรือน้อยที่สุด

10 of 15

10

( ข้อมูลเริ่มต้น 10 ตัว )

(4 ตัว)

(5 ตัว)

(2ตัว)

(2 ตัว)

pivot

pivot

ตัวอย่างการเลือก pivot ที่ดี

(1ตัว)

pivot

(1ตัว)

pivot

(2 ตัว)

(1ตัว)

pivot

(1ตัว)

pivot

ทำ quick sort 6 ครั้ง

เลือก pivot ที่แบ่งข้อมูลออกเป็น 2 ส่วนที่เท่ากัน, เกือบเท่ากัน

11 of 15

  • MERGE SORT
    • แยกออกเป็น 2 ส่วนที่เท่ากัน
  • QUICK SORT
    • แยกออกเป็น 2 ส่วน แต่ไม่จำเป็นต้องเท่ากัน

11

12 of 15

pseudo code ของ quick sort

function QuickSort (data A, int Lb, int Ub) {

if Lb < Ub then {

pivot = Partition (A, Lb, Ub)

QuickSort (A, Lb, pivot - 1)

QuickSort (A, pivot + 1, Ub)

}

}

function Partition (data A, int Lb, int Ub) {

select a pivot from A[Lb]...A[Ub]

reorder A[Lb]...A[Ub] such that :

all values to the left of the pivot are < pivot

all values to the right of the pivot are >= pivot

return pivot position

}

12

13 of 15

  • การจัดเรียงข้อมูลในฟังก์ชัน partition นิยมใช้วิธีการคล้ายกับ insertion sort (แทรกข้อมูล ณ ตำแหน่งที่ถูก)
  • โดยขั้นแรกจะทำการเลือก pivot ก่อน ซึ่งอาจเลือกจาก
    • ข้อมูลตัวแรกของพาร์ทิชัน หรือ
    • ข้อมูลที่อยู่กึ่งกลางของพาร์ทิชัน
  • จากนั้นจึงอ่านค่าที่เหลือของพาร์ทิชันและนำมาเปรียบเทียบกับ pivot ทีละตัว ถ้าตัวใดมีค่าน้อยกว่า pivot จะถูกสลับที่มาอยู่ฝั่งซ้าย ถ้าตัวใดมีค่ามากกว่า pivot จะถูกสลับที่มาอยู่ฝั่งขวา

13

14 of 15

function Partition (data A, int Lb, int Ub) {

// p_pos = (Lb+Ub) / 2

// swap (a[Lb],a[p_pos])

p_pos = Lb

pivot = a[Lb]

for ( i = Lb + 1 ; i <= Ub ; i++ ) {

if (a[i] < pivot) {

p_pos++

swap (a[i] , a[p_pos])

}

}

swap (a[Lb] , a[p_pos])

return p_pos

}

14

ตัวอย่าง

ในกรณีที่เลือกค่ากึ่งกลางพาร์ทิชันเป็น pivot

15 of 15

การวิเคราะห์อัลกอริทึม

  • ต้องวิเคราะห์เป็นกรณีต่างๆ หรือไม่ เพราะอะไร ?
    • ต้อง เพราะฟังก์ชัน Quicksort จะแบ่งข้อมูลออกเป็นกลุ่มตามผลการเลือก pivot
    • ถ้าเป็นกรณีที่ดีที่สุด จะได้รูปร่างคล้าย tree ที่มีความสูง log2n (complete binary tree)
    • กรณีแย่ที่สุด จะได้รูปร่างคล้าย tree ที่มีความสูง n
  • เนื่องจากการวิเคราะห์ค่อนข้างซับซ้อน จึงไม่พูดถึง
    • best = O (n log2n) , average = O (n log2n) , worst = O(n2)

15