คอรด หนึ่งซํ้า เดมิ อยใู นตําแหนงที่ 5 แตหลงั จากเรคอรด เรียงลาํ ดับแลว เรคอรดหมายเลข 14 ที่ 1 จะไป อยูห ลงั เรคอรดคีย หมายเลขที่ 5 ผลลพั ธคลาดเคล่อื นของตําแหนงเรคอรดทม่ี ีคียซา้ํ กันนี้เปน ผลมากจากการ ใชจดั เรียงลําดับทีไ่ มคงท่ี อน่ึง ในบางกรณีลักษณะคงท่ี (Stable) ไมจ ําเปนเพราะความสําคัญอะไร แตใ น บางกรณีลาํ ดับท่ีกอนหลงั ของเรคอรด ท่ีมคี ยี ซ าํ้ กันอาจเปนสําคญั และจาํ เปนจะตองเลือกใช วธิ กี ารจดั เรียงลาํ ดับทคี่ งท่ี ตวั อยางโปรแกรมการทํางานของ Selection Sort void selectionSort(int numbers[], int array_size) { int i, j; int min, temp; for (i = 0; i < array_size-1; i++) { min = i; for (j = i+1; j < array_size; j++) { if (numbers[j] < numbers[min]) min = j; } temp = numbers[i]; numbers[i] = numbers[min]; numbers[min] = temp; } } 7.2 การจดั เรียงลาํ ดบั แบบ Insertion sort เทคนคิ พื้นฐานในการจัดเรียงลําดับเรคอรด อีกวธิ หี น่ึง คือเทคนิคการแทรกเรคอรด ซึ่งใชว ธิ ีการอาน คา ขอมลู มาแลวแทรกจดั หาลําดับเรคอรด ตามตาํ แหนงทีเ่ หมาะสม วิธกี ารน้ีเปนเทคนิคที่ไดพัฒนาตอจาก เทคนิคแบบ Selection Sort คือแตละทีจ่ ะตองรอจนอานครบทกุ เรคอรดกอนจงึ จะเริม่ จัดเรียงลาํ ดับ (แบบ Selection) เราใชวธิ กี ารจดั เรยี งลาํ ดับไปเรอื่ ย ๆ ตามท่แี ตละเรคอรดถกู อา นเขามา (แบบ Insertion) หากจะ Data Structure & Algorithm 93 เปรยี บเทยี บกบั การเลนไพ เราหยับไพแตล ะใบเขามาแลว จดั เรียงไพไปเรื่อย ๆ เราใชเทคนคิ การแทรกไพ (เรยี งตามเลขมากนอยตามลําดบั ) แตถา เรารอจนแจกไพห มดแลวหยบิ เขามาในมือแลวจึงจดั เรยี ง เรากใ็ ช เทคนคิ การเลอื กเรียงไพ ตัวอยา งเชน เรามตี วั เลขทัง้ หมดทย่ี งั ไมไดเ รยี งลําดับอยดู ังนี้ 14 3 22 9 10 14 2 7 25 6 ในรอบแรกเราอา นคา เรคอรด ที่ 1 คือหมายเลข 14 ดงั น้ันผลลัพธในรายการทีจ่ ะจัดเรียงลาํ ดบั ก็คือ 14 3 22 9 10 14 2 7 25 6 14 Unsorted List Sorted List ในรอบท่ี 2 อา นเลข 3 เขา มา แลว นาํ ไปจัดเรยี งลาํ ดบั ใน Sorted List จะไดผลคอื 22 9 10 14 2 7 25 6 3 14 Unsorted List Sorted List หลังจากรอบท่ี 6 ผลลพั ธค ือ 2 7 25 6 3 9 10 14 22 Unsorted List Sorted List การดําเนนิ การสอดแทรกรายการจาก Unsorted List เขาไปใน Sorted List จะดาํ เนินการ ตอ ไปจนหมดเรคอรดใน Unsorted List อลั กอริทึมที่ 1 จะแสดงเทคนิคการจดั เรียงลาํ ดับเรคอรด แบบ Insertion Sort โดยจะเรยี งเรคอรด ท้งั หมดจํานวน n เรคอรด อนึง่ การจดั เรียงเรคอรด แบบน้ี จะไดผลลพั ธเ ปน แบบคงท่ี Insertion Sort void insort(record a[], int n) { int i,j; record memo; for(i=1; i<n; i++) Data Structure & Algorithm 94 { /* now a[0],a[1],...,a[i-1] is sorted */ memo=a[i]; for(j=i-1; j>=0; j--) { /* now a[0],a[1],...,a[j],a[j+2],...a[i] is sorted and a[j+1] may be overwritten */ if(cmp(&a[j], &memo)>0) a[j+1]=a[j]; /* now a[0],a[1],...,a[j-1],a[j+1],...a[i] is sorted and a[j] may be overwritten */ else break; } /* now a[0],a[1],...,a[j],a[j+2],...a[i] is sorted and a[j+1] may be overwritten */ a[j+1]=memo; /* now a[0],a[1],...,a[i] is sorted */ } } 7.3 การเรียงแบบ Bubble sort ตัวอยา งการเปรยี บเทยี บอยา งงายของชุดขอมลู 10 เรคอรด (เรคอรดละ 1 ตัวเลข) ท่ียงั ไมได เรียงลาํ ดับ ดังน้ี 512889 รูปท่ี 7.1 การเรียงแบบ bubble sort ชนั้ แรกใหน าํ เอา 5 เปรยี บเทยี บกับ 1 ปรากฏวา 5 และ 1 เรียงลําดบั ตามท่ีเราตองการอยแู ลว จากนนั้ ใหน ําเอา 1 เปรยี บเทียบกับตวั ถัดไปคือ 2 เนื่องจาก 2 มากกวา 1 และ 2 อยู ในตาํ แหนงท่ผี ดิ ลาํ ดับ จงึ ใหแ ลกที่กบั 1 หลงั จากท่ี 2 ไปอยใู นตําแหนงที่อยเู ดมิ ของ 1 (นัน่ คือ ตาํ แหนง ท่ี 2) แลว ก็ให 2 เปรียบเทยี บกับคาในตาํ แหนงที่ 1 คือ 5 ปรากฏอยูในลําดบั ทถี่ กู ตอ งกไ็ มต องแลกทกี่ นั ตอมานํา 1 ไป Data Structure & Algorithm 95 เปรียบเทียบกบั 8 แลวทาํ ในลกั ษณะเดมิ คา 8 จะคอยๆ ลอย ข้นึ ไปอยูในตาํ แหนงทีถ่ ูกตอ ง ในทสี่ ุดก็นาํ 1 ไปเปรยี บเทียบกบั 9 เลข 9 จะคอย ๆ ลอยข้ึน ไปยงั ตําแหนง ท่ถี กู ตอ ง วิธีการแบบ Bubble Sort และวธิ ีการ Sort แบบอนื่ ๆ ท่ีไดกลา วมาแลวทั้งหมดเปนวธิ กี ารที่งา ยตอ การเขยี นโปรแกรม แตการดําเนินการจะชกั ชาเสยี เวลามากเพราะตองไลเ ปรยี บเทยี บไปทีละคู โดยปกตแิ ลว มกั จะไมเ ปนท่นี ิยมใช เทคนิคการจัดเรยี งลําดบั แบบอนื่ ๆ ท่ีจะไดกลาวตอไปจะเปน เทคนิคทที่ าํ งานไดเร็วกวา และมปี ระสทิ ธิภาพกวามาก ตัวอยางโปรแกรมในการเรียงขอ มลู แบบ Bubble Sort void BubbleSort() { int A[n], x, y; for(x = 0; x < n; x++) for(y = 0; y < n-1; y++) if(A[y] > A[y+1]){ swap(A[y], A[y+1]); } } 7.4 การจัดเรียงลาํ ดบั แบบ Quick Sort วิธีการที่ทํางานไดผลอยา งมีประสทิ ธภิ าพมากกวา Exchange Sort คือวิธีการแบบ Partition- exchange Sort หรือท่ีเรียกวา Quick Sort วิธกี ารนีไ้ ดร บั การพัฒนาโดย C.A.R. Hoare ในป 1962 แนวความคิดพ้นื ฐานของการจัดเรยี งลําดบั แบบนี้ คอื ใชผ ลของการเปรียบเทยี บในรอบหนึ่งเปน ตัวกาํ หนดเง่ือนไขในการเปรียบเทยี บครั้งตอไปตามลาํ ดบั ในกระบวนการเปรยี บเทยี บจะทําใหเกดิ ผลลพั ธ แบงแยกเปน 2 สว น (partition) โดยยา ยคาของชุดขอมลู ทาํ ใหดานหน่ึงจะมคี าของชุดขอมลู ท่ีมคี าสูงกวา คา ของคยี ที่กําหนดในขณะท่อี ีกดานหนึ่งมคี าตํ่ากวา ลองพจิ ารณาตวั อยา งของชดุ ขอมลู ทีย่ ังไมไ ดจดั เรียงลาํ ดบั ดงั นี้ 6 25 7 2 14 10 9 2 3 14 จุดมุง หมายของการเปรยี บเทียบจะแบงแยกคา ของขอมูลออกเปน 2 ดาน คา ท่สี ูงกวาใหด า นลาง และต่ํากวาไวดา นบนของรายการ เรมิ่ ตนดวยการเปรียบเทียบเลข 6 กับ 14 ผลลพั ธคือ ไมต องแลกคา เพราะ 6 (คาตา่ํ ) อยดู า นบน และ 14 (คาสูงอยูดา นลา งอยแู ลว การเปรียบเทียบถดั ไปจะเปน การ Data Structure & Algorithm 96 เปรยี บเทียบ 6 กับ 3 ผลลพั ธคอื เอา 3 ยายไปดา นบน เลข 6 ยายไปดา นลา ง ถดั ไปเปรยี บเทียบ 25 กับ จะไดวาเลข 6 ถูกยายขึ้นบน 25 ถกู ยา ยลงลาง ตอ มา 6 จะถูกเปรยี บเทียบกับ 22 , 9, 10, 14 ตามลําดับ ผลลัพธค ือทกุ ตวั คงอยูต าํ แหนงเดิมจนถึง 6 กบั จะไดว า 2 ถกู ยา ยขน้ึ บน 6 ลงลาง การเปรียบเทยี บคร้ัง สดุ ทาย คือ กับ 6 จึงเกดิ ผลลัพธสลับคา ยา ยตาํ แหนง กัน ตรงจดุ นถี้ ือวาเปนการส้ินการยาย คา ในรอบแรกทั้งหมด สรปุ ไดผลลพั ธเ ปน คร่ึงบนเลขต้ังตนในรอบน้ี ( เลข 6 ) มีคาคือ 3, 2, 6 สว น ครึง่ ลางมี 7 คา คือ 7, 14, 10, 9, 22, 25, 14 333 25 3 25 25 7 2 77 7 14 10 22 2 9 22 14 14 14 3 14 10 10 10 99 9 22 22 22 25 14 14 14 รปู ที่ 7.2 การจัดเรยี งลาํ ดบั เรคอรด แบบ Quick Sort เมอ่ื จบรอบแลว จะเร่มิ ตนทาํ การเปรยี บเทียบสลบั คาไปมาโดยใชตรรกแบบเดิมของสวนคร่ึงบน และ สวนครง่ึ ลา งไปเรอ่ื ย ๆ ตามลําดบั เชน สว นคร่งึ ลางจะเรมิ่ ตนดว ยเลขต้ังตนท่ีเลข 7 แลวจะสลบั คายา ยไปมา ใหเลขท่ีต่ํากวา 7 ไวดานหนา สูงกวา 7 ไวอกี ดา นหน่ึง และจําทาํ การเปรยี บเทยี บเชนนี้ในสวนครึง่ บนและ ครงึ่ ลา งของเลข 7 อีกตอ ๆ ไป น้ันคอื เราจะแบงสวนของขอมลู ออกเปน สวนยอยๆ บนลางไปตามลําดบั จน ทุกคา ไดร บั การจดั เรยี งเรียบรอยแลว อน่ึง เมื่อสว นยอย ๆ มีขนาดเลก็ ลง ผเู ขียนโปรแกรมอาจจะเลอื กใช วธิ กี ารจดั เรียงลาํ ดบั วธิ อี ื่นๆ ที่งา ยกวา เขามาใชร ว มกบั วธิ ี Quick Sort ได นอกจากนยี้ งั มีเทคนิคการแบงสวนชุดขอ มลู เปน ดา นคาสูงและคาตํา่ อีกวิธีการหน่ึง ซง่ึ จะเลยี นแบบ วิธกี ารที่คนทั่วไปใชในการจดั เรยี งลําดบั ขอ มูล คอื การแบงชุดขอมลู ออกเปน “กอง (piles)” และจะแบงเปน กองยอยๆ ตอไปตามลําดับ ในการแบง กองของขอมูลดวยเทคนคิ ของ Quick Sort แบบนี้ จะเริ่มตนดว ย การคํานวณหาจดุ กงึ่ กลางของขอมลู (mid – point) แลวจะจดั เอาขอมลู ที่มีคาตาํ่ กวา จุดก่งึ กลางไวทด่ี า นหนึง่ ของชดุ ขอมลู และที่มีคา สูงกวาไวใ นอีกดา นหน่งึ และจะหาจดุ กึ่งกลางของขอมลู แตล ะดา นจดั แบงเปน กลุม ยอ ยๆ ทําวนเวียนไปจนทุกขอมูลอยใู นลําดับท่ตี อ งการ ลองพิจารณาตัวอยา งชุดขอ มูล 10 เรคอรด (ตวั เลข) ซ่งึ ยังไมไดเ รยี งลาํ ดับตอไปน้ี Data Structure & Algorithm 97 86 3 10 23 12 67 59 47 31 24 ในรอบแรก จุดกึง่ กลางของคาขอ มูลคือ 55 (ไดจาก (86+24)/2) หลังจากนั้นขอมูลทีม่ ีคาตํ่ากวา 55 จะถูกยายไปดา นหนึ่ง ( 24-47 ) และที่มากกวา 55 จะอยใู นอีกดานหน่งึ (59-86) ในรอบท่ี 2 จดุ กึ่งกลาง ขอ มูลของคร่ึงแรกจะมีคาเทากับ 35 (ไดจ าก(24+47)/2) และจะแบงสลบั ขอ มลู ยอ ยได 2 ดาน ดานตาํ่ กวา 35 คอื 24-31 และดานสงู กวาคอื 47 ) และจะใชตรรกเดิมเชน นีว้ นเวียนรวม 10 รอบจนไดผ ลลัพธสดุ ทาย เปนทกุ เรคอรด ถูกจัดวางในตําแหนงทค่ี วรจะเปนจุดกง่ึ กลาง ตาํ แหนงในอารเรยของขอมลู รอบท่ี 1 2 3 4 5 6 7 8 9 10 1 55 86 3 10 23 12 67 59 47 31 24 2 35 24 3 10 23 12 31 47 59 67 86 3 27 24 3 10 23 12 31 47 59 67 86 4 18 24 3 10 23 12 31 47 59 67 86 5 11 12 3 10 23 24 31 47 59 67 86 6 6 10 3 12 23 24 31 47 59 67 86 7 23 3 10 12 23 24 31 47 59 67 86 8 72 3 10 12 23 24 31 47 59 67 86 9 63 3 10 12 23 24 31 47 59 67 86 10 3 10 12 23 24 31 47 59 67 86 รปู ท่ี 7.3 การจัดเรียงลาํ ดบั เรคอรดแบบ Quick Sort (midpoint) 7.5 การจัดเรียงลาํ ดับแบบ Heap Sort วิธกี ารแบบ Quick Sort จะทาํ งานไดดีกวาเทคนิคการจดั เรยี งแบบเชงิ เสนตรง สวนเทคนิค Heap sort ตอ ไปนี้เปนวิธกี ารแบบไมเ สน ตรง และเทคนิคนจ้ี ะทํางานไดพอ ๆ กับ Quick Sort และอาจจะดีกวา ในหลายกรณีที่ขอมูลมคี วามซับซอนมาก ๆ แตอยา งไรกต็ าม การเขียนโปรแกรม Heap Sort กย็ งุ ยากกวา วิธี อ่นื ๆ ทีไ่ ดกลาวมาแลว เทคนิคของ Heap Sort นถ้ี กู พัฒนาในป 1964 โดย J.W.Williams Data Structure & Algorithm 98 ในการดําเนนิ การของ Heap Sort เราจะกําหนดใชโครงสรางขอมูลแบบพิเศษของ Binary Trees ท่ี เรียกวาเปนโครงสรางแบบ Heap ซงึ่ จะมโี ครงสรา งเปนแบบตน ไม แตกเปน ก่ิงกานและใบไปตามลาํ ดบั ชน้ั ใน Heap ขนาด n ของ Binary Trees จะมีกิง่ กานและใบเปนจาํ นวน n โหนดการแตกก่งิ กานของโหนดจะอยู ภายใตเ ง่ือนไขตอไปน้ี 1. ทีท่ ุกระดบั ของ Heap จะแตกสาขาออกไปได 2 ทาง คือทางซายและทางขวา และจะตองมีโหนด ในระดบั บนครบ 2 ดานกอน จงึ จะแตกโหนดตอในระดบั ลางได อนงึ่ การแตกโหนดออกไปจะตองเร่มิ ทางดาน ซา ยกอ น จึงจะแตกไปดา นขวาตามลาํ ดบั 2. คาคยี ข องโหนดจะตองถูกจัดในลักษณะทว่ี าโหนดตวั บน (father-ตัวพอ จะตองมีคาคียส ูงกวา ของ โหนดลา ง (son-ตวั ลูก) 90 70 45 35 60 50 39 22 33 30 35 75 30 40 20 (ก) โครงสรา ง Heap (ข) ไมใชโ ครงสราง Heap รปู ท่ี 7.4 การเปรยี บเทียบระหวางโครงสราง Heap กับโครงสรางอนื่ ในกระบวนการดําเนนิ การของ Heap Sort จะแบง ออกไดเ ปน 2 ลาํ ดบั ขน้ั ตอน คือ 1. การสรา ง Heap 2. การประมวลผลของขอ มลู ใน Heap ขน้ั ตอนการสราง Heap : ในขั้นตอนแรกของ Heap Sort เราจะตอ งจดั ชุดขอมูลที่มีอยูใหมี ลักษณะโครงสรา งเปนแบบ Heap ขนาดของ Heap จะใหญข ้นึ เร่ือย ๆ เม่ือเราอา นขอ มูลแตละตัว (key) เขามาตามลําดบั การจัดเรียงลําดบั ของคียของโหนดตางๆ จะตอ งเปน ไปตามเงื่อนไข 2 ประการท่ีไดกลา ว มาแลว ตรรกทีใ่ ชในการจัดการคอื เมื่ออา นคา คยี เ ขา มาแตล ะตัว คาของคูคยี จะถูกเปรยี บเทียบกัน ถา คยี ม ีคาสูง กวา จะถูกสลับคาไปเปนตวั พอ และอีกตัวหนึ่งที่คาตา่ํ กวาจะถกู ยายมาเปนตัวลกู คา ของแตล ะคียใน Data Structure & Algorithm 99 กงิ่ กานสาขาตางๆ ของ Heap ที่ขนาด I (I เปน ขนาดของ Heap มีคาตง้ั แต Heap ขนาด 1 ถึงขนาด n โหนด ) ข้ันที่ 1 : ใหเ ปรียบเทียบโหนดท่เี ขา ใหมก บั โหนดทเ่ี ปนพอ IF Knew > KFATHER THEN แลกท่ีกนั เล่ือน I ไปชย้ี งั ตําแหนง FATHER (น่ันคือ I ตดิ ตาม Knew ขนึ้ ไป ) ขัน้ ท่ี 2 : ทําขน้ั ท่ี 1 เรื่อย ๆ จนทาํ ไมได ผลลพั ธท ไี่ ดใ นข้ันตอนแรกของการสราง Heap ยงั ไมไดถ ูกจัดเรยี งลําดบั ตามความตองการเปนแตจดั โครงสรางของตน ไมขึ้นมาเทานัน้ ในขนั้ ตอนท่ี 2 นีจ้ ะเปนการปรับโครงสรางท่ีไดใหม โี ครงสรา งที่เปนการจัด เรียงลาํ ดบั ขอ มลู โดยท่ีจะทํายอนกลับการสรา ง Heap โดยทําจาก Heap ขนาด 10 ยอนกลบั ไปยัง Heap ขนาด 1 โดยอาศยั แนวความคิดทีว่ า ขอมูลใน Heap ยังคงจัดใหมีลักษณะโครงสรางแบบอารเรยไ ดดังนน้ั เรา จะยา ยโครงสรา งกลบั คือเปลี่ยนแลกตาํ แหนง จากโหนดบนคยี [1] ใหก ลายเปนโหนดลา งสุด คอื คีย [n] แลวปรับโครงสรางของ Heap ท่ีเรยี งตามลําดบั จนกลายเปน วาคีย [1] คอื คาตํา่ สุด และคยี [n] คือ คาสูงสดุ void perc_down(input_type a[], int i, int n) { int child; input_type tmp; for (tmp=a[i]; i*2 <= n; i=child) { child = i*2; if ((child != n) && (a[child+1] > a[child])) child++; if (tmp < a[child]) a[i] = a[child]; else break; } a[i] = tmp; } void heapsort(input_type a[], int n) { int i, j; Data Structure & Algorithm 100 j = n; for (i=n/2; i>0; i--) /* BuildHeap */ perc_down(a,i,j); i = 1; for (j=n; j>=2; j--) { swap(&a[i],&a[j]); /* DeleteMax */ perc_down(a,i,j-1); } } 7.6 การจดั เรยี งขอ มลู แบบ Tournament Sort การจัดเรยี งลาํ ดับขอมลู โดยใชหลักการของตน ไมอีกเทคนคิ หนง่ึ คอื Tournament Sort หรือบางที เรียกวา Tree – selection Sort เทคนิคนี้ไดร ับการพัฒนาโดย E.H.iend (1956) วธิ ีการของเทคนิคนเี้ ปน ลักษณะคลายการจดั สายการแขง ขันกฬี าแบบแพค ัดออกไปตามลําดบั โดยจะทําการเปรยี บเทียบคแู ขง ขันทีละ คจู นกระทงั่ ไดผูชนะในขนั้ สดุ ทา ย วิธีการจดั เรียงลําดับแบบ Tournament ดูจะเปนวิธกี ารทม่ี ผี ูนิยมใชมากกวาเทคนคิ การจัด เรยี งลาํ ดบั แบบ Internal อน่ื ๆ ท้ังหมด โปรแกรมสําเรจ็ รูปท่สี รางขนึ้ ใชใ นการจดั เรยี งลําดบั ขอมลู ก็มักจะ ประยุกตใ ชเ ทคนคิ น้ีกันเปนหลกั ลองพิจารณาตัวอยา งของชุดขอ มูลทยี่ ังไมไดจดั เรยี งลาํ ดับ 15 คียต อ ไปนี้ 6 25 7 2 14 10 9 22 3 14 8 12 1 30 13 เพ่ือแสดงเปนตวั อยาง สมมติวา สามารถอา นคา เขาเก็บไวใ นหนว ยความจาํ เพียงครั้งละ 4 คา ดงั นัน้ การจดั การเปรียบเทยี บจะเร่ิมตนดว ยการสรางเปน คเู ปรยี บแบบ 2 คู คอื 6 กับ 25 และ 7 กบั 2 ในคูแรกผู ชนะคอื เลข 6 (เพราะมีคาตาํ่ กวา ) และในคูห ลักคือเลข 2 ดงั นั้นเมอื่ ผชู นะ 2 ทมี จาก 4 ทมี มาพบกัน จะได ผลลัพธรอบแรกวาเลข 2 คือผูชนะเลศิ ในรอบท่ี 1 น้ี แตการแขง ขนั ยังไมจบและไมไ ดม ผี ูเขามาแขงขนั เพยี งแค 4 ทีม ยังมีผเู ขา แขงขนั อ่ืนๆ อกี อยูอีกตามลาํ ดบั และจะใชนโยบายแบบคดั ออกไป แลวทดแทนเขา มา (Tree replacement-selection sort) ดงั นัน้ ในรอบถดั ไปเราจะอานเลขถัดไปคือเลข 14 เขามาแทนท่ีเลข 2 ทช่ี นะ ออกไปและเร่มิ ทาํ การเปรยี บเทยี บคแู ขง 4 ทมี ใหม วนเวยี นเชน น้ีไปตามลําดับ เมอ่ื ถึงรอบท่ี 6 จะเกดิ มปี ญ หาข้นึ เพราะเลขท่ีอานเขามาแทนทเี่ ลขที่คดั ออกคือเลข 3 หากเอาเลข 3 เขารวมแขงขัน เลข 3 ก็จะเปนผูชนะเพราะมีคา ต่ํากวาเลขอ่ืนแตก จ็ ะทําใหลําดบั ที่ของผูเขา รอบชนะทผ่ี า น ๆ มาเสียไปหมด ดงั น้ัน ในการจัดการแขงขันเปรยี บเทยี บคาจึงมีขอกาํ หนดเอาไววา “ถาคยี เขา มาใหม < คียท ี่ เพิ่งออกไปใหกาํ หนดคยี ทเี่ ขามาใหมเ ปนคียท่ีขาดคณุ สมบตั ิที่จะลงแขง ขันชั่วคราว” (ในที่นีจ้ ะใส * เอาไว) Data Structure & Algorithm 101 เลข 3 ไมไดล งแขง ขันดวย เลขอนื่ ๆ ก็จะเลน แขงขันเปรยี บเทียบกนั ตอไปตามปกติ รอบที่ 6 ถึง 9 จะอา นคา ใหมเขามาไลค าเกา ออกไปได และตดิ เงื่อนไขดงั กลาวไวทลี ะรอบตามลําดับ ถึงรอบท่ี 10 ทุกคา (ทัง้ 4 คียทจี่ ะเปรยี บเทยี บ) ที่อา นเขามาจะตดิ เง่ือนไขหมดแลว จงึ ยกเลกิ เงื่อนไขดงั กลาวแลว เรมิ่ เปรียบเทียบใหมส รางเปน ชุดขอมลู เรยี งลาํ ดบั ชดุ ท่ี 2 ดงั นน้ั ในรอบที่ 10 จะเริ่มคู เปรยี บเทยี บคา ทเ่ี หลอื ใหมไปตามลาํ ดับ จนถึงรอบเริม่ จะหมดชุดขอมลู (ในทนี่ ้ใี สเปน เครือ่ งหมาย * ) และใน รอบที่ 14-15 เปน การเปรยี บเทียบตัวเลขทเ่ี หลือจนหมดชุดขอ มูลทงั้ หมดในรายการ ผลลพั ธสุดทาย คอื ตวั เลข ทถ่ี กู เรียงลาํ ดับแลว 2 ชุด 6 66 66 2=>2 25 25 25 7 7 2 72 2 2 2 (1) 2,6 66 6 => 2,6 66 25 25 6 = > 77 77 * 14 (2) รูปท่ี 7.5 การจดั เรยี งลําดับขอมูลแบบ Tournament Sort เพอ่ื ใหไ ดผลลัพธเ ปนรายการชดุ ขอมลู ที่จัดเรียงลําดบั 1 ชุดขอมูล จะใชเทคนิคการเชื่อมชุดขอมูล 2 ชุด เขาดว ยกนั ดว ยวิธี Two-way Merge กลาวคือผา นคา ขอมลู แตละตัวจากแตล ะรายการมาเปรียบเทียบ กัน ตัวใดมคี า นอยกวา เขียนเก็บไวใ นชดุ ผลลัพธสุดทา ย (Merged list) แลว อา นคา ใหมจ ากรายการเดิมมา เปรยี บเทียบตอ ๆ ไปตามลาํ ดับ ในกรณีตัวอยางขางตน เปน ขัน้ ตอนการทํา Tournament Sort อยา งงายๆ มขี อมูลไมมากนัก และ เปรียบเทียบทีละ 2 คเู ปรียบเทียบ แตเ ราสามารถเขยี นโปรแกรมซับซอนข้ึน เปรยี บเทียบทีละหลายคูการ เปรยี บเทยี บก็ได Data Structure & Algorithm 102 7.7 การเรียงขอมูลแบบ Merge Sort Merge sort เปนวิธกี ารเรยี งขอ มูลที่มีความสําคัญมาก เพราะเปน วธิ สี าํ คัญในการเรยี งขอมลู ขนาด ใหญ (การเรียงแบบภายนอก) วธิ ีการเรียงจะเรม่ิ กระทําครงั้ ละ 2 คา ซ่งึ จะไดล สิ ตยอยจาํ นวน n/2 ลสิ ต แตล ะ ลิสตมี 2 คา จากน้นั จะทาํ การ merge sort ตออีกครงั้ ละ 2 ลิสต แลวจะไดล ิสตท่เี รียงแลว จํานวน n/4 ลิสต แตละลิสตมี 4 คา ทาํ เชน นี้ไปเรอื่ ยๆ จนในที่สุดจะทาํ การ merge sort 2 ลสิ ต สุดทายเขา ดว ยกัน จะไดล สิ ต ท่ีเรียงแลว ดังรปู 54 28 89 6 (4,5) (2,8) (8,9) (2, 4, 5, 8) (6, 8, 9) (2, 4, 5, 6, 8, 8, 9) รปู ท่ี 7.6 การ Merge Sort จะเหน็ ไดว า การทาํ Merge Sort ตองกระทาํ เปนจํานวน O (log2 n) เที่ยว และแตล ะเท่ียวทีท่ าํ การ Merge สามารถกระทําไดใน O (n) ดังน้นั เวลาในการเรียงขอมูลจะเปน O (n log2 n) ตัวอยา งโปรแกรมของการเรยี งแบบ Merge Sort void mergeSort(int numbers[], int temp[], int array_size) { m_sort(numbers, temp, 0, array_size - 1); } void m_sort(int numbers[], int temp[], int left, int right) { int mid; if (right > left) Data Structure & Algorithm 103 { mid = (right + left) / 2; m_sort(numbers, temp, left, mid); m_sort(numbers, temp, mid+1, right); merge(numbers, temp, left, mid+1, right); } } 7.8 การเรียงขอ มูลแบบ Shell Sort โดยปกตกิ ารเรยี งขอ มลู แบบน้ีท่ีใชก ารเปรียบเทยี บประมาณ n log2 n จะตองมีกระบวนการและ ข้นั ตอนท่ีพสิ ดารกวาการเรยี งขอมลู แบบท่ีใชก ารเปรียบเทยี บประมาณ n2 คร้งั แตถ า จาํ นวนขอมลู ทต่ี องเรียง มจี าํ นวนนอ ย หรือเกือบจะเรียงกนั อยูแลว การทาํ งานของแบบการคํานวณแบบ n2 นนั้ จะทํางานไดดีกวา การ เรยี งแบบ n log2 n การเรียงท่จี ะกลาวตอไปนี้ จะใชแ นวความคดิ จากเร่ืองนี้ น่ันคือแทนที่จะเรียงขอมลู ทง้ั ชดุ โดยตรง เราจะแบง ขอมลู ท้ังชุดหรอื คียท ่ีแทนขอมูลเหลา นี้ออกเปน สว นยอ ยๆ แลว เรยี งสว นยอย ๆ เหลา นั้น โดยใชอัลกอรทิ ึม n2 เชน Bubble Sort หรือ Insertion Sort จากชุดคียที่กาํ หนดใหเ ราจะไมแ บงคยี ช ดุ นน้ั ออกเปน ลิสตย อยจริงๆ แตจะทาํ การแบงโดยกาํ หนดคาที่ จะอยใู นลิสตย อยหนึ่ง ๆ ดวยการกาํ หนดคา h เปน ระยะทางระหวางคา สองคาใด ๆ ในคียชุดนน้ั ทจี่ ะอยูใน ลิสตยอ ย อนง่ึ แตละลสิ ตย อยจะมคี ีย อยูประมาณ n/h คา จํานวนคยี ใ นลิสตยอ ยในแตละเทย่ี วที่ทําการเรยี ง จะไมเ ทากนั แตจ ะถกู กาํ หนดโดยคา h ตอ ไปนี้ ht, ht-1,…….., h1 โดยท่ีคา h1 = 1 เสมอ การเรยี งจะ ส้นิ สุดเม่อื ทําการเรยี งเปนจํานวน t เทยี่ ว การเลอื กคา hi วธิ ีการเลอื กคา hi มอี ยหู ลายแบบ สวนแบบทจี่ ะกลา วถึงในทีน่ ้ีมี 2 รปู แบบ คอื (1) ใหเลือก hi = 2i – 1 โดยทคี่ า I อยูร ะหวา งคา 1 และ (log2 n) ถา เลอื ก hi โดยวิธีน้ี จาํ นวนครงั้ ที่ตองมีการเปรียบเทียบคีย จะเปน O (n3/2) ซงึ่ เปน กรณเี ลวรา ย ทส่ี ุด (2) ชดุ คา hi ทใี ชไดด ีอีกแบบหน่ึงกาํ หนดโดยสมการ สาํ หรับคา I อยูระหวา ง 1 และ t โดยท่ี t เปนคาจาํ นวนเต็มนอ ยทส่ี ุดท่ีสอดคลอ งกบั อสมการ ht+2 n สมมติใหชดุ คยี ท่จี ะเรยี งมีดงั นี้ (37, 32, 14, 45, 92, 18, 19, 34, 31, 35,) เราจะเลอื กคา hi จากแบบ (1) ท่กี ลา วมาแลว เน่ืองจาก n = 10 เราจะไดว า (log2 10) = 3 ดงั น้ันคา I ทีใ่ ชค ือ 3, 2 และ 1 และจะได h3 = 7, h2 = 3, h1 = 1 ตามลาํ ดบั จากสมการ hi = 2i – 1 Data Structure & Algorithm 104 การเรียงเทย่ี วท่ี 1 h3 = 7 37 32 14 45 92 18 19 34 31 35 การเรยี งเทย่ี วที่ 1 จะมี 3 ลสิ ตยอย ดงั ที่แสดงโดยเสน ทโี ยงไว 3 ลสิ ตยอยนี้คอื (37, 34) (32, 31) (14, 35) หลังจากการเรยี งแตละลสิ ตยอยแลวจะไดชุดตัวเลขดังนี้ การเรียงเทีย่ วท่ี 2 h2 = 3 37 32 35 34 31 14 45 92 18 19 การเรยี งเทย่ี วนจ้ี ะประกอบดวย 3 ลิสต คอื (34, 45, 19, 35) (31, 92, 37) และ (14, 18,
19 31 14 34 37 18 35 92 32 45 การเรียงเที่ยวท่ี 3 h1 = 1 การเรยี งเท่ียวนี้จะประกอบดวยลสิ ตเพยี งลิสตเดยี ว นั่นคอื ทกุ คา ในลสิ ตน ้ี การเรียงเทากับการใช insertion sort หรอื การเรียงแบบอื่น ๆ 19 31 14 34 37 18 35 92 32 45 เมอ่ื เรยี งแลวจะได Data Structure & Algorithm 105 14 18 19 31 32 34 35 37 45 92 สังเกตดูขอมูลจากการเรยี งโดยวิธี Shell น้ี การเลือกคา hi อกี แบบทีม่ ีประโยชน (และงา ย) กค็ ือ ให hi = 1 แลว ให hi + 1 = 3hi + 1 และใหห ยดุ ที่ ht เมอ่ื ht + 2 มีคา มากกวา n Data Structure & Algorithm 106 แบบฝก หัด 1. จงแสดงขัน้ ตอนในการเรยี งขอมลู สําหรับแตล ะวิธี โดยใชข อมูลที่กําหนดใหต อไปนี้ (1) Bubble Sort (มากไปหานอย) 634859827 (2) Insertion Sort (นอยไปหามาก) 634859827 (3) Heap Sort (นอยไปหามาก) 22 12 24 76 82 35 21 74 32 18 (4) Radix Sort (นอ ยไปหามาก) 3475 3476 3567 7476 7235 1346 7645 3674 7636 1345 5675 2456 2. จงบอกขอ ดี ขอเสียของการเรยี งลําดบั ขอมูลแตละประเภทตอไปน้ี (1) Bubble Sort (2) Selection Sort (3) Insertion Sort (4) Quick Sort (5) Shell Sort (6) Heap Sort (7) Radix Sort (8) Merge Sort Data Structure & Algorithm 116 บทท่ี 8 การคนหาขอมลู (Searchintg) 8.1 บทบาทหนา ทีข่ องการคนหาขอ มูล การคนหาขอ มลู (Searching) เปนกระบวนการท่สี าํ คัญย่ิง ขอ มูลท่ีเก็บอยูในคอมพวิ เตอร หลังจากผา นการประมวลผลหรือรวมเปน หมวดหมหู รอื แปลงเปนรูปแบบท่ตี องการแลว ยอมตองการนํา ขอ มลู เหลาน้ันออกมาใช นน่ั คือ การคน หาขอมลู (Searching) นงั่ เอง ขอมูลในแฟมขอมูลจะมีการจัดกลุม แบบเรคคอรด (Record) แตล ะเรคคอรดจะมีสว นทีเ่ รยี กวา คีย (key) ท่ีใชใ นการระบุ (ldentify) เรคค อรด คยี ห นง่ึ ๆ อาจจะประกอบไปดว ยฟลด (field) หนึง่ หรือมากหน่ึงฟลดข้ึนไป ซง่ึ การคน หา (Searching) ก็คือขบวนการทท่ี ําการคนหาแตละเรคคอรด โดยใชค าคยี เพอื่ ใชใ นการคนหา ขอมลู ที่ ตองการ อัลกอริทึมของการคนหา คือ อัลกอริทมึ ซง่ึ รับอารก วิ เมนต (argument) Q และพยายามหา ระเบยี นซง่ึ มีคีย (key) คอื a อลั กอริทมึ นี้ใหคา ของทั้งระเบียน หรอื ใหคา พอยนเ ตอรท ชี่ ้ีไปยงั ระเบยี น กรณีท่หี าคียไมพบ ก็จะใหผ ลลพั ธเ ปน ระเบียนนิล (nil record) หรอื นิล พอยนเตอร (nil pointer) การ คนหาทปี่ ระสพผลสาํ เรจ็ เรียกวา การคนคนื (retrieval) ในการคนหาขอมูล คยี ของระเบียน เปน สิ่งบอก ความแตกตา งของระเบยี น คียภ ายใน (Internal key) เปนคยี ท อ่ี ยภู ายใน ระเบียนทีต่ าํ แหนงซึง่ กําหนดไว จากจุดเรม่ิ ตนของระเบียน คียภ ายนอก (Exteral key) เปนคียท ่เี กบ็ ไวในตารางของคียซึ่ง รวมถึงพอยน เตอรซึง่ ชไ้ี ปยังระเบียน คียปฐมภูม(ิ Primary key) เปนคยี ซึ่งมเี อกลักษณ (unique) ซง่ึ แตละระเบยี นจะมี คยี ไ มซํ้ากนั ดรรชนขี องแถวลําดบั เปน คยี ภ ายนอกท่ีมีลกั ษณะเฉพาะ (unique external key) สาํ หรับ คยี ทตุ ิยภูมิ (Secondary key) เปน คียของระเบยี นท่ีไมเปนเอกลกั ษณ ไดแก 2 ระเบยี นมคี ียต วั เดยี วกนั เชน คยี ช ่อื จงั หวัด ในระเบียนของท่ีอยู การคนหาถือวาเปน สง่ิ สาํ คัญในการประมวลผลขอมูลดว ยคอมพวิ เตอร การคนหาจะมคี วาม รวดเร็วหรือไมน ั้นขึน้ อยูกบั อัลกอริทึมของการคนหา และอัลกอรทิ ึมทใี่ ชก ็ข้ึนอยูกบั ลกั ษณะการเก็บขอมลู อกี ตอหนึ่ง โครงสรา งขอมลู ท่ีจะใชเ ปน ตัวบงบอกถงึ อลั กอริทมึ ทใ่ี ชคน หาขอมูลโดยตรงในกรณีที่ตารางนนั้ เกบ็ อยใู นหนว ยความจําหลกั (Main Memory) ทั้งหมด การคน หาขอมลู จะชาหรือเร็วข้นึ อยูกับจาํ นวน ครงั้ ท่ีตองทาํ การเปรียบเทียบ สวนในกรณที ่ีตารางท่ีใชใหญมากจนไมสามารถบรรจุอยูใ นหนว ยความจาํ หลกั ไดหมด ตารางสว นหน่ึงตองเก็บไวในหนวยความจําสาํ รอง (Secondary Storage) ในภาวะเชนนต้ี อ ง ใชเ ทคนิคการคน หาขอ มลู อกี แบบหนงึ่ ซ่งึ ตอ งคํานึงถึงเวลาทส่ี ูญเสียไปในระหวา งหนวยความจําหลกั และ หนว ยความจาํ รอง Data Structure & Algorithm 117 8.2 Sequential Search การคน หาขอมูลตามลาํ ดับ เปน การคน หาทลี่ ะคา ตามลําดับของขอมูลในแฟม ขอมูลจนกวาจะ พบ หรอื ถา ไมพ บกค็ นหาคาถัดไปเรอ่ื ย ๆ จนกวาจะหมดขอ มูล การคน หาขอมลู วธิ นี ี้ เปน การคน หาใน ลักษณะเชิงเสน เปนวิธีทง่ี ายท่สี ดุ และก็เปนวธิ ีทด่ี อ ยประสิทธิภาพกวา วธิ อี ืน่ แตกเ็ หมาะสมสําหรบั การ ประมวลผลขอมลู กบั บางประเภท เชน งานกลมุ (Bach Processing) งานสํารองขอมูล (Backup) งาน ปรับปรงุ แกไขขอมลู ใหทันสมัย (Update) หรอื งานประจาํ (Routine) ข้นั ตอนในการคน หาขอมลู มดี ังน้ี 1. กาํ หนดเขตขอมลู ใหเ ปน คยี ห ลกั หรอื ดชั นีในการคนหาขอ มลู 2. การคนหาเริม่ ตนจากขอมูลตําแหนง แรกสุด ไดแก ในอารเรยต ําแหนงที่ 0 หรือ 1 (ขึ้นอยกู บั ขอกําหนด ที่ผใู ชต อ งการวา จะใหคา เริ่มตนท่ีอารเ รยตําแหนงท่ี 0 หรอื 1 ) 3. ทาํ การเปรยี บเทียบคา ของขอมลู ท่ีตอ งการคนหากับคาของขอมูลในตาํ แหนง นนั้ ๆ 3.1 ถาคาท้ังสองตรงกัน แสดงวา คน พบและจบการทํางานในสวนของการคน หา 3.2 ถา คา ทั้งสองไมต รงกัน แสดงวาคน ยังไมพบ ใหเ ลื่อนตําแหนงของขอมูลไปอีก 1 ตําแหนง 3.3 ทําการเปรยี บเทยี บในขอที่ 3 ไปจนกวา จะพบขอมลู ที่ตองการ 3.4 ถาเปรียบเทยี บไปจนถึงขอมลู ตัวสดุ ทา ยแลวยังไมพ บ ใหจบการทาํ งานในสว นของการคน หา และแสดงใหผ ใู ชทราบวา ไมมีขอ มลู นัน้ ๆ อยใู นกลุม ของขอมูลที่ถกู จัดเก็บไวใ นโครงสรา งขอมูลน้ี ในการคนหาหากโชคดีจะพบครงั้ แรก แตถ าโชคไมด ีจะพบท่ีคาสุดทาย หรือโชครายอาจไมพ บเลย สาํ หรับ กรณีท่ีไมพบ หรอื พบที่คาสุดทาย จาํ นวนครัง้ ในการคน หาจะเทา กับจาํ นวนของขอมลู สมมตุ ิให N : จาํ นวนขอมูล / จํานวนครง้ั ในการคนหาแลวพบครงั้ แรก = 1 ครงั้ จํานวนคร้งั ทีค่ น หาแลวพบที่คาสดุ ทาย หรือไมพบเลย = N ครั้ง ดงั นัน้ จํานวนครั้งในการคนหาโดยเฉล่ยี = (จาํ นวนคร้ังท่คี นหาแลว พบที่คา แรก + จํานวนครง้ั ทค่ี น หา แลวพบที่คาสุดทา ย) /2 Data Structure & Algorithm 118 จํานวนครั้งในการคนหาโดยเฉลยี่ = (1 + N) /2 = N/2 +1/2 จะเห็นวาจาํ นวนครั้งในการคนหาขอมลู โดยเฉลยี่ ขนึ้ อยกู บั ฟงกช ัน Big O(N) Sequential_search (item, count, key) Char *item ; Int count ; Char key ; { register int t ; for (t = 0; t<count; ++t) if (key = = it em[t]) return t; return -1; } เร่ิมตน เราจะคน หาขอมูลท่ีตองการ แตถ าไมพบก็จะสง คา -1 กลบั ไป จะเหน็ วา วิธีน้ีเปนวิธที ง่ี า ย ท่ีสดุ แตเ วลาที่ใชใ นกรณที ่เี ลวท่ีสดุ จะมีคา เปน O(n) เมือ่ n คอื จํานวนขอมูล จากตวั อยา ง ถา ตองการคนหาขอ มูลตวั เลข หมายเลข 11 30 5 8 11 3 Algorithm กาํ หนดใหระเบยี นขอมูลทไี่ มไดจัดเรียงลาํ ดับของแฟมขอมูลประกอบดวย r1, r2,…,rn เมื่อ n >= 1 ซ่งึ มคี าคียข องระเบยี นเปน k1, k2,…,kn ตามลําดับ จากน้ันจะทําการคนหาระเบียนขอมูล ซ่งึ มคี า คยี ข องระเบียนคือ X 1. กาํ หนดตัวนบั ลําดับทีข่ องระเบยี นขอ มลู คอื I แลวทําซ้ําข้นั ตอนที่ 2 ถึงขัน้ ที่ 4 2. ทาํ การคน หา โดยถา x = k1 แลว ใหแจง ขอ ความการคน พบระเบียนขอมลู ทตี่ องการแลวไปทํา ขนั้ ตอนท่ี 5 3. เลอื่ นลาํ ดับท่ีของระเบยี นขอ มูลทลี ะหนึ่ง 4. ตรวจสอบจดุ สิ้นสุดแฟมขอมูล โดยถา I <= n แลว ใหย อนไปทํางานในข้นั ตอนที่ 2 หรอื ไมใหแ จง การคน หาไมพบระเบยี นทตี่ อ งการและทําขั้นตอไป 5. จบการคน หา Data Structure & Algorithm 119 ขอดี 1. งายตอการสรางแฟม ขอมูลขนึ้ มาใหม และการจัดเก็บขอมลู 2. ใชก บั สือ่ ขอ มูลไดทกุ ประเภท จงึ สามารถเลือกเกบ็ ในสอ่ื ขอ มูลราคาถูก 3. สามารถใชกับงานทเี่ ปลยี่ นแปลงขอมูลจํานวนมาก ขอ เสีย 1. ไมสามารถเขา ถึงขอมลู ไดโดยตรงได 2. การประมวลผลขา เพราะเสียเวลาในการอา น Record ทีไ่ มต องการประมวลผล 8.3 Binary Search เปน การคน หารขอมูลอกี วิธีที่มีประสทิ ธิภาพ และเปน ที่นยิ มใชกันอยางแพรหลาย โดยเฉพาะการ สราง Index Table แตว ธิ ีนี้ ขอ มูลจะตองเรยี งกนั กอน จงึ สามารถใชง านได ดงั น้ันถา ขอ มูลมจี าํ นวนมาก ๆ การเรยี งลาํ ดับขอมลู กอ็ าจเปนปญ หาและใชเ วลา การคน หาขอมูลแบบไบนารีเสิรชใชวธิ ีการคน หาโดยอาศยั หลักการของไบนารเี สริ ช ทรี ซึ่งมี รายละเอยี ดในสวนของขัน้ ตอนในการคนหาขอมลู มดี งั นี้ 1. กําหนด หรือรบั ขอมลู ที่ตองการคน หา 2. แบง ครึง่ แฟมขอ มูล หรอื แถวลําดบั ขอมลู 3. นําขอมูลทีต่ องการคนหา จากขอ 1. มาเปรยี บเทยี บกับขอ มูล ท่ีตําแหนงตรงกลาง ซ่ึงไดจ ากการ แบง ขอมูลในขอ 2. ถา มีคา เทากนั แสดงวาการคนหาประสบความสาํ เรจ็ แตถาไมเ ทา กันให ตรวจดูวาขอมลู ท่ตี องการคน หา มีคา นอยกวาหรือมากกวาคา ตรงกลาง ถา นอยกวาใหนาํ คา ใน สวนแรกมาแบง ครงึ่ เพ่ือนาํ มาเปรียบเทียบใหม แตถาไมใชใหน าํ คา ในสวนหลังมาแบงครึ่ง และ นาํ มาเปรียบเทียบใหม เชน เดียวกนั 4. ทําการเปรยี บเทยี บขอมูลในแฟมขอมูลหรือแถวลําดบั ขอมูล โดยแบงครึง่ ลงไปเรื่อยๆ จนกวา จะ พบหรอื ไมสามารถแบง ไดอกี ตอไป น้นั หมายความวาไมพ บขอมลู แนนอน การคาํ นวณหาคา Mid = Low + Hight / 2 Data Structure & Algorithm 120 Data Structure & Algorithm 121 การวัดประสิทธิภาพการทาํ งานของอัลกอริทมึ การคนหาขอมูลแบบไบนารเี สริ ช คา ท่ไี ดจากการวัดประสิทธภิ าพการทํางานของอัลกอรทิ ึมการคน หาขอมูลแบบไบนารีเสิรช พจิ ารณาจาก กรณตี า งๆ ดังนี้ กรณที ี่ดีทีส่ ดุ ( Best Case ) ในการคนหาขอมลู คือพบขอมลู ทตี่ องการคนหาในคร้งั ท่ี 1 กรณีที่แยท ี่สุด ( Worse Case ) ในการคน หาขอมูล คือพบขอมลู ท่ตี องการคน หาในครั้งที่ N +1 เมอ่ื N คือ จํานวนระดับ ( Level ) ของขอมูลในไบนารีนน้ั ๆ โดยคา ของ N เริ่มตน ที่ 0 ดงั น้นั การคน หาแบบไบนารีเราจะใชเ วลาอยา งมากที่สดุ เปน 0( Log2N ) เมอื่ n คอื จาํ นวน ขอมลู Binary Trees and Binary Search Trees Binary (item, count, key) Char *item ; Int count ; Char key ; { int low, high, mid ; low = 0 ; high = count-1 ; while (low<=high) { mid = (low+high)/2 ; if (key <item[mid]) Data Structure & Algorithm 122 high = mid-1 ; /* found */ else if (key > item[mid]) low = mid+1 ; else return mid ; } return -1 ; } ขอแตกตาง ของการคน หาแบบแบบไบนารีและแบบลาํ ดับ คือ การคน หาแบบไบนารไี มไดไล เปรียบเทยี บขอมลู ในลิสทอยา งลาํ ดบั แตเ ปรยี บเทยี บกับคากลางของชดุ ขอมลู ทีท่ ําเชนนี้ไดชุดขอ มลู ตอง เปนขอมลู ท่ีเรียงขอมลู ทเี่ รยี งลําดับ และตอ งอยูในโครงสรางขอมลู ทีส่ ามารถไปยังตําแหนงที่ตอ งการได ทันที 8.4 แฮชชิ่ง (Hashing) วิธนี เี้ ปนวธิ ีทีด่ ีที่สุดสาํ หรบั ใชในการคน หาแบบไบนารี ซึง่ จะใชเ วลาในการคนหา เปน O(log2n) วธิ แี ฮชชิ่งนี้เปนเทคนิคในการสรางตารางโดยมคี ยี แ บบหนึ่งใชในการคน หาคา คียใ น ตารางนัน้ ได ซึ่งทําได งา ยและรวดเร็ว แฮชช่ิงจะใชการแปลงคา คยี เ ปน คาแอดเดรสของคียนัน้ โดย จะอาศัยฟงกช นั พเิ ศษซึ่งเรา เรยี กวาแฮชชิ่งฟงกชัน (hashing function หรือ key – to – addresstransformation) เราจะใช สญั ลักษณ H(k) ซึ่ง k น้ัน กค็ ือคยี ท ่ีจะใชใ นการคน หาขอ มูล ตารางท่ีจะสรา งขึ้นน้ีจะข้ึนอยูกับฟง กชนั ดว ย ฉะน้ันเราจะเลือกใชฟง กท ม่ี ีการกระจายของขอ มูลหรอื คยี ไปสูแอดเดรสตา งๆ ใหม ากท่ีสุด แตใ นบางครั้ง ถาหากมีการแปลงคา คยี k1 และ k2 แลว ให คาแอดเดรสออกมาตรงกนั เราจะเรยี กวิธกี ารดงั กลา ววา การ ชนกนั (collisions) ซงึ่ เราจะตอ งมวี ธิ ใี นการแกปญหานี้ใหไ ด แตกอนอืน่ เราจะมาเรยี นรูถึงวิธกี ารสรา ง ฟง กช ันในการคํานวณหาคาแอดเดรสกันกอน วธิ ีการสรางฟง กช นั แฮชชงิ่ มดี วยกนั หลายวิธดี งั น้ี 8.4.1 วธิ กี ารหาร เปน วธิ ีท่ใี ชก นั มากวิธหี นึ่ง โดยจะกําหนดรูปแบบของวิธีน้คี ือ H(x) = x MOD m+1 โดย ที่ m คือ ตวั หารทีเ่ ปน จํานวนเตม็ บวก จากสูตร จะเหน็ วา เราจะนําเศษท่ีเหลือจากการหารมาใชแลว จงึ บวกดว ย 1 เชน ถา x = 35, m = 11 Data Structure & Algorithm 123 H(35) = 35 MOD 11+1 = 2 +1 = 3วธิ ีการนเี้ ราสามารถกระจายคาไดต้ังแต 1, 2, ….,m หลกั การเลือกคา m คือ จะตองเลอื กคา ใหกระจายในตารางใหม ากที่สุด และคาควรจะเปน จาํ นวนเฉพาะ เพ่ือปองกันไมใหเ กิดการชนกันหรือ เกดิ การชนกันนอ ยท่สี ดุ จากตวั อยา ง จงสรา ง Hash Function จากฟงกช่ันตอ ไปน้ี H(x) = x MOD 7 +1 จากขอมูล 12, 15, 9, 4, 34, 21, 38 01 21 H(12) = 6 02 15 H(15) = 2 03 9 H(9) = 3 04 38 H(4) = 5 05 4 H(34) = 7 06 12 H(21) = 1 07 34 H(38) = 4 Hash Table 8.4.2 วธิ ี Mid square หลกั การคือการนาํ คียขอมลู มายกกาํ ลังสอง จากนน้ั เลือกตําแหนงตรงกลางมาใช เปนตาํ แหนงที่อยูใ น Hash Table ตวั อยางเชน คยี ข อ มลู ยกกาํ ลังสอง ผลลัพธของเลขยกกําลัง ตําแหนงที่อยู (เลอื ก 3,4,5) 312 3122 124 1242 097344 734 542 5422 015376 537 056 0562 293764 376 003136 313 แตเ นอื่ งจากเทคนคิ น้มี ีขอจาํ กัดอยตู รงท่ี คยี ขอมลู จะตองมีคา ไมมากจนเกนิ ไป เพราะถาคีย ขอ มลู มีคา มาก เมื่อนํามายกกําลงั สองแลว คา ผลลพั ธที่ไดจะยงิ่ มคี ามากขึน้ ไปอีก ซง่ึ จะสงผลกระทบตอ การเกบ็ ขอมลู ในหนวยความจํา Data Structure & Algorithm 124 8.4.3 วธิ ีการพับ วิธีการนีเ้ ราจะแบงคียออกเปน สว นๆ ถา เปน ไปไดก็ควรจะแบงเปน สว นละเทาๆกนั แลว นําแตล ะสวนมาบวกเขา ดว ยกัน โดยถามตี ัวทดเกิดขน้ึ ในหลกั ท่มี ากที่สดุ ก็ใหละเอาไว แบง ออกปน 2 แบบ 1. เทคนิคแบบ Fold Shift โดยทําการแบง การชดุ ของขอมูลออกเปน 3 สว นเทา ๆกนั แลว ทําการเล่ือนคยี ของขอ มลู แตล ะ ชุดคยี ใหขอมลู ตรงหลักกัน แลวทําการบวกคา ขอมูลของคีย ผลลพั ธท่ไี ด จะเปนคา คีย Hash ของชดุ ขอมลู จากตัวอยา ง จงหาคาคียของชุดขอ มลู 345684533 โดยวิธีการแบบ Fold Shift จากขอมูล 345684533 แบงขอมลู 345 684 533 บวกขอมลู 345 684 + 533 1562 ตําแหนง ท่ีอยูใน Hash Table คอื ตําแหนง 562 2. เทคนิค Fold Boundary ทาํ การแบงชดุ ของขอมูลออกเปน 3 สว นเทา ๆกนั ทาํ การพบั ตวั เลขคยี ขอมูล โดยยดึ ตําแหนง ท่ี 4-6 เปนตําแหนงตรงกลาง แลวตําแหนง ท่ี 3-1 และ 9-7 จะทําการบวกคา คยี ของขอ มูล จากตัวอยาง จงหาคา Hash Function ของคา คียต อไปนี้ 356942781 โดยวธิ กี ารแบบ Fold Boundary จากขอมูล 356942781 แบง ขอมลู 356 942 781 บวกขอมลู 942 653 + 187 1782 คา คียของ Hash Function ทไ่ี ดคือ 782 Data Structure & Algorithm 125 8.5 การแกป ญ หาคอลลิชนั จากหัวขอท่ีเราไดกลา วถงึ การเกบ็ ขอมูลโดยใชฟง กช น่ั แฮชชิ่ง เพอื่ จะไดคน หาขอมลู ไดร วดเร็วข้ึน และในการเก็บขอมลู แตละคร้ังเราควรจะเกบ็ แอดเดรสเพียงคาเดยี วตอขอมูลหน่ึงคา แตในบางคร้งั ฟงกชน่ั แฮชชิง่ อาจจะทําใหคาแอดเดรสใหมตรงกับแอดเดรสทม่ี ีอยแู ลว จะทาํ ใหเ กิดการชนกันหรือเกดิ คอลลชิ ัน (collision) ข้นึ ซึง่ วธิ แี กป ญ หามหี ลายวธิ แี ตจ ะขอยกตัวอยา ง 2 วธิ คี อื 1. วธิ ี Separate Chaining 2. วิธี Open Addressing จดุ ประสงคข องการแกปญ หาคอลลชิ ันน้ี นอกจากแกปญหาการชนกนั แลว ยงั จะตองพยายามจดั คียใ หอยูใ นแอดเดรสทถ่ี ูกจองไวใ หอยางมปี ระสิทธภิ าพ โดยจะมองแอดเดรสตาง ๆ ใหอยูในรูปของตาราง (อาจมีหลาย ๆ ตารางก็ได) เพื่อจะไดส ะดวกในการเขยี นโปรแกรมและคนหา 8.5.1. วธิ ี Separate Chainning เปน วธิ กี ารเกบ็ ขอมลู โดยใชต ารางของ Hash Table ชว ยในการเกบ็ วธิ กี ารเก็บขอมูลน้ัน หา ไดจากการใช Hash Function โดยคา ขอมูลท่ีเกิดการชนกันของขอมูลน้นั จะทาํ การเกบ็ ขอมลู ลงใน ตารางของ Hash โดยทาํ การเรียงขอมูลตอกันไปเร่ือยๆ เหมอื นเปนแบบโครงสรางอารเรยห รอื ลิงคลสิ ต ตัวอยา ง จงสรางโครงสรางขอมลู แบบ Hash Table ประกอบดวยขอมูล 25, 4, 46, 23, 95, 26, 45 โดยกาํ หนดให Hash Table มขี นาดของตาราง 5 ชอ ง Hash Function : H(x) = x MOD 5 +1 H(25) = 1 H(4) = 5 H(46) = 2 H(23) = 4 H(95) = 1 H(26) = 2 H(45) = 1 01 45 95 25 02 26 46 03 04 23 05 4 Hash Table Data Structure & Algorithm 126 8.5.2. วธิ ี การแบบ Open Addressing มี 2 วิธี คอื 1. Linear Probing เปนวธิ กี ารแกปญหาการชนกันของขอมลู โดยการใช Hash Function มาเปน เครื่องมือชว ย ในการจัดการ จากตวั อยาง จงเพมิ่ คาขอมูลรหสั สนิ คาของบริษัท ซ่ึงมีคา ดงั ตอ ไปนี้ 156, 85, 42, 54, 189, 34, |