520 likes | 764 Views
การเรียงลำดับข้อมูล (Sorting). Data Structure and Algorithm. Sorting. การจัดเรียงข้อมูลเป็นขั้นตอนหนึ่งที่สำคัญในการประมวลผลข้อมูล ข้อมูลที่จัดเรียงแล้วช่วยให้เราทำงานกับข้อมูลนั้นได้ง่ายขึ้นเช่น . การแสดงผล. การคำนวณ. ประโยชน์ด้านการแสดงผล. รายการโทรศัพท์. จัดเรียงตามวันที่.
E N D
การเรียงลำดับข้อมูล (Sorting) Data Structure and Algorithm
Sorting • การจัดเรียงข้อมูลเป็นขั้นตอนหนึ่งที่สำคัญในการประมวลผลข้อมูล • ข้อมูลที่จัดเรียงแล้วช่วยให้เราทำงานกับข้อมูลนั้นได้ง่ายขึ้นเช่น การแสดงผล การคำนวณ
ประโยชน์ด้านการแสดงผลประโยชน์ด้านการแสดงผล • รายการโทรศัพท์ จัดเรียงตามวันที่
ประโยชน์ด้านการค้นหาและแสดงผลประโยชน์ด้านการค้นหาและแสดงผล จัดเรียงตาม Sender, Subject, Date/Time
ประโยชน์ด้านการคำนวณ • การหาค่า Median (ค่าข้อมูล ณ. ตำแหน่งกลางของชุดข้อมูล) • 20 25 45 46 49 55 65 73 80 92 101 • การหาค่า Maximum • 20 25 45 46 49 55 65 73 80 92 101 • หากข้อมูลไม่ได้จัดเรียงต้องใช้เวลา O(N) เพื่อหาค่า Max • แต่เมื่อข้อมูลจัดเรียงเรียบร้อยแล้วใช้เวลา O(1)
Ascending VS. Descending Order • เราสามารถจัดเรียงข้อมูลได้ทุกประเภท int, float, boolean, character, string ฯลฯ • ข้อมูลที่จัดเรียงต้องมีKeyที่ใช้เป็นตัววัดลำดับข้อมูลเช่น จำนวน วันที่ ชื่อ เป็นต้น • การจัดเรียงจากน้อยไปหามาก (Ascending Order) • เช่นเรียงตัวเลข, วันที่ในรายการสมุดบัญชีธนาคาร • การจัดเรียงมากไปหาน้อย (Descending Order) • เช่น เรียง E-mail โดยเอาวันที่ล่าสุดขึ้นมาก่อน
Data Representation for Sorting • ข้อมูลที่ต้องการจัดเรียงนั้นมีอยู่หลายรูปแบบ เช่น ข้อมูลที่อยู่ใน Array, อยู่ในไฟล์, อยู่ในฐานข้อมูล • ในวิชานี้เราศึกษาถึงรูปแบบการเรียงลำดับข้อมูลใน Array เท่านั้น สมมติมีข้อมูล 1 ชุด จำนวน 6 ตัว ดังนี้ 44 33 11 85 77 60 ข้อมูลในอุดมคติ List 44 33 11 85 77 60 ข้อมูลใน Array ชื่อ List
ความหมาย • การจัดเรียงลำดับ (Sorting) หมายถึงการจัดเรียงข้อมูล ให้เรียงลำดับตามเงื่อนไขที่กำหนดไว้ (มากไปน้อย หรือ น้อยไปมาก) • ในกรณีที่ข้อมูลในแต่ละ Record มีหลาย Field เราต้องพิจารณาเลือก Field ที่สนใจเพื่อใช้ในการเรียงลำดับ เช่น การจัดเรียงลำดับประวัตินักศึกษา อาจใช้หมายเลขประจำตัวของนักศึกษาเป็น Field โดยเรียงจากน้อยไปมาก เป็นต้น
ประเภทของการเรียงลำดับข้อมูลประเภทของการเรียงลำดับข้อมูล • การจัดเรียงภายใน (Internal Sorting) • การจัดเรียงลำดับข้อมูลที่เก็บอยู่ในหน่วยความจำของเครื่องคอมพิวเตอร์ การจัดเรียงแบบนี้จะต้องอาศัยเทคนิคและวิธีการของโครงสร้างข้อมูลมาช่วย เช่น การใช้ Array หรือ Linked-List เข้ามาช่วย • การจัดเรียงภายนอก (External Sorting) • การจัดเรียงข้อมูลที่เก็บอยู่ในสื่อบันทึกข้อมูล เช่น Disk โดยทั่วไปการเรียงประเภทนี้ มักใช้กับข้อมูลที่มีจำนวนมาก ที่ไม่สามารถเก็บไว้ในหน่วยความจำได้หมด การเรียงในแบบนี้จะต้องแบ่งข้อมูลออกเป็นส่วนย่อย แล้วนำมาเรียงด้วยการจัดเรียงแบบภายในก่อน แล้วจึงนำแต่ละส่วนย่อยมารวมกัน
วิธีการจัดเรียงข้อมูลวิธีการจัดเรียงข้อมูล • การจัดเรียงแบบแลกเปลี่ยน (Exchange Sort) • การจัดเรียงแบบแทรก (Insertion Sort) • การจัดเรียงแบบเลือก (Selection Sort) • Merg Sort • Redix Sort • Heap Sort • Shell sort • Quick Sort
การจัดเรียงแบบแลกเปลี่ยน (Bubble Sort) • เป็นการจัดเรียงโดยการเปรียบเทียบค่า 2 ค่าที่ติดกัน • ทำต่อเนื่องกันไปเรื่อย ๆ และตัดสินใจว่าจะสลับตำแหน่งกันหรือไม่ เช่น ถ้าต้องการเรียงข้อมูลจากน้อยไปมาก ก็คือ • ข้อมูลที่มีค่าน้อย ต้องอยู่ในตำแหน่งหน้า • ข้อมูลที่มีค่ามาก จะอยู่ตำแหน่งหลัง • ข้อมูล 2 ตัวที่อยู่ติดกัน ถ้า • ถ้าข้อมูลตัวแรกมากกว่าตัวหลัง ก็จะต้องสลับตำแหน่งกัน • แต่ถ้าข้อมูลตัวแรกน้อยกว่าข้อมูลตัวหลัง ก็ไม่ต้องสลับตำแหน่ง • ทำเช่นนี้ซ้ำกันไปเรื่อย ๆ จนกว่าการเปรียบเทียบของข้อมูลตลอดทั้งชุดจะไม่ต้องมีการสลับตำแหน่งเลย
Bubble Sort • เป็นวิธีที่ง่ายเช่นกัน • แนวคิด คือค่าที่มากๆ จะต้องถูกนำไป (ลอยไป) ไว้ด้านท้าย • เหมือนลูกโป่งที่ขนาดใหญ่จะลอยได้เร็วและสูง • แนวคิด • เริ่มนำข้อมูลตัวแรกเทียบกับตัวที่ 2 ตัวไหนมากก็จะถูกสลับกัน ทำอย่างนี้ไปจนถึงตัวสุดท้าย เราจะได้ค่าที่มากที่สุด 1 ตัวไว้ด้านท้าย • แต่ละครั้งจะได้ค่ามากที่สุดไปไว้ท้ายสุด • จากนั้นเริ่มการเปรียบเทียบใหม่ตั้งแต่ตัวแรกถึงตัวที่ N-1 • จากนั้นเริ่มการเปรียบเทียบใหม่ตั้งแต่ตัวแรกถึงตัวที่ N-2 • … • จากนั้นเริ่มการเปรียบเทียบใหม่ตั้งแต่ตัวแรกถึงตัวที่ N-x • ทำจน x = N-1
ตัวอย่าง Function การจัดเรียงแบบ Bubble
ตัวอย่าง: Bubble Sort 44 55 12 42 94 18 06 67 ข้อมูล 8 ตัวทำ 7 รอบ รอบที่ ข้อมูล 1 06445512429418 67 2 06124455184294 67 3 0612184455426794 4 061218424455 6794 5 061218424455 6794 6 0612 184244556794 7 0612 1842445567 94
Program bublesort1; const n = 8; a:array[1..n] of integer = (44,55,12,42,94,18,06,67); VAR i,j,l,temp : integer; begin for i := 2 to n do begin for j := n downto i do if a[j-1] > a[j] then begin temp := a[j-1]; a[j-1] := a[j]; a[j] := temp; end; for l := 1 to n do write(a[l]:10); end; writeln;readln; end.
int main() { int A[ELEMENTS]={44,55,12,42,94,6,18,67}; int x; cout<<"NON SORTED LIST:"<<endl; for(x=0;x<ELEMENTS;x++) { cout<<A[x]<<endl; } exchange_sort(A,ELEMENTS); cout<<endl<<"SORTED LIST"<<endl; for(x=1;x<=ELEMENTS;x++) { cout<<A[x]<<endl; } return 0; } #include <iostream.h> #define ELEMENTS 8 void exchange_sort(int x[],int length) { int temp; for(int i=0;i<length;i++) { for (int j=length;j>i;j--) { if(x[j-1]>x[j]) { temp=x[j-1]; x[j-1]=x[j]; x[j]=temp; } } } }
การจัดเรียงแบบแทรก (Insertion Sort) • เป็นการจัดเรียงโดยการนำข้อมูลที่จะทำการเรียงนั้น ๆ ไปจัดเรียงทีละตัว • โดยการแทรกตัวที่จะเรียงไว้ในตำแหน่งที่เหมาะสมของข้อมูลที่มีการจัดเรียงเรียบร้อยแล้ว ณ ตำแหน่งที่ถูกต้อง • วิธีการลักษณะนี้จะคล้ายกับการหยิบไพ่ขึ้นมาเรียงทีละใบ ซึ่ง • ไพ่ใบแรกจะไม่ต้องสนใจอะไร • แต่เมื่อหยิบไพ่ใบที่ 2 ก็จะต้องพิจารณาว่าจะไว้ก่อนหรือไว้หลังใบแรก • และเช่นเดียวกัน เมื่อหยิบไพ่ใบถัด ๆ มา ก็จะต้องพิจารณาว่าจะวางใบตำแหน่งใดเพื่อให้เกิดการเรียงลำดับ จนกระทั่งหมด
ตัวอย่าง Function การเรียงแบบ Insertion
ตัวอย่าง: Insertion Sort 44 55 12 42 94 18 06 67 ข้อมูล 8 ตัวทำ 7 รอบ รอบที่ ข้อมูล 244551242 941806 67 312445542 941806 67 412424455941806 67 512424455 941806 67 61218424455940667 70612 184244559467 80612 1842445567 94
Program insertionsort; const n = 8; a:array[1..n] of integer = (44,55,12,42,94,18,06,67); VAR i,j,l,x : integer; begin for i := 2 to n do begin x := a[i]; j := i-1; while (x < a[j]) and (j > 0) do begin a[j+1] := a[j]; j := j - 1; end; a[j+1] := x; for l := 1 to n do write(a[l]:10); end; writeln;readln; end.
int main() { int A[ELEMENTS]={44,55,12,42,94,06,18,67}; int x; cout<<"NON SORTED LIST:"<<endl; for(x=0;x<ELEMENTS;x++) { cout<<A[x]<<endl; } insertion_sort(A,ELEMENTS); cout<<endl<<"SORTED LIST"<<endl; for(x=0;x<ELEMENTS;x++) { cout<<A[x]<<endl; } return 0; } #include <iostream.h> #define ELEMENTS 8 void insertion_sort(int x[],int length) { int key,i; for(int j=1;j<length;j++) { key=x[j]; i=j-1; while(x[i]>key && i>=0) { x[i+1]=x[i]; i--; } x[i+1]=key; } }
การจัดเรียงแบบเลือก (Selection Sort) • เป็นการจัดเรียงโดยการเริ่มต้นค้นหาข้อมูลตัวที่น้อยที่สุดจากข้อมูลที่มีอยู่ทั้งหมด • แล้วเอามาเก็บไว้ข้างนอก • แล้วกลับไปหาข้อมูลตัวที่น้อยที่สุดในกองต่อไปจนกว่าจะหมดกอง
ตัวอย่าง Function การเรียงแบบ Selection
ตัวอย่าง: Selection Sort 44 55 12 42 94 18 06 67 ข้อมูล 8 ตัวทำ 7 รอบ รอบที่ ข้อมูล 1 06551242 941844 67 2 06125542 941844 67 3 061218429455 44 67 4 06121842 9455 44 67 5 061218424455 9467 6 0612 184244559467 7 0612 1842445567 94
Program selectionsort; const n = 8; a:array[1..n] of integer = (44,55,12,42,94,18,06,67); VAR i,j,k,l,temp : integer; begin for i := 1 to n-1 do begin k := i; for j := i+1 to n do if a[k] >a[j] then k := j; temp := a[i]; a[i] := a[k]; a[k] := temp; for l := 1 to n do write(a[l]:10); end; writeln;readln; end.
int main() { int A[ELEMENTS]={44,55,12,42,94,6,18,67}; int x; cout<<"NON SORTED LIST:"<<endl; for(x=0;x<ELEMENTS;x++) { cout<<A[x]<<endl; } selection_sort(A,ELEMENTS); cout<<endl<<"SORTED LIST"<<endl; for(x=0;x< ELEMENTS;x++) { cout<<A[x]<<endl; } return 0; } #include <iostream.h> #define ELEMENTS 8 void selection_sort(int x[],int length) { int k,temp; for(int i=0;i<length;i++) { k=i; for (int j=i+1;j< length;j++) { if(x[j]< x[k]) k=j; } temp=x[i]; x[i]=x[k]; x[k]=temp; } }
Shellsort • Shellsort ตั้งตามชื่อของผู้คิดค้นการจัดเรียงแบบนี้ คือ Donald Shell และเป็นอัลกอริทึมแรกที่ทำลายขอบเขตเวลาที่เป็น quadratic • ในขณะทำงานแต่ละ phase นั้น shell sort ใช้การเปรียบเทียบค่าที่อยู่ในตำแหน่งที่ห่างกัน ระยะห่างดังกล่าวนี้จะลดลงลงเรื่อย ๆ จนกระทั่งถึงขั้นตอนสุดท้ายที่เป็นการเปรียบเทียบค่าที่อยู่ติดกัน • ด้วยเหตุที่ระยะห่างของค่าที่นำมาเปรียบเทียบกันลดลงในระหว่างการทำงานของอัลกอริทึมนี้เองจึงเรียกShellsort อีกอย่างว่าdiminishing increment sort
Shellsort ใช้การลำดับของh1, h2, . . . , ht ซึ่งเรียกว่าincrement sequenceและลำดับที่ใช้จะมีค่าลักษณะใดก็ได้เพียงแต่มีเงื่อนไขว่าh1 = 1 เท่านั้นแต่แน่นอนว่าบางลำดับจะทำงานได้ดีกว่าบางลำดับ (จะกล่าวถึงอีกครั้ง) • ในการทำงานแต่ phase ที่ใช้ลำดับการเพิ่มhkผลที่ได้ คือ สำหรับแต่ละค่า iเราจะได้ว่า a[i] a[i + hk] กล่าวคือสมาชืกทุกตัวที่มีระยะห่างกันhkจะอยู่ในลำดับที่มีกี่จัดเรียงอย่างถูกต้อง ซึ่งเรียกว่าhk-sortedfile
คุณสมบัติที่สำคัญของ Shellsort คือ การทำhk-sorted แล้วตามด้วยhk-1-sorted นั้นยังคงสภาพของhk-sorted Original 819411 96 12351795 28 58417515 -------------------------------------------------------------------------------------- After 5-sort 3517 11 2812 41 7515 96 5881 94 95 After 3-sort 28 12 11 35 15 41 58 17 94 75 81 96 95 After 1-sort 11 12 15 17 28 35 41 58 75 81 94 95 96 Figure Shellsort หลังการทำงานแต่ละ pass
Shellsort routine ใช้ลำดับการเพิ่มของ Shell public static void shellsort( Comparable [ ] a ) { int j; /* 1*/ for( int gap = a.length / 2; gap > 0; gap /= 2 ) /* 2*/ for( int i = gap; i < a.length; i++ ) { /* 3*/ Comparable tmp = a[ i ]; /* 4*/ for( j = i; j >= gap && tmp.compareTo( a[ j - gap ] ) < 0; j -= gap ) /* 5*/ a[ j ] = a[ j - gap ]; /* 6*/ a[ j ] = tmp; } }
Heapsort • ในการจัดเรียงด้วยเวลา O(N log N) อัลกอริทึมที่ใช้พื้นฐานแนวคิดนี้ เรียกว่าheapsortและมี Big-Oh running time ดีกว่าอัลกอริทึมอื่น ๆ ที่กล่าวมาแล้ว • วิธีการ คือ สร้าง binary heap (มีสมาชิกNตัว)ซึ่งใช้เวลา O(N) จากนั้นทำdeleteMin Nครั้งสมาชิกที่ถูกย้ายออกไปจาก heap ตัวแรก คือตัวที่มีค่าน้อยที่สุด และเรียงลำดับตามค่าไปแล้วนำไปเก็บใน Arrray อีกตัวหนึ่งจากนั้นก็คัดลอกกลับไปยัง Array เดิมซึ่งก็จะเป็นคำตอบในการจัดเรียงเนื่องจากการทำdeleteMinแต่ละตัวใช้ O(log N) ดังนั้น running time รวมทั้งหมด คือ O(N log N)
หลังการทำงานจนเสร็จ Array ที่ได้ก็จะเป็น Arrayของสมาชิกที่จัดเรียงจากมากไปน้อย • ถ้าต้องการจัดเรียงจากน้อยไปมาก เราก็จะใช้ heap ที่ parent มีค่ามากกว่า child ของมัน นั่นคือ (max)heap • เราจะใช้ (max)heap ในการ implement ของเราและยังคงใช้ Array เช่นเดิม • ขั้นแรกสร้าง heap ด้วย linear time จากนั้นทำdeleteMaxes จำนวน N - 1 ครั้ง ด้วยการสลับสมาชิกตัวสุดท้ายใน heap กับสมาชิกตัวแรก แล้วลดขนาดของ heap ลงแล้วทำการ percolating down • หลังจบอัลกอริทึมจะได้ Arrayที่มีสมาชิกเรียงตามลำดับค่า
Figure 7.6 (Max) heap หลังการ build_heap Figure 7.7 Heap หลัง deleteMax ครั้งแรก
Quick Sort หลักการดำเนินงาน * หาตำแหน่งในการแยกลิสต์ * แบ่งแยกข้อมูลออกเป็นสองส่วน และหาตำแหน่ง ในการแยกลิสต์ * ทำจนกว่าข้อมูลจะเรียงลำดับเรียบร้อย
first last Ex เริ่มต้นใช้ข้อมูลตัวแรกเป็นตัวเปรียบเทียบ (pivot) pivot ทำการเปรียบเทียบค่าของข้อมูลที่ชี้โดย first กับ Pivot ถ้าน้อยกว่า pivot ให้ทำการเลื่อน first ไปยังข้อมูลต่อไปและเปรียบเทียบไปจนกว่าจะพบ แล้วจึงหยุดการเปรียบเทียบ
first first last last เมื่อพบตำแหน่งแล้ว จะหันมาพิจารณาที่ last ชี้อยู่ หากค่าที่ last ชี้อยู่มีค่าน้อยกว่าที่ first ชี้อยู่ให้สลับตำแหน่ง
จากชุดข้อมูลหลังจากการสลับค่าจากชุดข้อมูลหลังจากการสลับค่า first last ทำการเปรียบเทียบค่าของข้อมูลที่ชี้โดย first กับ Pivot ถ้าน้อยกว่า pivot ให้ทำการเลื่อน first ไปยังข้อมูลต่อไปและเปรียบเทียบไปจนกว่าจะพบ แล้วจึงหยุดการเปรียบเทียบ
first first last last เมื่อพบตำแหน่งแล้ว จะหันมาพิจารณาที่ last ชี้อยู่ หากค่าที่ last ชี้อยู่มีค่าน้อยกว่าที่ first ชี้อยู่ให้สลับตำแหน่ง
ย้อนกระบวนการไปพิจารณา first และ last จะได้ first first last last สลับตำแหน่งข้อมูล
ย้อนกระบวนการไปพิจารณา first และ last จะได้ first last พบตำแหน่งที่จะใช้แบ่งชุดข้อมูลแล้ว จึงทำการแบ่งข้อมูล ออกเป็นสองชุด
ทำการแบ่งข้อมูลออกเป็นสองชุดทำการแบ่งข้อมูลออกเป็นสองชุด สลับค่าข้อมูลตัวแรกกับสุดท้ายของข้อมูลชุดซ้าย จะได้ว่า 15 และ 16 อยู่ในตำแหน่งที่ถูกต้อง(ตน.5และ ตน.6) เรียบร้อยแล้วไม่ต้องนำมาพิจารณาอีกดำเนินการกับข้อมูลที่เหลือเหมือนเดิมจนกว่าจะได้ข้อมูลในตำแหน่งต่างๆ จนครบ และดำเนินการแบบเดียวกับกับข้อมูลชุดขวามือ
first first last last ข้อมูลเริ่มต้นชุดซ้าย ข้อมูลเริ่มต้นชุดขวา pivot พิจารณาชุดข้อมูลด้านซ้ายมือก่อน
pivot pivot pivot first first first last last last • First มากกว่า pivot พิจารณา last เลื่อนมาด้านซ้ายจนพบ 7 ซึ่งน้อยกว่า 9 จึงหยุด ทำการสลับตำแหน่งข้อมูล • First มากกว่า pivot พิจารณา last เลื่อนมาด้านซ้ายจนมาชี้ที่ pivot พบว่าไม่มีข้อมูลใดต่อไปอีกทำการแบ่งข้อมูลออกเป็นสองชุดแสดงว่า pivot อยู่ในตำแหน่งที่ถูกต้องแล้ว (2 อยู่ ตน. 1) 2
last last pivot pivot first first เปรียบเทียบ first กับ pivot พบว่า first มากกว่า พิจารณา last พบว่ามากกว่า first จึงเลื่อนมาด้านซ้ายจนมาชี้ที่ pivot และไม่มีตัวอื่นอีกจะได้ตำแหน่งในการแยก list
ได้ว่า pivot (7) อยู่ในตำแหน่งที่ถูกต้องแล้ว first pivot last pivot last first สรุปตำแหน่งข้อมูลที่ทราบแล้วคือตำแหน่งที่ 1 ถึง 5 ได้แก่ 2 7 9 12 และ 15 ตามลำดับ ดำเนินการกับข้อมูลชุดด้านขวามือต่อ
Merge Sort กระบวนการแยกชุดข้อมูล
กระบวนการรวมชุดข้อมูลกระบวนการรวมชุดข้อมูล ได้ชุดข้อมูลที่เรียงลำดับเรียบร้อยแล้ว
Merge Sort Algorithm Analysis จำนวนครั้งของการเปรียบเทียบทั้งหมด = ผลบวกทุกระดับของ ( จำนวนลิสต์ในแต่ละระดับ * จำนวนครั้งของการเปรียบเทียบแต่ละลิสต์ ) = (N-1) *1 + (N/2 -1)*2 + (N/4 – 1)*4 +..+(2-1)*N/2 = ( N-1) + (N-2)+(N-4)+..+(N-N/2) = Nlog2N จะได้ bigO(Nlog2N)
วิธีการจัดเรียงข้อมูลวิธีการจัดเรียงข้อมูล • การจัดเรียงแบบแลกเปลี่ยน (Exchange Sort) • การจัดเรียงแบบแทรก (Insertion Sort) • การจัดเรียงแบบเลือก (Selection Sort) • Merg Sort • Redix Sort • Heap Sort • Shell sort • Quick Sort