• 堆排序


    堆是一个完全二叉树(对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树),常用来利用树的性质进行排序,即堆排序。

    排序过程

    0.输入一个集合R[0,n],先把该集合元素构成树(分层,第一个元素在第一层,依次按完全二叉树性质放置其余元素)

    1.把树调整为大顶堆或小顶堆;

    2.将R[0]和R[n]互换位置(即将最大的或最小的元素放到最后位置),此时将原集合分为两个集合:R[0,n-1]与R[n](即无序区与有序区)

    3.待交换数据结束,剩下元素可能不满足堆性质,则将R[0,n-1]集合重新调整位置,将R[0]和R[n-1]位置互换(R[n-1]到了有序区),不断重复该过程,直到有序区元素个数为n-1个,排序结束。

    c++代码

    #include<iostream>

    using namespace std;

    //调整方法,构成大顶堆

    //array:待调整的集合

    //start:最后一个非叶子节点

    //end:元素个数(最后位置)

    void Adjust(int *array,int start,int end){

      int temp=array[start];

      int i=2*start+1;//左孩子下标,右孩子2*start+2

      while(i<=end){

      //进行交换

      //在孩子中找最大

        if (i+1<=end && array[i+1]>array[i]){

        i++;//右孩子位置

        }

        if(array[i]<=temp){//孩子小于等于爸爸,不需要操作

        break;

        }

        array[start]=array[i];//不交换,直接赋值,直到最后找到最大的才交换,即本循环结束交换:array[start]=temp

        start=i;

        i=2*start+1;//继续查找有没有左孩子

      }

      array[start]=temp;

    }

    //大顶堆

    void Sort(int *array,int size){

    //本循环执行结束后得到第一个最大值

      for(int i=size/2-1;i>=0;i--){//从最后一个非叶子节点开始,往上到根节点,即从下到上调整

    //调整方法,构成相应的大顶堆

         Adjust(array,i,size-1);

      }

    //调整结束后交换元素(第一个与最后一个元素交换位置)(相当于一次完整调整树结构后得到顶为最大元素(只能保证顶为最大,其他元素不一定满足大顶堆的性质),然后与目前的最后一个元素交换,之后再对堆结构微调)

    for(int j=size-1;j>0;j--){

      int temp=array[j]

      array[j]=array[0]

      array[0]=temp

    //交换后可能不满足堆性质,重新调整剩余元素(即第0个元素到倒数第二个元素),即除第一个最大元素之外其他排序结果都是在本循环中得到

      Adjust(array,0,j-1);//第0个元素到倒数第二个元素调整,从上到下调整,每次元素个数减1:j-1

    }

    }

    int main(int argc,const char *argv[]){

      int array[6]={23,43,5,67,87,45};

      Sort(array,6)

      for (int i=0;i<6;i++){

      cout<<array[i]<<",";

    }

      cout<<endl;

      return 0;

    }

    python 代码:

    # -*- coding:utf-8 -*-
    class Solution:
        def GetLeastNumbers_Solution(self, tinput, k):
               # write code here
                    size=len(tinput)
                    if size==0 or k>size:#注意k是个数,不是第k个,所以是or k>size-1
                        return []
                    array=self.sort(tinput,size)
                    return array[:k]
        def sort(self,array,size):
            for i in range(size/2-1,-1,-1):#从第一个非叶子节点到根节点,range取不到最后边的元素所以是-1
                array1=self.adjust(array,i,size-1)
            for j in range(size-1,-1,-1):
                temp=array1[j]
                array[j]=array1[0]
                array1[0]=temp
                array1=self.adjust(array1,0,j-1)#每次元素个数减1
            return array1
        def adjust(self,array,start,end):
            temp=array[start]
            i=start*2+1
            while i<=end:
                if i+1<=end and array[i+1]>array[i]:
                    i+=1
                if array[i]<temp:
                    break
                array[start]=array[i]
                start=i#往下面一层非叶节点进行判断
                i=start*2+1
            array[start]=temp#所有层级找完后将要判断的temp与目前最大值交换!!!!!!!!!!!这步要注意,temp记录了此次循环的非叶节点的值,array[start]为目前被最大值覆盖了的节点
            return array
               

  • 相关阅读:
    PostgreSQL数据库管理:定期vacuum
    关于压力测试的思路
    作业自动提示功能设计思路
    This system is not registered with RHN
    读《高性能建站指南》(上)
    Ubuntu下PostgreSQL数据库集群(PL/Proxy)配置方法
    PG SQL数据库读写分离的思路
    ASP.NET知识点的明晰(非原创,东拼西凑的,向这些内容的原创者致敬)
    [转]Effective C#原则4:用条件属性而不是#if
    如何在Word文档中插入一条分隔线?
  • 原文地址:https://www.cnblogs.com/kjkj/p/9785970.html
Copyright © 2020-2023  润新知