复杂排序实现

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

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]<<'\t'; 
}

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]<<'\t';
     //优先队列实现排序
     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()<<'\t';       //从大到小输出
         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<<'\t';
 
   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]<<'\t';
    return 0;    
} 

 

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

posted on 2018-12-25 19:42  爱笑的张飞  阅读(428)  评论(0编辑  收藏  举报

导航