Python堆排序原理与实现方法详解


Posted in Python onMay 11, 2018

本文实例讲述了Python堆排序原理与实现方法。分享给大家供大家参考,具体如下:

在这里要事先说明一下我也是新手,很多东西我了解不是很深入,写算法完全是锻炼自己逻辑能力同时顺带帮助读研的朋友么解决一些实际问题。所以很多时候考虑的东西不是很全面能请各位看到博文的大牛们指正。对于排序算法说实在的我觉得已经写烂了,但是为什么还是要过一遍呢?还是为了能够打牢基础。说一下自己的看法,对于已经的玩烂的算法因该怎么学。首先最重要的还是了解算法的基本模型和算法思想,我觉得这是非常重要的。其次的话首先先尝试自己实现算法每个步骤的功能,当遇到瓶颈的时候回去看算法思想。当你写出来的时候就应该去网上找找有没有更好的实现方法。编程最大的魅力在于每个人都有每个人的套路。然后去思考自己还有哪些地方写的不够好。写算法实际上目标只有两个,对基础语法的巩固和对算法思想的理解。

堆排序

在这里首先要先解释一下什么是堆,堆栈是计算机的两种最基本的数据结构。堆的特点就是FIFO(first in first out)先进先出,这里的话我觉得可以理解成树的结构。堆在接收数据的时候先接收的数据会被先弹出。

栈的特性正好与堆相反,是属于FILO(first in/last out)先进后出的类型。栈处于一级缓存而堆处于二级缓存中。这个不是本文重点所以不做过多展开。

堆排序节点访问和操作定义

堆节点的访问

在这里我们借用wiki的定义来说明:

通常堆是通过一维数组来实现的。在阵列起始位置为0的情况中

(1)父节点i的左子节点在位置(2*i+1);
(2)父节点i的右子节点在位置(2*i+2);
(3)子节点i的父节点在位置floor((i-1)/2);

堆操作

堆可以分为大根堆和小根堆,这里用最大堆的情况来定义操作:

(1)最大堆调整(MAX_Heapify):将堆的末端子节点作调整,使得子节点永远小于父节点。这是核心步骤,在建堆和堆排序都会用到。比较i的根节点和与其所对应i的孩子节点的值。当i根节点的值比左孩子节点的值要小的时候,就把i根节点和左孩子节点所对应的值交换,当i根节点的值比右孩子的节点所对应的值要小的时候,就把i根节点和右孩子节点所对应的值交换。然后再调用堆调整这个过程,可见这是一个递归的过程。

(2)建立最大堆(Build_Max_Heap):将堆所有数据重新排序。建堆的过程其实就是不断做最大堆调整的过程,从len/2出开始调整,一直比到第一个节点。

(3)堆排序(HeapSort):移除位在第一个数据的根节点,并做最大堆调整的递归运算。堆排序是利用建堆和堆调整来进行的。首先先建堆,然后将堆的根节点选出与最后一个节点进行交换,然后将前面len-1个节点继续做堆调整的过程。直到将所有的节点取出,对于n个数我们只需要做n-1次操作。

这里用网上的一张直观图来感受一下

Python堆排序原理与实现方法详解

代码:

# -*- coding: utf-8 -*-
#! python2
import random
def MAX_Heapify(heap,HeapSize,root):#在堆中做结构调整使得父节点的值大于子节点
  left = 2*root + 1
  right = left + 1
  larger = root
  if left < HeapSize and heap[larger] < heap[left]:
    larger = left
  if right < HeapSize and heap[larger] < heap[right]:
    larger = right
  if larger != root:#如果做了堆调整则larger的值等于左节点或者右节点的,这个时候做对调值操作
    heap[larger],heap[root] = heap[root],heap[larger]
    MAX_Heapify(heap, HeapSize, larger)
def Build_MAX_Heap(heap):#构造一个堆,将堆中所有数据重新排序
  HeapSize = len(heap)#将堆的长度当独拿出来方便
  for i in xrange((HeapSize -2)//2,-1,-1):#从后往前出数
    MAX_Heapify(heap,HeapSize,i)
def HeapSort(heap):#将根节点取出与最后一位做对调,对前面len-1个节点继续进行对调整过程。
  Build_MAX_Heap(heap)
  for i in range(len(heap)-1,-1,-1):
    heap[0],heap[i] = heap[i],heap[0]
    MAX_Heapify(heap, i, 0)
  return heap
if __name__ == '__main__':
  a = [30,50,57,77,62,78,94,80,84]
  print a
  HeapSort(a)
  print a
  b = [random.randint(1,1000) for i in range(1000)]
  print b
  HeapSort(b)
  print b

运行结果:

[30, 50, 57, 77, 62, 78, 94, 80, 84]
[30, 50, 57, 62, 77, 78, 80, 84, 94]
[107, 115, 207, 919, 128, 651, 534, 546, 217, 295, 54, 202, 498, 620, 174, 897, 873, 112, 873, 729, 588, 669, 994, 773, 462, 550, 347, 597, 440, 426, 271, 677, 323, 302, 604, 154, 589, 871, 235, 305, 502, 743, 575, 53, 130, 686, 726, 959, 980, 884, 542, 246, 292, 226, 608, 357, 229, 168, 415, 671, 972, 142, 472, 375, 522, 486, 241, 368, 839, 841, 137, 545, 427, 601, 476, 229, 757, 601, 136, 506, 394, 975, 162, 163, 26, 776, 886, 82, 37, 248, 47, 246, 23, 895, 623, 373, 147, 109, 553, 176, 204, 530, 927, 656, 153, 487, 743, 113, 20, 334, 554, 850, 510, 423, 373, 207, 795, 403, 499, 509, 531, 256, 920, 313, 694, 322, 100, 825, 578, 954, 526, 92, 820, 9, 931, 303, 408, 132, 833, 194, 902, 766, 14, 140, 729, 328, 636, 316, 536, 232, 687, 425, 811, 432, 955, 715, 339, 861, 736, 411, 901, 609, 353, 97, 330, 896, 852, 1000, 828, 5, 879, 41, 642, 719, 35, 621, 742, 285, 715, 987, 246, 641, 636, 993, 368, 140, 319, 647, 555, 436, 479, 85, 669, 899, 556, 71, 237, 189, 211, 106, 623, 164, 371, 137, 730, 679, 491, 981, 372, 483, 50, 676, 125, 868, 903, 33, 555, 710, 199, 835, 458, 311, 384, 81, 784, 338, 3, 665, 934, 362, 122, 816, 2, 439, 869, 94, 806, 760, 309, 372, 360, 61, 756, 995, 642, 652, 176, 85, 735, 894, 745, 654, 734, 699, 933, 59, 168, 311, 313, 758, 753, 122, 195, 902, 527, 305, 106, 281, 321, 681, 323, 858, 877, 278, 966, 706, 947, 648, 893, 247, 882, 931, 859, 675, 243, 129, 424, 475, 478, 946, 720, 881, 737, 470, 252, 921, 382, 659, 441, 854, 553, 134, 116, 183, 285, 353, 285, 840, 80, 661, 353, 556, 916, 861, 901, 496, 888, 686, 70, 600, 998, 457, 707, 980, 572, 950, 111, 3, 320, 620, 181, 796, 731, 892, 629, 106, 539, 58, 173, 126, 922, 381, 129, 859, 63, 633, 723, 628, 661, 128, 582, 893, 479, 379, 831, 863, 245, 49, 735, 419, 713, 887, 833, 399, 26, 698, 280, 839, 220, 604, 764, 782, 974, 912, 939, 604, 26, 229, 130, 949, 99, 671, 481, 885, 907, 116, 621, 546, 201, 21, 213, 242, 172, 899, 627, 996, 933, 957, 168, 386, 788, 643, 200, 646, 32, 496, 722, 375, 271, 553, 542, 370, 904, 393, 74, 42, 948, 428, 155, 311, 486, 708, 936, 819, 201, 763, 927, 596, 26, 902, 467, 31, 631, 540, 472, 909, 809, 832, 88, 240, 934, 598, 531, 337, 839, 552, 183, 694, 611, 693, 518, 397, 897, 526, 849, 15, 776, 438, 133, 771, 412, 174, 619, 245, 711, 423, 383, 556, 604, 310, 139, 879, 995, 870, 173, 98, 174, 441, 627, 712, 637, 470, 350, 509, 261, 648, 443, 152, 690, 486, 901, 52, 425, 45, 684, 243, 94, 655, 679, 534, 31, 778, 405, 316, 8, 640, 236, 903, 526, 579, 43, 595, 884, 225, 188, 483, 909, 890, 846, 794, 682, 649, 569, 1000, 840, 292, 614, 986, 305, 800, 763, 563, 266, 134, 202, 156, 231, 896, 174, 696, 914, 235, 302, 358, 538, 595, 770, 462, 13, 960, 768, 106, 119, 370, 602, 807, 622, 770, 359, 768, 209, 314, 195, 590, 527, 275, 775, 785, 271, 557, 680, 756, 399, 426, 730, 57, 905, 643, 852, 406, 932, 204, 757, 348, 655, 812, 891, 887, 214, 171, 296, 279, 81, 383, 668, 271, 335, 345, 541, 997, 659, 671, 732, 525, 811, 612, 704, 23, 1000, 511, 731, 505, 818, 815, 766, 689, 978, 721, 987, 546, 824, 753, 277, 838, 16, 382, 910, 332, 301, 727, 851, 395, 310, 649, 432, 864, 894, 756, 400, 116, 31, 990, 232, 611, 75, 969, 600, 823, 58, 236, 378, 489, 222, 269, 382, 745, 984, 278, 530, 994, 493, 182, 681, 822, 664, 241, 126, 502, 167, 546, 710, 956, 647, 454, 776, 525, 46, 537, 550, 374, 497, 787, 577, 540, 538, 552, 187, 862, 392, 266, 269, 885, 563, 430, 13, 853, 936, 566, 366, 236, 962, 877, 15, 812, 231, 929, 123, 484, 331, 237, 310, 835, 643, 55, 85, 345, 341, 86, 742, 852, 309, 489, 414, 295, 288, 464, 513, 573, 322, 785, 697, 988, 425, 376, 677, 56, 833, 482, 61, 611, 701, 709, 420, 682, 74, 690, 800, 962, 828, 722, 194, 524, 692, 516, 576, 854, 942, 682, 265, 710, 826, 648, 769, 843, 424, 387, 91, 256, 352, 378, 649, 660, 479, 208, 75, 570, 394, 372, 736, 701, 464, 430, 704, 395, 425, 377, 724, 349, 204, 281, 317, 711, 337, 953, 599, 615, 93, 395, 926, 78, 447, 649, 893, 928, 63, 763, 978, 920, 426, 370, 524, 312, 820, 885, 667, 298, 18, 170, 657, 698, 483, 532, 891, 486, 263, 480, 648, 898, 923, 288, 51, 786, 733, 782, 116, 471, 440, 703, 600, 983, 479, 19, 983, 145, 88, 781, 899, 565, 258, 862, 374, 4, 634, 560, 691, 875, 735, 622, 646, 291, 782, 562, 249, 640, 263, 62, 638, 510, 237, 653, 990, 926, 805, 717, 32, 513, 502, 217, 273, 905, 266, 554, 922, 950, 538, 322, 347, 230, 687, 359, 452, 360, 211, 755, 44, 898, 611, 431, 610, 450, 526, 771, 933, 179, 132, 326, 884, 966, 870, 957, 523, 381, 917, 368, 845, 714, 588, 357, 230, 436, 924, 865, 341, 139, 239, 971, 433, 452, 794, 737, 814, 368, 655, 442, 870, 691, 564, 384, 480, 235, 322, 485, 867, 404, 597, 955, 83, 432, 352, 183, 45, 486, 210, 270, 264, 213, 722, 283, 582, 1, 521, 804, 846, 261, 540, 494, 260, 168, 758, 873, 543, 409, 313, 397, 386, 730, 692, 420, 299, 26, 489, 838, 278, 415, 376, 896, 416, 936, 569, 945, 485, 672, 969, 997, 929, 981, 582, 59, 534, 547]
[1, 2, 3, 3, 4, 5, 8, 9, 13, 13, 14, 15, 15, 16, 18, 19, 20, 21, 23, 23, 26, 26, 26, 26, 26, 31, 31, 31, 32, 32, 33, 35, 37, 41, 42, 43, 44, 45, 45, 46, 47, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 58, 59, 59, 61, 61, 62, 63, 63, 70, 71, 74, 74, 75, 75, 78, 80, 81, 81, 82, 83, 85, 85, 85, 86, 88, 88, 91, 92, 93, 94, 94, 97, 98, 99, 100, 106, 106, 106, 106, 107, 109, 111, 112, 113, 115, 116, 116, 116, 116, 119, 122, 122, 123, 125, 126, 126, 128, 128, 129, 129, 130, 130, 132, 132, 133, 134, 134, 136, 137, 137, 139, 139, 140, 140, 142, 145, 147, 152, 153, 154, 155, 156, 162, 163, 164, 167, 168, 168, 168, 168, 170, 171, 172, 173, 173, 174, 174, 174, 174, 176, 176, 179, 181, 182, 183, 183, 183, 187, 188, 189, 194, 194, 195, 195, 199, 200, 201, 201, 202, 202, 204, 204, 204, 207, 207, 208, 209, 210, 211, 211, 213, 213, 214, 217, 217, 220, 222, 225, 226, 229, 229, 229, 230, 230, 231, 231, 232, 232, 235, 235, 235, 236, 236, 236, 237, 237, 237, 239, 240, 241, 241, 242, 243, 243, 245, 245, 246, 246, 246, 247, 248, 249, 252, 256, 256, 258, 260, 261, 261, 263, 263, 264, 265, 266, 266, 266, 269, 269, 270, 271, 271, 271, 271, 273, 275, 277, 278, 278, 278, 279, 280, 281, 281, 283, 285, 285, 285, 288, 288, 291, 292, 292, 295, 295, 296, 298, 299, 301, 302, 302, 303, 305, 305, 305, 309, 309, 310, 310, 310, 311, 311, 311, 312, 313, 313, 313, 314, 316, 316, 317, 319, 320, 321, 322, 322, 322, 322, 323, 323, 326, 328, 330, 331, 332, 334, 335, 337, 337, 338, 339, 341, 341, 345, 345, 347, 347, 348, 349, 350, 352, 352, 353, 353, 353, 357, 357, 358, 359, 359, 360, 360, 362, 366, 368, 368, 368, 368, 370, 370, 370, 371, 372, 372, 372, 373, 373, 374, 374, 375, 375, 376, 376, 377, 378, 378, 379, 381, 381, 382, 382, 382, 383, 383, 384, 384, 386, 386, 387, 392, 393, 394, 394, 395, 395, 395, 397, 397, 399, 399, 400, 403, 404, 405, 406, 408, 409, 411, 412, 414, 415, 415, 416, 419, 420, 420, 423, 423, 424, 424, 425, 425, 425, 425, 426, 426, 426, 427, 428, 430, 430, 431, 432, 432, 432, 433, 436, 436, 438, 439, 440, 440, 441, 441, 442, 443, 447, 450, 452, 452, 454, 457, 458, 462, 462, 464, 464, 467, 470, 470, 471, 472, 472, 475, 476, 478, 479, 479, 479, 479, 480, 480, 481, 482, 483, 483, 483, 484, 485, 485, 486, 486, 486, 486, 486, 487, 489, 489, 489, 491, 493, 494, 496, 496, 497, 498, 499, 502, 502, 502, 505, 506, 509, 509, 510, 510, 511, 513, 513, 516, 518, 521, 522, 523, 524, 524, 525, 525, 526, 526, 526, 526, 527, 527, 530, 530, 531, 531, 532, 534, 534, 534, 536, 537, 538, 538, 538, 539, 540, 540, 540, 541, 542, 542, 543, 545, 546, 546, 546, 546, 547, 550, 550, 552, 552, 553, 553, 553, 554, 554, 555, 555, 556, 556, 556, 557, 560, 562, 563, 563, 564, 565, 566, 569, 569, 570, 572, 573, 575, 576, 577, 578, 579, 582, 582, 582, 588, 588, 589, 590, 595, 595, 596, 597, 597, 598, 599, 600, 600, 600, 601, 601, 602, 604, 604, 604, 604, 608, 609, 610, 611, 611, 611, 611, 612, 614, 615, 619, 620, 620, 621, 621, 622, 622, 623, 623, 627, 627, 628, 629, 631, 633, 634, 636, 636, 637, 638, 640, 640, 641, 642, 642, 643, 643, 643, 646, 646, 647, 647, 648, 648, 648, 648, 649, 649, 649, 649, 651, 652, 653, 654, 655, 655, 655, 656, 657, 659, 659, 660, 661, 661, 664, 665, 667, 668, 669, 669, 671, 671, 671, 672, 675, 676, 677, 677, 679, 679, 680, 681, 681, 682, 682, 682, 684, 686, 686, 687, 687, 689, 690, 690, 691, 691, 692, 692, 693, 694, 694, 696, 697, 698, 698, 699, 701, 701, 703, 704, 704, 706, 707, 708, 709, 710, 710, 710, 711, 711, 712, 713, 714, 715, 715, 717, 719, 720, 721, 722, 722, 722, 723, 724, 726, 727, 729, 729, 730, 730, 730, 731, 731, 732, 733, 734, 735, 735, 735, 736, 736, 737, 737, 742, 742, 743, 743, 745, 745, 753, 753, 755, 756, 756, 756, 757, 757, 758, 758, 760, 763, 763, 763, 764, 766, 766, 768, 768, 769, 770, 770, 771, 771, 773, 775, 776, 776, 776, 778, 781, 782, 782, 782, 784, 785, 785, 786, 787, 788, 794, 794, 795, 796, 800, 800, 804, 805, 806, 807, 809, 811, 811, 812, 812, 814, 815, 816, 818, 819, 820, 820, 822, 823, 824, 825, 826, 828, 828, 831, 832, 833, 833, 833, 835, 835, 838, 838, 839, 839, 839, 840, 840, 841, 843, 845, 846, 846, 849, 850, 851, 852, 852, 852, 853, 854, 854, 858, 859, 859, 861, 861, 862, 862, 863, 864, 865, 867, 868, 869, 870, 870, 870, 871, 873, 873, 873, 875, 877, 877, 879, 879, 881, 882, 884, 884, 884, 885, 885, 885, 886, 887, 887, 888, 890, 891, 891, 892, 893, 893, 893, 894, 894, 895, 896, 896, 896, 897, 897, 898, 898, 899, 899, 899, 901, 901, 901, 902, 902, 902, 903, 903, 904, 905, 905, 907, 909, 909, 910, 912, 914, 916, 917, 919, 920, 920, 921, 922, 922, 923, 924, 926, 926, 927, 927, 928, 929, 929, 931, 931, 932, 933, 933, 933, 934, 934, 936, 936, 936, 939, 942, 945, 946, 947, 948, 949, 950, 950, 953, 954, 955, 955, 956, 957, 957, 959, 960, 962, 962, 966, 966, 969, 969, 971, 972, 974, 975, 978, 978, 980, 980, 981, 981, 983, 983, 984, 986, 987, 987, 988, 990, 990, 993, 994, 994, 995, 995, 996, 997, 997, 998, 1000, 1000, 1000]

这里的函数名我就直接用了wiki上对堆操作的定义,方便理解,其实也是方便我以后来看。

时间复杂度

堆排序的时间复杂度分为两个部分一个是建堆的时候所耗费的时间,一个是进行堆调整的时候所耗费的时间。而堆排序则是调用了建堆和堆调整。

刚刚在上面也提及到了,建堆是一个线性过程,从len/2-0一直调用堆调整的过程,相当于o(h1)+o(h2)+…+o(hlen/2)这里的h表示节点深度,len/2表示节点深度,对于求和过程,结果为线性的O(n)

堆调整为一个递归的过程,调整堆的过程时间复杂度与堆的深度有关系,相当于lgn的操作。

因为建堆的时间复杂度是O(n),调整堆的时间复杂度是lgn,所以堆排序的时间复杂度是O(nlgn)

Python 相关文章推荐
Python 条件判断的缩写方法
Sep 06 Python
零基础写python爬虫之爬虫框架Scrapy安装配置
Nov 06 Python
Python实现豆瓣图片下载的方法
May 25 Python
详解使用 pyenv 管理多个版本 python 环境
Oct 19 Python
查看Django和flask版本的方法
May 14 Python
python ddt数据驱动最简实例代码
Feb 22 Python
pandas 时间格式转换的实现
Jul 06 Python
python利用re,bs4,requests模块获取股票数据
Jul 29 Python
Python大数据之网络爬虫的post请求、get请求区别实例分析
Nov 16 Python
Python解析json代码实例解析
Nov 25 Python
pytorch MSELoss计算平均的实现方法
May 12 Python
python 开心网和豆瓣日记爬取的小爬虫
May 29 Python
python 执行shell命令并将结果保存的实例
May 11 #Python
python 实现登录网页的操作方法
May 11 #Python
Python利用splinter实现浏览器自动化操作方法
May 11 #Python
Python爬虫信息输入及页面的切换方法
May 11 #Python
对python-3-print重定向输出的几种方法总结
May 11 #Python
利用Python如何实现数据驱动的接口自动化测试
May 11 #Python
Python数据结构之图的应用示例
May 11 #Python
You might like
PHP 获取MSN好友列表的代码(2009-05-14测试通过)
2009/09/09 PHP
Laravel 5 框架入门(四)完结篇
2015/04/09 PHP
thinkphp3.x自定义Action、Model及View的简单实现方法
2016/05/19 PHP
PHP巧妙利用位运算实现网站权限管理的方法
2017/03/12 PHP
php usort 使用用户自定义的比较函数对二维数组中的值进行排序
2017/05/02 PHP
Jquery工作常用实例 使用AJAX使网页进行异步更新
2011/07/26 Javascript
jQuery获取浏览器中的分辨率实现代码
2013/04/23 Javascript
ListBox实现上移,下移,左移,右移的简单实例
2014/02/13 Javascript
javascript闭包传参和事件的循环绑定示例探讨
2014/04/17 Javascript
Javascript动态引用CSS文件的2种方法介绍
2014/06/06 Javascript
JavaScript严格模式禁用With语句的原因
2014/10/20 Javascript
JavaScript中将数组进行合并的基本方法讲解
2016/03/07 Javascript
json对象转为字符串,当做参数传递时加密解密的实现方法
2016/06/29 Javascript
Bootstrap Multiselect 常用组件实现代码
2017/07/09 Javascript
mongoose设置unique不生效问题的解决及如何移除unique的限制
2017/11/07 Javascript
原生js实现简单的焦点图效果实例
2017/12/14 Javascript
JS+HTML实现的圆形可点击区域示例【3种方法】
2018/08/01 Javascript
微信小程序封装自定义弹窗的实现代码
2019/05/08 Javascript
Vue+Element UI+vue-quill-editor富文本编辑器及插入图片自定义
2019/08/20 Javascript
[29:10]Ti4 冒泡赛第二天 NEWBEE vs Titan 3
2014/07/15 DOTA
Pyramid Mako模板引入helper对象的步骤方法
2013/11/27 Python
基于Python和Scikit-Learn的机器学习探索
2017/10/16 Python
python实现代码统计程序
2019/09/19 Python
Python搭建代理IP池实现检测IP的方法
2019/10/27 Python
python2.7使用scapy发送syn实例
2020/05/05 Python
Python3爬虫发送请求的知识点实例
2020/07/30 Python
Python 字典一个键对应多个值的方法
2020/09/29 Python
Cpython解释器中的GIL全局解释器锁
2020/11/09 Python
用纯CSS3实现网页中常见的小箭头
2017/10/16 HTML / CSS
致接力运动员广播稿
2014/02/17 职场文书
行政助理工作职责范本
2014/03/04 职场文书
应届毕业生自荐书
2014/06/18 职场文书
项目经理岗位职责
2015/01/31 职场文书
云冈石窟导游词
2015/02/04 职场文书
谢师宴学生答谢词
2015/09/30 职场文书
高二化学教学反思
2016/02/22 职场文书