zoukankan      html  css  js  c++  java
  • 堆排序HeapSort

    1. 堆排序快速排序归并排序一样都是时间复杂度为O(N*logN)的几种常见排序方法。学习堆排序前,先讲解下什么是数据结构中的二叉堆。

    二叉堆的定义

    二叉堆是完全二叉树或者是近似完全二叉树。

    二叉堆满足二个特性:

     1)父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值。

     2)每个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆)。

    当父结点的键值总是大于或等于任何一个子节点的键值时为最大堆。当父结点的键值总是小于或等于任何一个子节点的键值时为最小堆

    堆分为大顶堆和小顶堆,其中下图(1)中是大顶堆,(2)为小顶堆

    2.   堆排序的思想

       利用大顶堆(小顶堆)堆顶记录的是最大关键字(最小关键字)这一特性,使得每次从无序中选择最大记录(最小记录)变得简单。

        其基本思想为(大顶堆):

        1)将初始待排序关键字序列(R1,R2....Rn)构建成大顶堆,此堆为初始的无序区;

        2)将堆顶元素R[1]与最后一个元素R[n]交换,此时得到新的无序区(R1,R2,......Rn-1)和新的有序区(Rn),且满足R[1,2...n-1]<=R[n]; 

        3)由于交换后新的堆顶R[1]可能违反堆的性质,因此需要对当前无序区(R1,R2,......Rn-1)调整为新堆,然后再次将R[1]与无序区最后一个元素交换,得到新的无序区(R1,R2....Rn-2)和新的有序区(Rn-1,Rn)。不断重复此过程直到有序区的元素个数为n-1,则整个排序过程完成。

    下面举例说明(大顶堆):

         给定一个整形数组a[]={16,7,3,20,17,8},对其进行堆排序。

        1)首先根据该数组元素构建一个完全二叉树,得到

     
     2)然后需要构造初始堆,则从最后一个非叶节点开始调整,调整过程如下:

    20和16交换后导致16不满足堆的性质,因此需重新调整

    这样就得到了初始堆。

    即每次调整都是从父节点、左孩子节点、右孩子节点三者中选择最大者跟父节点进行交换(交换之后可能造成被交换的孩子节点不满足堆的性质,因此每次交换之后要重新对被交换的孩子节点进行调整)。有了初始堆之后就可以进行排序了。
    3)

    此时3位于堆顶不满堆的性质,则需调整继续调整

    其实就是每次把堆顶元素和最后没交换过的子节点元素交换,然后将此子节点之前的二叉树重新排序,变成大顶堆。

    如果按递增排序,需要用到大顶堆,每次把堆顶(无序堆最大值)放到有序堆前面,重新得到无序区大顶堆;

    如果按递减排序,需要用到小顶堆,每次把堆顶(无序堆最小值)放到有序堆前面,重新得到无序区小顶堆;

    程序如下(包含递增和递减):

     
      1 using System;
      2 using System.Collections.Generic;
      3 using System.Linq;
      4 using System.Text;
      5 using System.IO;
      6 
      7 namespace conHeapSort
      8 {
      9     class HeapSort
     10     {
     11         private static Boolean Asce = true;//heap sorted by ascending order
     12         private static Boolean Desc = false;//heap sorted by descending order
     13         static void Main(string[] args)
     14         {
     15             List<int> input = new List<int>();
     16             HeapSort exap = new HeapSort();
     17             String str;
     18 
     19             input.Add(0);//start from index one
     20             str = Console.ReadLine();
     21             while(str != "exit"){
     22                 input.Add(Int32.Parse(str));
     23                 str = Console.ReadLine();
     24             }
     25 
     26             exap.SortHeap(input, Desc);
     27             for (int i = 1; i < input.Count; i++ )
     28             {
     29                 Console.WriteLine(input[i].ToString());
     30             }
     31         }
     32         void SortHeap(List<int> data, Boolean order)
     33         {
     34             BuildHeap(data, order);
     35 
     36             if (order)
     37             {
     38                 for (int i = data.Count - 1; i >= 1; i--)
     39                 {
     40                     Swap(data, 1, i); //exchange between index 1 and index i
     41                     MaxHeap(data, 1, i - 1); //get max heap
     42                 }
     43             }
     44             else
     45             {
     46                 for (int i = data.Count - 1; i >= 1; i--)
     47                 {
     48                     Swap(data, 1, i);//exchange between index 1 and index i
     49                     MinHeap(data, 1, i - 1); //get min heap
     50                 }
     51             }
     52         }
     53         void BuildHeap(List<int> data, Boolean order)
     54         {
     55             if (order) //make maximal heap
     56             {
     57                 for (int i = data.Count / 2; i >= 1; i--)
     58                 {
     59                     MaxHeap(data, i, data.Count - 1); //initialize
     60                 }
     61             }
     62             else //make minimal heap
     63             {
     64                 for (int i = data.Count / 2; i >= 1; i--)
     65                 {
     66                     MinHeap(data, i, data.Count - 1);//initialize
     67                 }
     68             }
     69         }
     70         //get max heap
     71         void MaxHeap(List<int> data, int i, int size)
     72         {
     73             int lchild = 2 * i;
     74             int rchild = lchild + 1;
     75             int max = i;
     76             if (i <= size / 2)
     77             {
     78                 if (lchild <= size && data[lchild] > data[max])
     79                 {
     80                     max = lchild;
     81                 }
     82                 if (rchild <= size && data[rchild] > data[max])
     83                 {
     84                     max = rchild;
     85                 }
     86                 if (max != i)
     87                 {
     88                     Swap(data, i, max); //exchange child and parent node
     89                     MaxHeap(data, max, size); //continue to adjust 
     90                 }
     91             }
     92         }
     93         //get min heap
     94         void MinHeap(List<int> data, int i, int size)
     95         {
     96             int lchild = 2 * i;
     97             int rchild = lchild + 1;
     98             int min = i;
     99             if (i <= size / 2)
    100             {
    101                 if (lchild <= size && data[lchild] < data[min])
    102                 {
    103                     min = lchild;
    104                 }
    105                 if (rchild <= size && data[rchild] < data[min])
    106                 {
    107                     min = rchild;
    108                 }
    109                 if (min != i)
    110                 {
    111                     Swap(data, i, min);//exchange child and parent node
    112                     MinHeap(data, min, size);
    113                 }
    114             }
    115         }
    116         //exchange index1 and index2 in data
    117         void Swap(List<int> data, int index1, int index2)
    118         {
    119             int temp = data[index2];
    120             data[index2] = data[index1];
    121             data[index1] = temp;
    122         }
    123     }
    124 }
  • 相关阅读:
    light oj 1105 规律
    light oj 1071 dp(吃金币升级版)
    light oj 1084 线性dp
    light oj 1079 01背包
    light oj 1068 数位dp
    light oj 1219 树上贪心
    light oj 1057 状压dp TSP
    light oj 1037 状压dp
    矩阵快速幂3 k*n铺方格
    矩阵快速幂2 3*n铺方格
  • 原文地址:https://www.cnblogs.com/ywl925/p/2870474.html
Copyright © 2011-2022 走看看