(c++)数据结构与算法之七种排序

//插入排序*3
//交换排序*2
//简单选择排序
//归并排序
//数据:32 18 65 48 27 9
#include <iostream>
using namespace std;
void Show(int a[],int n)
{
    for(int j=0;j<n;j++)
        cout<<a[j]<<"     ";
    cout<<endl;
}
//插入排序:
//向一个有序数组(空数组第一个元素直接插入即可)中
//通过从后至前依次比较,再进行插入(找到合适的位置后其他元素依次后推)
//直到整个数组有序的过程(循环结束)
void insertSort(int data[],int n)//直接插入排序
{
    int p=0,i,a[n];
    for(int j=0;j<n;j++)
        a[j]=data[j];
    for(i=1;i<n;i++)
    {
        int temp=a[i];
        p=i-1;
        while(p>=0&&a[p]>temp)
        {
            a[p+1]=a[p];
            p--;
        }
        a[p+1]=temp;
    }
    for(int j=0;j<n;j++)
        cout<<a[j]<<"     ";
    cout<<endl;
}
//折半插入:
//对比较过程的优化(比较中间值与插入值(参见二分法求解方程),而不是从后至前每个都去比较)
//插入同直接插入排序
void binaryInsertSort(int data[],int n)//折半插入排序
{
    int a[n];
    for(int j=0;j<n;j++)
        a[j]=data[j];
    int lef,mid,rig,p;
    for(p=1;p<n;p++)
    {
        int temp=a[p];
        lef=0;
        rig=p-1;
        while(lef<=rig)
        {
            mid=(lef+rig)/2;
            if(a[mid]>temp)
                rig=mid-1;
            else
                lef=mid+1;
        }
        for(int i=p-1;i>=lef;i--)
            a[i+1]=a[i];
        a[lef]=temp;
    }
    for(int j=0;j<n;j++)
        cout<<a[j]<<"     ";
    cout<<endl;
}
//希尔排序:
//(采用分治法的思想)循环进行:分组+小范围排序--->扩大分组+再排序
//当存在唯一分组(包含所有元素)时循环结束
void shellSort(int data[],int n)//希尔排序
{
    int a[n];
    for(int j=0;j<n;j++)
        a[j]=data[j];
    int d=n/2;
    while(d>=1)
    {
        for(int k=0;k<d;k++)
        {
            for(int i=k+d;i<n;i+=d)
            {
                int temp=a[i];
                int j=i-d;
                while(j>=k&&a[j]>temp)
                {
                    a[j+d]=a[j];
                    j-=d;
                }
                a[j+d]=temp;
            }
        }
        d/=2;
    }
    for(int j=0;j<n;j++)
        cout<<a[j]<<"     ";
    cout<<endl;
}
//冒泡排序:
//双层循环依次比较a[i]和a[i+1],使较大值交换到较后面的位置,
//随着交换越大的位置越靠后,就像泡泡一样随着浮出水面越来越大,因此得名
void paoSort(int data[],int n)//冒泡排序
{
    int a[n];//flag用于标记是否发生交换,若没发生则结束循环(对传统冒泡的优化)
    for(int j=0;j<n;j++)
        a[j]=data[j];
    for(int i=0;i<n;i++)
    {
        int flag=0;
        for(int j=i+1;j<n;j++)
        {
            if(a[i]>a[j])
            {
                flag=1;
                int temp=a[i];
                a[i]=a[j];
                a[j]=temp;
            }
        }
        if(flag==0)     break;
    }
    for(int j=0;j<n;j++)
        cout<<a[j]<<"     ";
    cout<<endl;
}
//快速排序:(递归和非递归两种)
//同样采用分治法的思想:
//找到轴心元素,将数据分为大于小于等于轴心的三部分,对大于小于部分分别递归进行快速排序
//所谓分割策略就是找轴心元素的过程
int Partition1(int data[],int lef,int rig)//快速排序分割策略1
{
    int pivot=data[lef];
    while(lef<rig)
    {
        while(lef<rig&&data[rig]>pivot)
            rig--;
        data[lef]=data[rig];
        while(lef<rig&&data[lef]<=pivot)
            lef++;
        data[rig]=data[lef];
    }
    data[lef]=pivot;
    return lef;
}
int Partition2(int data[],int sta,int en)//快速排序分割策略2
{
    int pivot=data[sta];
    int lef=sta,rig=en;
    while(lef<rig)
    {
        while(lef<=rig&&data[lef]<=pivot)
            lef++;
        while(lef<=rig&&data[rig]>pivot)
            rig--;
        if(lef<rig)
        {
            swap(data[lef],data[rig]);
            rig--;
            lef++;
        }
    }
    swap(data[sta],data[rig]);
    return rig;
}
void quickSort(int data[],int lef,int rig)//快速排序
{
    if(lef<rig)
    {
        int p=Partition1(data,lef,rig);
        quickSort(data,lef,p-1);
        quickSort(data,p+1,rig);
    }
}
void quickSortNoRecursive(int data[],int n)
{
    for(int i=0;i<n;i++)
    {
        int pivot=i;
        int pos=pivot+1;
        for(int j=i+1;j<n;j++)
        {
            if(data[j]<data[pivot])
            {
                if(data[pos]!=data[j])
                    swap(data[pos],data[j]);
                pos++;
            }
        }
        pos--;
        swap(data[i],data[pos]);
    }
    Show(data,n);
}
//选择排序:(只是最简单的选择排序)
//每次找到一个关键值最小的元素与第i个进行交换
//i=0~n-1(循环n次)
void selectionSort(int data[],int n)
{
    for(int i=1;i<n;i++)
    {
        int k=i-1;
        for(int j=i;j<n;j++)
            if(data[j]<data[k])
                k=j;
        if(k!=i-1)
        {
            int t=data[k];
            data[k]=data[i-1];
            data[i-1]=t;
        }
    }
    Show(data,n);
}
//归并排序(递归实现):
//类似快排(递归),采用分治法:分解+对分解子序列进行归并
//先分解成最小的子序列(每个序列只有一个元素)
//合并的同时进行排序,直至合成为一个序列为止
void mergeArray(int data[],int sta,int mid,int en)//合并:data[sta,mid]+data[mid+1,en]
{
    int lenl=mid-sta+1,lenr=en-mid;
    int *lef=new int[lenl],*rig=new int[lenr];
    for(int i=0;i<lenl;i++)
        lef[i]=data[i+sta];
    for(int i=0;i<lenr;i++)
        rig[i]=data[i+mid+1];
    int i=0,j=0,k;
    for(k=sta;k<en;k++)
    {
        if(i==lenl||j==lenr)
            break;
        if(lef[i]<=rig[j])
            data[k]=lef[i++];
        else
            data[k]=rig[j++];
    }
    while(i<lenl)
        data[k++]=lef[i++];
    while(j<lenr)
        data[k++]=rig[j++];
    delete [] lef;
    delete [] rig;
}
void mergeSort(int data[],int sta,int en)
{
    if(sta<en)
    {
        int mid=(sta+en)/2;
        mergeSort(data,sta,mid);
        mergeSort(data,mid+1,en);
        mergeArray(data,sta,mid,en);
    }
}

int main()
{
    int data[6]={32,18,65,48,27,9},a[6],b[6];
    for(int j=0;j<6;j++)
    {
        cout<<data[j]<<"     ";
        a[j]=data[j];
        b[j]=data[j];
    }
    cout<<endl;
    cout<<"直接插入排序:    ";
    insertSort(data,6);
    cout<<"折半插入排序:    ";
    binaryInsertSort(data,6);
    cout<<"    冒泡排序:    ";
    paoSort(data,6);
    cout<<"    希尔排序:    ";
    shellSort(data,6);
    cout<<"    快速排序:    ";
    quickSort(a,0,5);
    Show(a,6);
    cout<<"快速排序(非递归):";
    quickSortNoRecursive(data,6);
    cout<<"简单选择排序:    ";
    selectionSort(data,6);
    cout<<"    归并排序:    ";
    mergeSort(b,0,5);
    Show(b,6);
    return 0;
}
简单地阐述了一下大概的过程,具体内部怎么实现以后有机会了再补吧!
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值