美文网首页
第五讲 堆排序

第五讲 堆排序

作者: 飞奔的小鲨鱼 | 来源:发表于2018-12-09 16:46 被阅读0次

算法原理:

1.将长度为n的待排序的数组进行堆有序化构造成一个大根堆(小根堆)
2.将根节点与尾节点交换并输出此时的尾节点
3.将剩余的n -1个节点重新进行堆有序化
4.重复步骤2,步骤3直至构造成一个有序序列

@[@(40),@(60),@(20),@(30),@(50),@(80),@(10),@(90),@(70),@(100)]

Snip20181209_9.png

首先要做的是将堆有序化,这里我们以大根堆为例,将有孩子节点的父节点标记为0,1,2,3,4,先从后往前对有孩子节点的父节点开始,将50和100互换,然后一次往前,将30和90互换,然后将20与80互换,将100与60互换,再将100与40互换,当40在节点1的位置时,要保证互换后也是大根堆,所以将40与90互换之后,再与70互换,最后得到的就是一个堆化后的二叉树。

堆有序化.png

接下来执行第2步,将100与50互换,再做一次堆有序化,

100与50互换后堆化.png

然后再将90与40互换,并且堆化,

90与40互换后堆化.png

重复上述的步骤,直到输出根节点。

20与10互换后.png

至此,一个无序化的数组就排序完成了,接下来我们是这用代码实现一下。

- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSArray * array = @[@(40),@(60),@(20),@(30),@(50),@(80),@(10),@(90),@(70),@(100)];
    NSMutableArray * temp = [NSMutableArray arrayWithArray:array];
    // 构造一个大根堆
    // 有子节点的节点 n/2-1 = 4
    // 所以需要调整的父节点为 4,3,2,1,0
    NSInteger size = temp.count;
    for (NSInteger i = array.count/2 - 1; i >= 0; i--) {
        [self creatHeapWithArray:temp size:size parent:i];
    }
    while (size > 0) {
        [temp exchangeObjectAtIndex:size-1 withObjectAtIndex:0];
        size--;
        [self creatHeapWithArray:temp size:size parent:0];
    }
    NSLog(@"Heap Sort  --------> %@",temp);
}


- (void)creatHeapWithArray:(NSMutableArray *)array size:(NSInteger)size parent:(NSInteger)parent {
    NSInteger leftChildNode = 2*parent + 1;
    NSInteger rightChildNode = leftChildNode + 1;//2*index + 2;
    //  左右节点都有的情况
    while (rightChildNode < size) {
        // 如果父节点比两个子节点都大,直接返回
        if (array[parent] >= array[leftChildNode] && array[parent] >= array[rightChildNode]) {
            return;
        }
        
        // 两个子节点其中至少有一个比父节点大
        if (array[leftChildNode] > array[rightChildNode]) {
            // 左子节点和父节点的值交换
            [array exchangeObjectAtIndex:parent withObjectAtIndex:leftChildNode];
            parent = leftChildNode;
        }
        else{
            // 右子节点和父节点的值交换
            [array exchangeObjectAtIndex:parent withObjectAtIndex:rightChildNode];
            parent = rightChildNode;
        }
        
        leftChildNode = 2*parent + 1;
        rightChildNode = leftChildNode + 1;
    }
    
    // 只有左子节点的情况
    if (leftChildNode < size && array[leftChildNode] >= array[parent]) {
        [array exchangeObjectAtIndex:parent withObjectAtIndex:leftChildNode];
    }
}


输出的结果:

Heap Sort  --------> (
    10,
    20,
    30,
    40,
    50,
    60,
    70,
    80,
    90,
    100
)

相关文章

  • 第五讲 堆排序

    算法原理: 1.将长度为n的待排序的数组进行堆有序化构造成一个大根堆(小根堆)2.将根节点与尾节点交换并输出此时的...

  • 03-堆排序(Heap Sort)

    堆排序(Heap Sort) 结合上一讲的内容,发现选择排序可以使用堆排序来进行优化。所以堆排序可以认为是对选择排...

  • 堆排序

    目录 1.堆排序介绍 2.堆排序图文说明 3.堆排序的时间复杂度和稳定性 4.堆排序实现 堆排序介绍 堆排序(He...

  • 堆排序---基础篇

    本文主要介绍堆排序的一些基本过程和分析。 大纲 堆排序简介 堆排序代码实现 1. 堆排序简介 1.1 堆排序的存储...

  • 堆和堆排序

    我们今天讲另外一种特殊的树,“堆”(Heap)。堆这种数据结构的应用场景非常多,最经典的莫过于堆排序了。堆排序是一...

  • 堆和堆排序

    最小K个数 堆排序 堆排序

  • 堆和堆排序

    堆的简介 堆排序是一种复杂度为Nlog(N)的排序算法。介绍堆排序之前先讲一讲什么是堆。这里介绍的是数据结构中的二...

  • JS实现堆排序

    原理 堆排序原理 实现 说明 堆排序对大文件很有效 堆排序是不稳定排序

  • iOS算法总结-堆排序

    iOS算法总结-堆排序 iOS算法总结-堆排序

  • 18-1-23

    第五讲

网友评论

      本文标题:第五讲 堆排序

      本文链接:https://www.haomeiwen.com/subject/tboacqtx.html