小根堆排序

2017-07-24 17:04:23

writer:pprp

参考书目:张新华的《算法竞赛宝典》

小根堆排序,使用数组模拟堆,时间复杂度为O(nlogn)

调整部分的程序比较难理解,有的地方还是不太清楚。

代码如下:

#include <iostream>

using namespace std;

const int N = 100000;

int a[N+1];

void adjust_down(int i,int m)
{
    int tmp;
    while(i*2 <= m)
    {
        i *= 2;
        if((i < m)&&(a[i+1]>a[i]))  //通过这个if判断左右哪个更大一点
            i++;
        if(a[i] > a[i/2]) // 如果max(左,右) > 父节点,那么交换
        {
            tmp = a[i];
            a[i] = a[i/2];
            a[i/2] = tmp;
        }
        else    //如果符合最小堆,那么不进行操作
        {
            break;
        }
    }
}

int main()
{

    int n;
    int i;

    cin >> n;
    // 从1开始用
    for(i = 1 ; i <= n ; i++)
    {
        cin >> a[i];
    }

    for(i = n/2; i>=1; i--)   // 只需从一半开始调整??
    {
        adjust_down(i,n);      //建立堆
    }

    for(i = n; i >= 2; i--)
    {
//        int tmp = a[i];
//        a[i] = a[1];
//        a[1] = tmp;
        a[i] = a[i]^a[1];
        a[1] = a[1]^a[i];
        a[i] = a[i]^a[1];
        adjust_down(1,i-1); //从1开始到i-1开始调整堆
    }

    for(i = 1 ; i <= n; i++)
        cout << a[i] << " ";
    cout << endl;

    return 0;
}
时间: 2024-10-12 08:00:10

小根堆排序的相关文章

Java 小根堆排序

Counter类:计数器 IntPk中包含主键 public class Counter extends IntPK{     private int count;     public int getCount() {         return count;     }     public void setCount(int count) {         this.count = count;     } } MinHeap类:最小堆排序类 package com.ryx.incan

堆排序(选择排序)-八大排序三大查找汇总(2)

二叉堆的定义 二叉堆是完全二叉树或者是近似完全二叉树. 二叉堆满足二个特性: 1.父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值. 2.每个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆). 当父结点的键值总是大于或等于任何一个子节点的键值时为最大堆.当父结点的键值总是小于或等于任何一个子节点的键值时为最小堆.下图展示一个最小堆: 堆的存储 一般都用数组来表示堆,i结点的父结点下标就为(i – 1) / 2.它的左右子结点下标分别为2 * i + 1和2 * i + 2.如

排序算法之堆排序(Heapsort)解析

一.堆排序的优缺点(pros and cons) (还是简单的说说这个,毕竟没有必要浪费时间去理解一个糟糕的的算法) 优点: 堆排序的效率与快排.归并相同,都达到了基于比较的排序算法效率的峰值(时间复杂度为O(nlogn)) 除了高效之外,最大的亮点就是只需要O(1)的辅助空间了,既最高效率又最节省空间,只此一家了 堆排序效率相对稳定,不像快排在最坏情况下时间复杂度会变成O(n^2)),所以无论待排序序列是否有序,堆排序的效率都是O(nlogn)不变(注意这里的稳定特指平均时间复杂度=最坏时间复

【算法拾遗(java描写叙述)】--- 选择排序(直接选择排序、堆排序)

选择排序的基本思想 每一趟从待排序的记录中选出关键字最小的记录,顺序放在已排好序的子文件的最后,知道所有记录排序完毕.主要有两种选择排序方法:直接选择排序(或称简单选择排序)和堆排序. 直接选择排序 基本思想 第i趟排序開始时,当前有序区和无序区分别为R[1 -- i-1]和R[i -- n](1 <= i <= n-1),该趟排序则是从当前无序区中选出关键字最小的记录R[k],将它与无序区的第一个记录R[i]交换,使R[1 -- i]和R[i+1 -- n]分别变为新的有序区和新的无序区.

堆排序模板

1 #include<stdio.h> 2 #include<string.h> 3 #include<iostream> 4 using namespace std; 5 //小根堆 6 void heapAdd(int a[],int i,int num)//添加 7 { 8 a[i]=num; 9 for(int j=i>>1;j&&i&&a[i]<a[j];i=j,j>>=1) 10 swap(a[i

c#:排序

http://www.cnblogs.com/end/archive/2011/10/22/2220940.html 选择排序 冒泡排序 快速排序 插入排序 希尔排序 归并排序 基数排序 计数排序 小根堆排序

C# 常用算法之-排序算法【原创独家】

前段时间因为项目需要,做了个用来对数组排序的类,顺便把以前学过的几种排序算法用C#实现一下.用C#的一些机制来诠释了一下算法的是实现.在阅读本之前,需要一些对C#的有些基本的了解,了解方法参数中out ,ref的作用,掌握面向对象的一些基本思想. 1. 插入排序 1.1. 基本思想: 每次将一个待排序的数据元素,插入到前面已经排好序的数列中的适当位置,使数列依然有序:直到待排序数据元素全部插入完为止. 1.2. 排序过程: [示例]: [初始关键字] [49] 38 65 97 76 13 27

【C++面试】常考题复习:排序算法

// Sort.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <stdlib.h> /************************************************************************/ /* copyright (c) 2014 kernel_main /* c++面试常考点 /* 转载请注明出处:http://www.cnblogs.com/kernel0815/

优先队列及最小堆最大堆

为什么优先队列里默认是堆(heap)实现,默认是优先级高的出队,定义结构体重载函数为什么要按照从小到大排序?原来是自己对优先队列还不太了解: 1 堆 1.1 简介 n个关键字序列Kl,K2,-,Kn称为(Heap),当且仅当该序列满足如下性质(简称为堆性质): (1)ki<=k(2i)且ki<=k(2i+1)(1≤i≤ n),当然,这是小根堆,大根堆则换成>=号.//k(i)相当于二叉树的非叶结点,K(2i)则是左孩子,k(2i+1)是右孩子 若将此序列所存储的向量R[1..n]看做是一