zoukankan      html  css  js  c++  java
  • 堆排序实现(C++)

    写堆排序的动机

            自从学了堆以来,对于堆用得最多的就是STL的map,set以及优先队列,而最基本的堆构建,堆调整都没有动作做过,趁着找实习的阶段复习一下堆,实现一个堆排序。


    堆介绍

            堆是一个完全二叉树,也就是说,整棵树除了叶子最底层的叶子节点之外,都是填满的,而最底层的叶子节点由左到右不能有空隙。也就是除了底层,每一层都是满的,底层必须从左到右填数。而最大堆必须满足父节点大于子节点,最小堆则相反。对于堆的插入和删除都是Log(N)的时间复杂度。


    堆排序思路

           堆排序的思想就是先构建一个最大堆,然后不断对堆进行pop操作,把最大值pop到队列尾部。最大堆最大的特点是”子承父业“。当子节点大于父节点时候,子代替父上一线;当父节点被“提升”时候找到最大的子节点补入,剩下的空缺依次不上,遇到没有后代的时候把最后的数过继过来。由于堆是一个完全二叉树,所以堆有一个很重要的特性,就是节点i的子节点分别是i*2 + 1和i*2+2,所以并不需要真正构建一棵树。


    代码

    #include <iostream>
    #include <vector>
    #include <cstdlib>
    #include <ctime>
    #include <algorithm> 
    
    using namespace std;
    void swap(int &num1,int &num2){
        if(num1 != num2){
            num1 ^= num2;
            num2 ^= num1;
            num1 ^= num2;
        }
    }
    void insert(vector<int> &arr_sort){//构建一个最大堆 
         for(int i = 1;i < arr_sort.size();i ++){
             int j = i;
             while(arr_sort[j] > arr_sort[(j - 1)/ 2]){
                 swap(arr_sort[j],arr_sort[(j - 1)/2]);
                j = (j - 1)/2; 
             }
         }
    } 
    
    void pop(vector<int> &arr_sort){
        for(int i = 0;i < arr_sort.size();i ++){
            int tmp = arr_sort[0],j = 0;
            while(j * 2 + 2 <= arr_sort.size() - i - 1){
                if(arr_sort[j * 2 + 1] > arr_sort[j * 2 + 2]){
                    arr_sort[j] = arr_sort[j * 2 + 1];
                    j = j * 2 + 1;
                }else{
                    arr_sort[j] = arr_sort[j * 2 + 2];
                    j = j * 2 + 2;
                }
            }
            arr_sort[j] = arr_sort[arr_sort.size() - i - 1];
            while(arr_sort[j] > arr_sort[(j - 1)/ 2]){
                 swap(arr_sort[j],arr_sort[(j - 1)/2]);
                j = (j - 1)/2; 
             }
            arr_sort[arr_sort.size() - i - 1] = tmp;
            
        }
    }
    
    void initVec(vector<int> &vec) {
        srand((unsigned)time(NULL)); 
        int len = rand() % 1000;
        for(int i = 0; i < len; i ++) {
            vec.push_back(rand() % 1000);
        }
    }
    
    void heap_sort(vector<int> &vec) {
        insert(vec);
        pop(vec);
    }
    
    void print(vector<int> vec) {
        for(int i = 0;i < vec.size();i ++) {
            cout << vec[i] << " ";
        }
        cout << endl;
    }
    
    int main(){
        int nums = 10;
        while(nums --) {
            vector <int> arr1;
            vector <int> arr2;
        
            initVec(arr1);
            arr2 = arr1;
            heap_sort(arr1);
            sort(arr2.begin(), arr2.end());
            cout << "the heap_sort result: ";
            print(arr1);
            cout << "the correct result: ";
            print(arr2);
            for(int i = 0; i < arr1.size(); i ++) {
                if(arr1[i] != arr2[i]) {
                    cout << "wrong result:" << endl;
                    cout << arr1[i] << " and " << arr2[i] << endl;
                    return 1;
                }
            }
            cout << "correct result!" << endl;
        }
        
        return 0;
    }
    View Code
  • 相关阅读:
    算法之递归(4) 应用
    算法之递归(1)
    [Async] [Series #1] 初识Async异步编程模型。
    CVE202142287/CVE202142278 复现
    易读文库下载器1.2版发布
    Sqlite.net 读取DateTime异常的解决方案
    QZFL 2.0.5 源代码
    Sqlite 管理工具 SQLiteDeveloper 及破解
    visio2010数据库正向工程生成数据库脚本
    什么是高内聚、低耦合?
  • 原文地址:https://www.cnblogs.com/chruny/p/6497361.html
Copyright © 2011-2022 走看看