堆排序

堆排序也是一种选择排序。有大顶堆和小顶推,下面以一个数组为例简单说明(大顶堆)。

    NSMutableArray *array = [NSMutableArray arrayWithArray:@[@23,@56,@12,@78,@90,@876,@99]];

一、首先按照层的顺序构造一个完全二叉树,然后初始化堆。

废话少说上代码:

 //建立初始堆
    for (int i = (int)(array.count-1)/2; i >= 0; i--) {//最后一个非叶子结点开始查找
        [self heapOne:array length:array.count index:i];
    }

- (void)heapOne:(NSMutableArray *)array length:(NSInteger)n index:(NSInteger)k{

    NSInteger  k1 = (2*k + 1);//左子树的索引
    NSInteger  k2 = (2*k + 2);//又子树的索引
    
    if (k1 >= n && k2 >= n) {//K已是叶子结点
        return;
    }
    
    NSInteger a1 = NSIntegerMax;
    NSInteger a2 = NSIntegerMax;
    if (k1 < n) {
        a1 = [array[k1] integerValue]; //左孩子值
    }
    if (k2 < n) {
        a2 = [array[k2] integerValue];//右孩纸值
    }
    
    if ([array[k] intValue] <= a1 && [array[k] intValue] <= a2) {//此时已经是堆了
        return;
    }
    if(a1 < a2){
        id m = array[k1];
        array[k1] = array[k];
        array[k] = m;
        [self heapOne:array length:n index:k1];
    }else{
        id m = array[k2];
        array[k2] = array[k];
        array[k] = m;
        [self heapOne:array length:n index:k2];
    }  
}

二、每次遍历即可找到最小值。循环遍历即可输出从小到大的排序。

  //边输出堆边调整
    NSUInteger n = array.count;
    while (n > 0) {
        NSLog(@"%@  ",array[0]);
        array[0] = array[n-1];
        n--;
        [self heapOne:array length:n index:0];
    }

你可能感兴趣的:(堆排序)