• 复杂排序实现


    注:本篇写一些常见的复杂排序的实现,比如:快速排序,堆排序,归并排序

    1,快速排序:

    #include<iostream>
    #include<ctime>
    #include<cstdlib>
    using namespace std;
    
    void printIn(int* a,int length){
        for(int i=0;i<length;i++)
            cout<<a[i]<<'	'; 
    }
    
    void swap(int& a,int& b){  //行参为引用,可直接修改实参的值 
        int temp;
        temp = a;
        a = b;
        b = temp;
    }
    
    int InRandomRange(int a,int b){  // 形参不是引用,不修改实参的值 
        int randomNumber = rand()%(b-a+1) + a; //生成[a,b]中的随机数
        return randomNumber; 
    } 
    
    // 教材思想 
    int Partition1(int* arr,int left,int right){
        int pivot = arr[left];   //选取第一个元素为基准
        while(left<right){
            while(left < right && arr[right] >= pivot)  //找到第一个小于 tmp 的元素 arr[right] 
                right--;
                if(left<right) arr[left] = arr[right];
            while(left < right && arr[left] <= pivot)  //找到第一个大于 tmp 的元素 arr[left] 
                left++;
                if(left<right) arr[right] = arr[left];     
        } 
        arr[left] = pivot;      //此时 left == right 
        return left;            //返回枢纽值的下标 
    }
    
    // 剑指 Offer 思想
    int Partition2(int* arr,int start,int end){
        int index = InRandomRange(start,end); //随机选择枢纽值 
        int small = start - 1;               //small 始终是左边数组的最后一个元素的下标 
        swap(arr[index],arr[end]);
        for(index=start;index<end;index++){
            if(arr[index]<arr[end]){         //进入这个 if 语句的 index 指向小于枢纽值的元素 
                ++small;                     //small 为在等待放小于枢纽值元素的下标位置 
                if(small != index)            
                    swap(arr[small],arr[index]);   //将小于枢纽值的元素放在 small 处 
            }//if
        } //for
        ++small;                           //把枢纽值放到 small 下标的后面,返回 枢纽值下标位置 
        swap(arr[small],arr[end]);
        return small;
    } 
      
    void quickSort(int*a,int left,int right){         
        int pivot;
        if(left<=right){
            pivot = Partition2(a,left,right);
            quickSort(a,left,pivot-1);
            quickSort(a,pivot+1,right);
        } 
    }
    
    int main(){
        int a[5] = {1,3,2,6,5};
        quickSort(a,0,4);
        printIn(a,5);
        return 0;
    }

    快排在库函数中的实现(c/c++):

    #include<iostream>
    #include<algorithm>
    #include<queue>
    #include<set> using namespace std; int compare(const void* a,const void* b){ // c 中 qsort 有函数指针参数要传递 return (*(int*) a - *(int*) b); } int arr[10] = {12,45,234,64,12,35,63,23,12,55}; //测试数组 int main(){ sort(arr,arr+10); //c++ STL 中的sort :实质是快排实现的 qsort(arr,10,sizeof(int),compare); // c 库函数中的排序,实质是快排,但是速度比 C++ 慢,使用也不够灵活 for(int i=0;i<(sizeof(arr)/sizeof(arr[0]));i++) cout<<arr[i]<<' ';
         //优先队列实现排序
         priority_queue<int> pq1;              // 定义优先队列,先插入,排序好再输出
         for(int i=0;i<(sizeof(arr)/sizeof(arr[0]));i++)
             pq1.push(arr[i]);
    
    
         for(int i=0;!pq1.empty();i++){
             cout<<pq1.top()<<' ';       //从大到小输出
             pq1.pop();
         }
         // set 实现排序:set 的底层实现是红黑树,即平衡二叉树,所以对其进行中序遍历即可实现排序操作
       set<int> set1;
         set1.insert(arr,arr+10);
         for(set<int>::iterator p=set1.begin();p!=set1.end();++p)
             cout<<*p<<' ';
     
       return 0;
    } 

    2,堆排序:

    /* 堆排序  arr 从下标 1 开始存储  */
    #include<iostream>
    using namespace std;
    
    void swap(int& a,int &b){
        int tmp;
        tmp = a;
        a = b;
        b = tmp;
    }
    
    //向上调整 
    void siftup(int*arr,int u){
        int i,p;
        i = u;
        for(;;){
            if(i==1) break;
            p = i/2;
            if(arr[p]>=arr[i]) break;
            swap(arr[p],arr[i]);
            i = p;
        }
    } 
    //向下调整
    void siftdown(int*arr,int l,int u){
        int i,c;
        i=1;
        for(;;){
            c=2*i;
            if(c>u) break;
            if(c+1<=u && arr[c+1]>arr[c]) c++;  //找出左右孩子中的最大的那个进行交换 
            if(arr[i]>arr[c]) break;
            swap(arr[i],arr[c]);
            i=c;
        }
    } 
    
    // 向上调整建立大根堆 
    void buildUpBigHeap(int* arr,int n){
        for(int i=2;i<=n;i++)
            siftup(arr,i);
    }
    
    // 向下调整建立大根堆 
    void buildDownBigHeap(int* arr,int n){
        for(int i=n/2;i>=1;i--)
            siftdown(arr,i,n);
    } 
    
    void heapSort(int* arr,int n){
        int i;
    //    arr--;                        //注释两行 arr-- arr++ 的作用是:输入的数组下标从 0 开始,排序完成的数组也是从下标 0 处开始存放 
        buildUpBigHeap(arr,n);        // 也可以选择向下调整建立大根堆,此次选择向上调整建立大根堆 
        for(i=n;i>=2;i--){
            swap(arr[i],arr[1]);    //最大值交换到最后
            siftdown(arr,1,i-1); 
        }
    //    arr++;
    }
    
    int main(){
        int a[6] = {-1,1,3,2,6,5};  //下标从 1 开始,开始时的 -1 作为开始 a[0] 处 
        heapSort(a,5);
        for(int i=1;i<=5;i++)
            cout<<a[i]<<'	';
        return 0;    
    } 

    后面的几种排序有空再更新了。。

    所有博文均为原著,如若转载,请注明出处!
  • 相关阅读:
    Educational Codeforces Round 81 (Rated for Div. 2)(训练)
    Prime Path(POJ) 3126
    前端知识(一)04 Vue.js入门-谷粒学院
    前端知识(一)03 初识 ECMAScript 6-谷粒学院
    前端知识(一)02 初识 Node.js-谷粒学院
    前端知识(一)01 前端开发和前端开发工具-谷粒学院
    同步和异步、阻塞和非阻塞
    给HTML页面设置自己的icon
    解决MyBatis-Plus 3.3.1中自动生成代码tinyint(1)无法自动转换为Boolean 的办法
    驼峰命名和短横线命名的转换
  • 原文地址:https://www.cnblogs.com/zpcoding/p/10176041.html
Copyright © 2020-2023  润新知