User Tools

Site Tools


Sidebar

1. บทนำ

2. การวิเคราะห์ Algorithm

3. List, Stack and Queue

4. Tree

5. Hashing

6. Priority Queues

7. การจัดเรียง (Sorting)

8. The Disjoint Set

9. Graph Algorithms

dsa:sheap

7.5. Heapsort

ในบทที่ 6 ได้กล่าวแล้วว่าเราอาจใช้ priority queues ในการจัดเรียงด้วยเวลา O(N log N) อัลกอริทึมที่ใช้พื้นฐานแนวคิดนี้ เรียกว่า heapsort และมี Big-Oh running time ดีกว่าอัลกอริทึมอื่น ๆ ที่กล่าวมาแล้ว อย่างไรก็ตาม ในทางปฏิบัติแล้วมันทำงานช้ากว่า shellsort ที่ใช้ลำดับการเพิ่มของ Sedwick

วิธีการที่ใช้ตามที่กล่าวในบทที่ 6 คือ สร้าง binary heap (มีสมาชิก N ตัว) ซึ่งใช้เวลาเป็น O(N) จากนั้นทำ deleteMin N ครั้ง สมาชิกที่ถูกย้ายออกไปจาก heap ตัวแรก คือตัวที่มีค่าน้อยที่สุด และเรียงลำดับตามค่าไป แล้วนำไปเก็บในอะเรย์อีกตัวหนึ่งจากนั้นก็คัดลอกกลับไปยังอะเรย์เดิมซึ่งก็จะเป็นคำตอบในการจัดเรียง เนื่องจากการทำ deleteMin แต่ละตัวใช้ O(log N) ดังนั้น running time รวมทั้งหมด คือ O(N log N)

ปัญหาของอัลริทึมนี้ คือ ต้องใช้อะเรย์เพิ่มเข้ามาสำหรับเก็บค่าที่ deleteMin ออกไปจาก heap นั่นคือต้องใช้พื้นที่หน่วยความจำเพิ่มขึ้นเป็นสองเท่า และอาจก่อปัญหาได้ในบางกรณี ส่วนเวลาที่ใช้ในการคัดลอกอะเรย์กลับไปยังอะเรย์แรกนั้นใช้เวลาเป็น O(N) ซึ่งไม่มีผลอย่างมีนัยสำคัญต่อ running time เพื่อหลีกเลี่ยงการใช้อะเรย์ตัวที่สองดังกล่าว เราพบว่าหลังจากการ deleteMin แต่ละครั้งนั้นขนาดของ heap ก็จะลดลง 1 ตัวด้วย ดังนั้นตำแหน่งเซลล์ใน heap ที่ว่างซึ่งเป็นตำแหน่งสุดท้ายใน heap เดิมนั้นก็สามารถนำมาใช้ในการเก็บค่าของตัวที่เพิ่งจะถูกย้ายออกไปนั้นได้ เช่น ถ้าเรามี heap ที่มีสมาชิก 6 ตัว การทำ deleteMin ครั้งแรกจะได้ a1 และทำให้ heap เหลือสมาชิก 5 ตัว ดังนั้นเราก็สามารถบรรจุ a1 ลงในตำแหน่งที่ 6 ที่ว่างนั้นได้ การ deleteMin ถัดมาได้ a2 และ heap จะมีสมาชิกเหลือเพียง 4 ตัว และเราสามารถบรรจุ a2 ลงในตำแหน่ง 5 ได้

ด้วยกรรมวิธีที่กล่าวมาข้างบนนี้ หลังการทำงาน deleteMin ครั้งสุดท้ายแล้ว เราจะได้อะเรย์ที่มีสมาชิกจัดเรียงค่าจากมากไปน้อย ดังนั้นถ้าเราต้องการจัดเรียงค่าจากน้อยไปมาก เราก็จะใช้วิธีการเดียวกันนี้เพียงแต่ต้องใช้ heap ที่ parent มีค่ามากกว่า child ของมัน นั่นคือ (max)heap ในที่นี้เราจะใช้ (max)heap ในการ implement ของเราและยังคงใช้อะเรย์เช่นเดิม ขั้นแรกสร้าง heap ด้วย linear time จากนั้นทำ deleteMax เป็นจำนวน N - 1 ครั้ง ด้วยการสลับสมาชิกตัวสุดท้ายใน heap กับสมาชิกตัวแรก แล้วลดขนาดของ heap ลงแล้วทำการ percolating down หลังจบอัลกอริทึมจะได้อะเรย์ที่มีสมาชิกเรียงตามลำดับค่า เช่นมีลำดับของค่าเริ่มต้นคือ 31, 41, 59, 26, 53, 58, 97 ซึ่งสร้าง heap ได้ดังรูปที่ 7.6 ภายหลังจากทำการ deleteMax ครั้งแรกแล้วก็จะได้สถานะของ heap และอะเรย์ดังรูปที่ 7.7 ซึ่งมีค่า 31 เป็นค่าสุดท้ายใน heap และ 97 ถูกบรรจุลงในตำแหน่งสุดท้ายของ heap ซึ่งในทางเทคนิกแล้วในขณะนี้ตำแหน่งดังกล่าวนี้ไม่ถือว่าเป็นส่วนหนึ่งของ heap อีกต่อไปแล้ว รูปที่ 7.8 เป็นโปรแกรม heapsort ซึ่งแตกต่างจาก binary heap เล็กน้อย คือ ในที่นี้จะใช้อะเรย์ตั้งแต่ตำแหน่ง 0 แต่สำหรับ binary heap เราใช้ตำแหน่งที่ 1 ของอะเรย์เป็นตำแหน่งแรก

97 53 59 26 41 58 31
0 1 2 3 4 5 6 7 8 9 10

รูปที่ 7.6 รูป Heap หลัง buildHeap

59 53 58 26 41 31 97
0 1 2 3 4 5 6 7 8 9 10

รูปที่ 7.7 รูป Heap หลังการ deleteMax ครั้งแรก  

/* Internal method for heapsort.
    return the index of the left child. */
private static int leftChild( int i )  
{  
    return 2 * i + 1;  
}
private static void percDown( Comparable [ ] a, int i, int n )
{           
        int child;
        Comparable tmp;
/* 1*/  for ( tmp = a[ i ]; leftChild( i ) < n; i = child )
        {
/* 2*/      child = leftChild( i );
/* 3*/      if (child != n - 1 && a[child].compareTo(a[ child + 1 ]) < 0 )
/* 4*/          child++;
/* 5*/      if ( tmp.compareTo( a[ child ] ) < 0 )
/* 6*/            a[ i ] = a[ child ];
            else
/* 7*/            break;
            }
/* 8*/      a[ i ] = tmp;
        } 
/*** Standard heapsort.
* @param a an array of Comparable items.
*/
        public static void heapsort( Comparable [ ] a )
        {
/* 1*/      for( int i = a.length / 2; i >= 0; i-- ) 	 /* buildHeap */
/* 2*/          percDown( a, i, a.length );
/* 3*/      for ( int i = a.length - 1; i > 0; i-- )
            {
/* 4*/          swapReferences( a, 0, i );            	/* deleteMax */
/* 5*/          percDown( a, 0, i );
            }
        }

รูปที่ 7.8 โปรแกรม heapsort

dsa/sheap.txt · Last modified: 2021/09/08 22:16 by wasu

Page Tools