ACM总结(各类排序的实现)

各类排序的实现


对于排序这个模块,一直想总结一下,但是确实排序的有太多太多,就借数据结构课上所学来总结一下,感觉以后ACM可以用的上。
基本排序分类

基本排序分类
其中最基础的有直接插入排序,简单选择排序与冒泡排序,不用多说了。
希尔排序:
先将整个待排序记录序列分割成若干个子序列,在子序列内分别进行直接插入排序,待整个序列基本有序时,再对全体记录进行一次直接插入排序。
快速排序:
其实是起泡排序的一种改进,它解决了起泡排序中只有相邻元素之间才能交换的问题。它首先确定一个轴值(pivot(它是比较的基准)),将待排序记录划分成两部分,左侧记录均小于或等于轴值,右侧记录均大于或等于轴值,然后分别对这两部分重复上述过程,直到整个序列有序。
堆排序:
首先将待排序序列调整成一个堆,此时,选出了堆中所以记录的最大者即堆顶的记录,将堆顶记录移走,然后将剩余记录再调整成堆,重复上述操作,直到堆中只有一个记录。
归并排序:
将若干个有序序列逐步归并,最终归并为一个有序数列。(有待学习emmm~)
可添加swap()函数,使得代码更简洁

void swap(int a,int b)
{
int temp;
temp=a;
a=b;
b=temp;
}

这是以下排序的时间性能:
各类排序的时间性能

#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
using namespace std;
class Sort{
public :
    Sort(int r[],int n);//构造函数,生成待排序数列
    ~Sort();//析构函数
    //插入排序:
    void InsertSort();//直接插入排序
    void ShellSort();//希尔排序
    //交换排序:
    void BubbleSort();//冒泡排序
    void QuickSort(int first,int last);//快速排序
    //选择排序:
    void SelectSort();//简单选择排序
    void HeapSort();//堆排序
    //归并排序:
    void MergeSort1(int first,int last);//二路归并递归排序
    void MergeSort2();//二路归并非递归排序
    void Print();//输出
private:
    int Partition(int first,int last);//快速排序,一次划分
    void Sift(int k,int last);//堆排序,堆调整
    void Merge(int first1,int last1,int last2);//归并排序,合并相邻有序数列
    void MergePass(int h);//归并排序,一趟归并
    int *data;//待排序数列
    int length;
};
Sort::Sort(int r[],int n){
data=new int[n];
for(int q=0;q<n;q++)
{
data[q]=r[q];
}
length=n;
}
Sort::~Sort(){
delete[] data;
}
void Sort::Print(){
for(int q=0;q<length;q++)
    {
    cout<<data[q]<<" ";
    }
    cout<<endl;
}
//直接插入排序:
void Sort::InsertSort(){
int i,j,temp;
for(i=1;i<length;i++)
{
temp=data[i];
for(j=i-1;j>=0&&temp<data[j];j--)
{
data[j+1]=data[j];
}
data[j+1]=temp;
}
}
//希尔排序:
void Sort::ShellSort(){
int d,i,j,temp;
for(d=length/2;d>=1;d=d/2)//增量为d进行直接插入排序
{
for(i=d;i<length;i++)//进行一趟希尔排序
{temp=data[i];//暂存待插入记录
for(j=i-d;j>=0&&temp<data[j];j-=d)
{data[j+d]=data[j];}//记录后移d个位置
data[j+d]=temp;
}}}
//起(冒)泡排序:
void Sort::BubbleSort(){
int j,exchange,bound,temp;
exchange=length-1;//第一趟起泡的排序区间是[0~length-1]
while(exchange!=0)
{
bound=exchange;exchange=0;
for(j=0;j<bound;j++)//一趟起泡的排序区间是[0~bound]
{
if(data[j]>data[j+1]){
    temp=data[j];data[j]=data[j+1];data[j+1]=temp;
    exchange=j;//记录每一次交换的位置
}}}}
//
int Sort::Partition(int first,int last){
    int i=first,j=last,temp;//初始化一次划分的区间
    while(i<j){
    while(i<j&&data[i]<=data[j])j--;//右侧扫描
    if(i<j){
        temp=data[i];data[i]=data[j];
        data[j]=temp;
        i++;
        }
    while(i<j&&data[i]<=data[j])i++;//左侧扫描
    if(i<j){
        temp=data[i];data[i]=data[j];
        data[j]=temp;
        j--;
        }
    }
    return i;//i为轴值记录的最终位置
    }
void Sort::QuickSort(int first,int last){
    if(first>=last)return;//区间长度为1,递归结束
    else{
        int pivot=Partition(first,last);//一次结束
        QuickSort(first,pivot-1);//对左侧子序列进行快速排序
        QuickSort(pivot+1,last);//对右侧子序列进行快速排序
        }
    }
//简单选择排序:
void Sort::SelectSort(){
    int i,j,index,temp;
    for(i=0;i<length-1;i++)//进行length-1趟简单选择排序
    {
    index=i;
    for(j=i+1;j<length;j++)//在无序区中选取最小记录
    {if(data[j]<data[index])index=j;}
    if(index!=i){
        temp=data[i];data[i]=data[index];
        data[index]=temp;
        }
    }
    }
//堆排序:
void Sort::Sift(int k,int last){
    int i,j,temp;
    i=k;j=2*i+1;//i是被调整结点,j是i的左孩子
    while(j<=last){//还没有进行到叶子
        if(j<last&&data[j]<data[j+1])j++;//j指向左右孩子的较大者
        if(data[i]>data[j]){break;}//已经是堆
        else{
            temp=data[i];
            data[i]=data[j];
            data[j]=temp;
            i=j;
            j=2*i+1;//被调整结点位于结点j的位置
            }
        }
    }
void Sort::HeapSort(){
    int i,temp;
    for(i=ceil(length/2)-1;i>=0;i--)//从最后一个分支结点至根节点调整
    {Sift(i,length-1);}
    for(i=1;i<length;i++)
    {temp=data[0];data[0]=data[length-i];data[length-i]=temp;
    Sift(0,length-i-1);//重建堆
    }
    }
//二路归并排序:
void Sort::Merge(int first1, int last1, int last2)
{
    int *temp = new int[length]; //数组temp作为合并的辅助空间
    int i = first1, j = last1 + 1, k = first1;
while (i <= last1 && j <= last2)
{
    if (data[i] <= data[j])temp[k++] = data[i++]; //取较小者放入temp[k]
else temp[k++] = data[j++];
}
while (i <= last1) //对第一个子序列进行收尾处理
    temp[k++] = data[i++];
while (j <= last2) //对第二个子序列进行收尾处理
    temp[k++] = data[j++];
for (i = first1; i <= last2; i++) //将合并结果传回数组r
    {data[i] = temp[i];}
delete[ ] temp;
}
//二路归并递归排序:
void Sort::MergeSort1(int first, int last)
{
if (first == last) return; //待排序序列只有1个记录,递归结束
else {
    int mid = (first + last)/2;
    MergeSort1(first, mid); //归并排序前半个子序列
    MergeSort1(mid+1, last); //归并排序后半个子序列
    Merge(first, mid, last); //将两个已排序的子序列合并
}
}
//二路归并非递归排序:
void Sort::MergePass(int h)
{
int i = 0;
while (i + 2 * h <= length) //待归并记录有两个长度为h的子序列
{
Merge(i, i+h-1, i+2*h-1);
i = i + 2 * h;
}
if (i + h < length)
Merge(i, i+h-1, length-1); //两个子序列一个长度小于h
}
void Sort::MergeSort2()
{
int h = 1; //初始时子序列长度为1
while (h < length)
{
MergePass(h); //一趟归并排序
h = 2 * h;
}}
int main()
{
    int a[100000];
    int n;
    cin>>n;
    fill_n(a,n+5,0);
    for(int q=0;q<n;q++)
    {
    cin>>a[q];
    }
    Sort l(a,n);
    //l.ShellSort();
    //l.InsertSort();
    //l.BubbleSort();
    //l.QuickSort(0,n-1);
    //l.SelectSort();
    //l.HeapSort();
    //l.MergeSort1(0,n-1);
    l.MergeSort2();
    l.Print();
    return 0;
}


继续加油吧!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值