1.冒泡排序
2.插入排序
3.选择排序
4.快速排序
5、归并
6、堆排序
1、冒泡排序 .时间复杂度 O(n2)
冒泡排序是一种用时间换空间的排序方法,最坏情况是把顺序的排列变成逆序,或者把逆序的数列变成顺序。在这种情况下,每一次比较都需要进行交换运算。举个例子来说,一个数列 5 4 3 2 1 进行冒泡升序排列,第一次大循环从第一个数(5)开始到倒数第二个数(2)结束,比较过程:先比较5和4,4比5小,交换位置变成4 5 3 2 1;比较5和3,3比5小,交换位置变成4 3 5 2 1……最后比较5和1,1比5小,交换位置变成4 3 2 1 5。这时候共进行了4次比较交换运算,最后1个数变成了数列最大数。
第二次大循环从第一个数(4)开始到倒数第三个数(2)结束。进行3次比较交换运算。
……
所以总的比较次数为 4 + 3 + 2 + 1 = 10次
对于n位的数列则有比较次数为 (n-1) + (n-2) + ... + 1 = n * (n - 1) / 2,这就得到了最大的比较次数
而O(N^2)表示的是复杂度的数量级。举个例子来说,如果n = 10000,那么 n(n-1)/2 = (n^2 - n) / 2 = (100000000 - 10000) / 2,相对10^8来说,10000小的可以忽略不计了,所以总计算次数约为0.5 * N^2。 用O(N^2)就表示了其数量级(忽略前面系数0.5)。
//冒泡排序
-(void)bubbleSort:(NSMutableArray*)array int:(int)n
{
for (int i = 0; i [array[j+1] intValue]) {
NSNumber* temp = array[j];
[array replaceObjectAtIndex:j withObject:array[j+1]];
[array replaceObjectAtIndex:j+1 withObject:temp];
}
}
}
NSLog(@"%@",array);
}
2、插入排序
O(n2)
—插入排序:插入即表示将一个新的数据插入到一个有序数组中,并继续保持有序。例如有一个长度为N的无序数组,进行N-1次的插入即能完成排序;
1)第一次,数组第1个数认为是有序的数组,将数组第二个元素插入仅有1个有序的数组中;
2)第二次,数组前两个元素组成有序的数组,将数组第三个元素插入由两个元素构成的有序数组中......
3)第N-1次,数组前N-1个元素组成有序的数组,将数组的第N个元素插入由N-1个元素构成的有序数组中,则完成了整个插入排序。
-(void)insertSortWithArray:(NSArray *)aData{
NSMutableArray *data = [[NSMutableArray alloc]initWithArray:aData];
for (int i = 1; i < [data count]; i++) {
id tmp = [data objectAtIndex:i];
int j = i-1;
while (j != -1 && [data objectAtIndex:j] > tmp) {
[data replaceObjectAtIndex:j+1 withObject:[data objectAtIndex:j]];
j--;
}
[data replaceObjectAtIndex:j+1 withObject:tmp];
}
NSLog(@"插入排序后的结果:%@",[data description]);
}
3、选择排序(Selection sort)
O(n2)
每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。 选择排序是不稳定的排序方法。
选择排序:比如在一个长度为N的无序数组中,
1)在第一趟遍历N个数据,找出其中最小的数值与第一个元素交换,
2)第二趟遍历剩下的N-1个数据,找出其中最小的数值与第二个元素交换......
3)第N-1趟遍历剩下的2个数据,找出其中最小的数值与第N-1个元素交换,
至此选择排序完成。
int main(int argc, const char * argv[])
{
int array[] = {12,2, 6, 9, 8, 5, 7, 1, 4};
//为了增加可移植性(采取sizeof())计算数组元素个数count
int count = sizeof(array) /sizeof(array[0]);
//
for (int i = 0; i < count - 1; i++) { //比较的趟数
int minIndex = i;//查找最小值
for (int j = minIndex +1; j < count; j++ ) {
if (array[minIndex] > array[j]) {
minIndex = j;
}
}
//如果没有比较到最后还剩余一个数,那么就执行下面的操作
if (minIndex != i) {
//交换数据
int temp = 0;
temp = array[i];
array[i] = array[minIndex];
array[minIndex] = temp;
}
}
return 0;
}
4、快速排序 .时间复杂度 O(n*log2n)
1 )设置两个变量i,j ,排序开始时i = 0,就j = mutableArray.count - 1;
2 )设置数组的第一个值为比较基准数key,key = mutableArray.count[0];
3 )因为设置key为数组的第一个值,所以先从数组最右边开始往前查找比key小的值。如果没有找到,j--继续往前搜索;如果找到则将mutableArray[i]和mutableArray[j]互换,并且停止往前搜索,进入第4步;
4 )从i位置开始往后搜索比key大的值,如果没有找到,i++继续往后搜索;如果找到则将mutableArray[i]和mutableArray[j]互换,并且停止往后搜索;
5 )重复第3、4步,直到i == j(此时刚好执行完第3步或第4部),停止排序;
//快速排序
NSMutableArray *arr = [[NSMutableArray alloc] initWithObjects:@(6), @(1),@(2),@(5),@(9),@(4),@(3),@(30),@(35),@(36),@(7),nil];
[self quickSortArray:arr withLeftIndex:0 andRightIndex:arr.count - 1];
- (void)quickSortArray:(NSMutableArray *)array withLeftIndex:(NSInteger)leftIndex andRightIndex:(NSInteger)rightIndex
{
if (leftIndex >= rightIndex) {//如果数组长度为0或1时返回
return ;
}
NSInteger i = leftIndex;
NSInteger j = rightIndex;
//记录比较基准数
NSInteger key = [array[i] integerValue];
while (i < j) {
/**** 首先从右边j开始查找比基准数小的值 ***/
while (i < j && [array[j] integerValue] >= key) {//如果比基准数大,继续查找
j--;
}
//如果比基准数小,则将查找到的小值调换到i的位置
array[i] = array[j];
/**** 当在右边查找到一个比基准数小的值时,就从i开始往后找比基准数大的值 ***/
while (i < j && [array[i] integerValue] <= key) {//如果比基准数小,继续查找
i++;
}
//如果比基准数大,则将查找到的大值调换到j的位置
array[j] = array[i];
}
//将基准数放到正确位置
array[i] = @(key);
/**** 递归排序 ***/
//排序基准数左边的
[self quickSortArray:array withLeftIndex:leftIndex andRightIndex:i - 1];
//排序基准数右边的
[self quickSortArray:array withLeftIndex:i + 1 andRightIndex:rightIndex];
}
5、归并
时间复杂度O(nlogn)
归并过程为:比较a[i]和b[j]的大小,若a[i]≤b[j],则将第一个有序表中的元素a[i]复制到r[k]中,并令i和k分别加上1;否则将第二个有序表中的元素b[j]复制到r[k]中,并令j和k分别加上1,如此循环下去,直到其中一个有序表取完,然后再将另一个有序表中剩余的元素复制到r中从下标k到下标t的单元。归并排序的算法我们通常用递归实现,先把待排序区间[s,t]以中点二分,接着把左边子区间排序,再把右边子区间排序,最后把左区间和右区间用一次归并操作合并成有序的区间[s,t]。
- (void)mergeSortArray:(NSMutableArray *)array lowIndex:(NSInteger)lowIndex highIndex:(NSInteger)highIndex
{
if (lowIndex >= highIndex) {
return;
}
NSInteger midIndex = lowIndex + (highIndex - lowIndex) / 2;
[self mergeSortArray:array lowIndex:lowIndex highIndex:midIndex];
[self mergeSortArray:array lowIndex:midIndex + 1 highIndex:highIndex];
[self mergeArray:array lowIndex:lowIndex midIndex:midIndex highIndex:highIndex];
}
- (void)mergeArray:(NSMutableArray *)array lowIndex:(NSInteger)lowIndex midIndex:(NSInteger)midIndex highIndex:(NSInteger)highIndex
{
for (NSInteger i = lowIndex; i <= highIndex; i ++) {
self.tempArr[i] = array[i];
}
NSInteger k = lowIndex;
NSInteger l = midIndex + 1;
for (NSInteger j = lowIndex; j <= highIndex; j ++) {
if (l > highIndex) {
array[j] = self.tempArr[k];
k++;
}else if (k > midIndex)
{
array[j] = self.tempArr[l];
l++;
}else if ([self.tempArr[k] integerValue] > [self.tempArr[l] integerValue])
{
array[j] = self.tempArr[l];
l++;
}else
{
array[j] = self.tempArr[k];
k++;
}
}
}
6、堆排序
图解排序算法(三)之堆排序
//堆排序time:O(nlgn)
+ (void)heapSort:(NSMutableArray *)list{
int i , size;
size = [list count]/1.0;
// 从子树开始整理树
for (i = [list count]/1.0 - 1; i >= 0; i--) {
[self createBiggestHeap:list withSize:size beIndex:i];
}
//拆除树
while (size > 0) {
[list exchangeObjectAtIndex:size - 1 withObjectAtIndex:0];//将根(最小)与数组最末交换
size--;//树大小减小
[self createBiggestHeap:list withSize:size beIndex:0];//整理树
}
}
/// 最大堆heap 最大/最小优先级队列
+ (void)createBiggestHeap:(NSMutableArray *)list withSize:(int)size beIndex:(int)element{
int lchild = element * 2 + 1,rchild = lchild + 1;//左右子树
while (rchild < size) {//子树均在范围内
//如果比左右子树都小,完成整理
if (list[element] <= list[lchild] && list[element] <= list[rchild]) return;
//如果左边最小
if(list[lchild] <= list[rchild]){
[list exchangeObjectAtIndex:element withObjectAtIndex:lchild];//把左面的提到上面
element = lchild;//循环时整理子树
}else{
//否则右面最小
[list exchangeObjectAtIndex:element withObjectAtIndex:rchild];
element = rchild;
}
lchild = element * 2 + 1;
rchild = lchild + 1;//重新计算子树位置
}
//只有左子树且子树小于自己
if (lchild < size && list[lchild] < list[element]) {
[list exchangeObjectAtIndex:lchild withObjectAtIndex:element];
}
}
参考:
http://blog.csdn.net/hguisu/article/details/7776068
文中评论很长....有的指出作者的错误,所以代码要自己要运行验证。