[数据结构与算法-iOS 实现]堆排序附demo

堆排序

堆排序实际上是对选择排序的一个优化,选择排序每次都要选出一个最大值,相当于从头遍历到尾去选择最大值,时间复杂度为O(n),在加上外层遍历n-1次,所有时间复杂度为O(n^2),而堆排序在选择最大值的时候有优势,所以堆排序是对选择排序的一个优化。

这里如果不了解怎样建堆,不了解什么是上滤或者下滤,是没办法完成堆排序的,关于堆,可以看我的这篇文章,先明白这些才能完成堆排序.

操作流程

1. 对数组元素进行原地建堆,然后执行后面的操作,直到堆的元素数量为1
2. 交换堆顶元素与尾元素,相当于最大值和最小值的交换
3. 然后将堆的数量减去一
4. 因为堆顶元素被交换之后不符合大顶堆或者小顶堆的要求,需要对0位置的元素进行一次 siftDown 下滤操作。、

时间复杂度分析

原地建堆需要遍历每一个元素,所以时间复杂度为 O(n),交换元素的位置为O(1),数量减去一为iO(1),siftDown 操作为logn,因为每找一个最大值就需要log,所以为nlog

所以总的复杂度为 O(n) + O(1) + O(1) + nlogn = nlogn

代码及注释

//
//  SCXHeapSoft.m
//  TestArithmetic
//
//  Created by 孙承秀 on 2020/7/11.
//  Copyright © 2020 孙承秀. All rights reserved.
//

#import "SCXHeapSoft.h"
@interface SCXHeapSoft(){
    
    int _size;
}

@end
@implementation SCXHeapSoft
-(NSArray *)soft:(NSArray *)arr{
    // 建堆
    NSMutableArray *soft = arr.mutableCopy;
    _size = soft.count;
    // 自下而上下滤
    for (NSInteger i = (_size >> 1) - 1; i >= 0; i --) {
        [self siftDown:i arr:soft];
    }
    while (_size > 1) {
        // 将堆顶和堆尾元素互换
        // size --
        NSNumber *tmp = soft[--_size];
        soft[_size] = soft[0];
        soft[0] = tmp;
        
        // 将第0个元素下滤,保证除了最后一个元素之外,其余的元素组成一个堆
        [self siftDown:0 arr:soft];
    }
    return soft.copy;
}
// 下滤
- (void)siftDown:(NSInteger)index arr:(NSMutableArray *)_array{
    //第一个叶子节点的索引就是非叶子节点的数量,因为为完全二叉树,所以,要么没有左右子节点,要么只有左节点,不可能出现只有右子节点的情况
    // index < 第一个叶子节点的索引,这样就能保证他能和有子节点的进行交换
    // 必须保证index 位置为非叶子节点,因为这样可以找到左节点,或者左右节点,进行交换
    // 非叶子节点的数量为 二叉树节点数量除以二
    if (index >= _array.count) {
        return;
    }
    id obj = _array[index];
    // 第一个非叶子节点的索引
    NSInteger half = _size >> 1;
    while (index < half) {
        // 要么只有左子节点
        // 要么右左右子节点
        // 左子节点的索引为 2i +1 ,右子节点的索引为 2i+2
        NSInteger leftIndex = (index << 1) + 1;
        id leftObjf = _array[leftIndex];
        NSInteger rightIndex = leftIndex +1;
        
        
        // 选出最大值
        id maxObj = leftObjf;
        NSInteger maxIndex = leftIndex;
        if (rightIndex < _size ) {
            id rightObj = _array[rightIndex];
            if ([self compareA:rightObj valueB:leftObjf]) {
                // 右节点比左节点大
                maxObj = rightObj;
                maxIndex = rightIndex;
            }
        }
        
        // 选出左右最大的节点和index之后,和当前节点进行比较
        if ([self compareA:obj valueB:maxObj]) {
            // 如果当前节点比左右子节点中最大的那一个都打大,就退出不用交换了
            break;
        }
        // 如果当前节点比左右节点中的其中一个小,那么将当前位置,赋值为最大值,将最大值一次上滤,然后自己下沉,记住位置
        _array[index] = maxObj;
        index = maxIndex;
    }
    _array[index] = obj;
}
- (BOOL)compareA:(NSNumber *)valueA valueB:(NSNumber *)valueB{
    return valueA.intValue > valueB.intValue;
}
@end

demo

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,458评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,454评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,171评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,062评论 0 207
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,440评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,661评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,906评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,609评论 0 200
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,379评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,600评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,085评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,409评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,072评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,088评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,860评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,704评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,608评论 2 270