算法练习之排序算法(二)
排序算法有很多,包括插入排序、冒泡排序、堆排序、归并排序、选择排序、计数排序、基数排序、桶排序、快速排序等。其中插入排序、堆排序、选择排序、归并排序和快速排序、冒泡排序都是比较排序,它们通过对数组中的元素进行比较来实现排序,而其它排序算法则是利用非比较的其它方法来获得有关输入数组的排序信息。之前利用空闲时间把上述排序算法都实现了一遍,一直没有仔细整理。下面就详细介绍这些算法的实现:
一、选择排序
选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排序完成。它的实现原理是假如数组a中有10个数据,先从a[0]开始与其它元素逐个比较,等一趟比较完毕后,就能找出最小值a[P](或最大值),然后把a[P]和a[0]调换位置,这时a[0]到a[9]中最小(或最大)的数据就调换到了最前面了,依次进行上述运算,就可以实现数据的完整排序了。
数组:26、24、8、6、2、30
一趟:2、24、8、6、26、30 最小索引 4
二趟:2、6、8、24、26、30 最小索引 3
三趟:2、6、8、24、26、30 最小索引 2
。。。
NSMutableArray *array = [NSMutableArray arrayWithObjects:@20, @12, @4, @5, @15, nil];
for (int i = 0; i < array.count - 1; i++) { //比较的趟数
int minIndex = i; //最小值索引
for (int j = i + 1; j < array.count; j++) {
if ([array[j - 1] intValue] > [array[j] intValue]) {
minIndex = j;
}
}
//如果最小值的索引与i不等,调换位置;否则不换
if (minIndex != i) {
[array exchangeObjectAtIndex:i withObjectAtIndex:minIndex];
}
}
NSLog(@"%@", array);
二、冒泡排序
冒泡排序就是把最小的元素往前调或者把最大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间,它是一种稳定排序算法。冒泡排序算法实现起来比较简单,只要弄清楚内循环与外循环执行的操作就可以了。假如我们这里把最大的元素往后调,外循环是指比较的趟数,内循环是指每趟需要比较的次数。每趟比较后,会得出一个最大值。例如数组的长度为6,则需要比较5趟(最后一个数据不需要比较)。
数组:26、24、8、6、2、30
一趟:24、8、6、2、26、30
两趟:8、6、2、24、26、30
三趟:6、2、8、24、26、30
四趟:2、6、8、24、26、30
五趟:2、6、8、24、26、30
1 NSMutableArray *array = [[NSMutableArray alloc]initWithObjects:@26, @24, @8, @6, @2, @30, nil]; 2 /* 3 内循环: 4 -1:为了避免角标越界 5 -x:为了让外循环增加一次,内循环参数与比价的元素个数递减 6 */ 7 for (int i = 0; i < array.count - 1; i++) { 8 for (int j = 0; j < array.count - 1 - i; j++) { 9 if ([array[j] intValue] > [array[j + 1] intValue]) { 10 int temp = [array[j + 1] intValue]; 11 array[j + 1] = array[j]; 12 array[j] = [NSNumber numberWithInt:temp]; 13 } 14 } 15 } 16 17 //第二种方法 18 for (int i = array.count - 1; i > 0; i--) { 19 for (int j = 0; j < i; j++) { 20 if ([array[j] intValue] > [array[j + 1] intValue]) { 21 int temp = [array[j + 1] intValue]; 22 array[j + 1] = array[j]; 23 array[j] = [NSNumber numberWithInt:temp]; 24 } 25 } 26 } 27 28 NSLog(@"%@", array);
三、插入排序
插入排序其基本操作就是将一个数据插入到已经排好序的有序数组中,从而得到一个新的、个数加1的有序数组,算法适用于少量数据的排序。按照插入算法的不同,它可以分为直接插入排序、二分插入排序(又称折半插入排序)、链表插入排序、希尔排序(又称缩小增量排序),它属于稳定排序的一种(通俗的说就是两个相等的数不会交换位置)。
(1)直接插入排序
直接插入排序的基本思想是插入算法把要排序的数组分为两个部分:第一部分包涵了这个数组的所有元素,但将最后一个元素除外(让数组多一个空间才有插入的位置),而第二部分就只有一个元素就是待插入的元素。在第一部分排序完成后,再将这个最后元素插入到已经拍好序的第一部分中。每步将一个待排序的记录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直到全部插完为止。
(2)二分插入排序
二分插入排序
四、希尔排序
希尔排序
五、快速排序
快速排序
六、归并排序
归并排序
七、基数排序
基数排序
八、堆排序
堆排序