冒泡排序,简单选择排序,直接插入排序,归并排序,快速排序算法

//各种排序算法的实现
//容易
//2020/4/12
#include 
#include
#define MaxSize 100
typedef int  ElemType;
typedef struct SqList
{
    int data[MaxSize];
    int length;
}SqList;
//简单选择排序
//对一个序列a中的元素按从小到大进行选择排序
void selectsort(int a[])
{
    int j,i,n;
    printf("请输入要使用简单选择排序的序列长度\n");
    scanf("%d",&n);
    for(i=0;i<n;i++)
    {
        int k=i;
        for(j=i;j<n;j++)
        {
            if(a[j]<a[k])  //选出[i,n-1]中最小的元素,下标为k
            {
                k=j;
            }
        }
            int temp=a[i]; //将较小值进行交换
            a[i]=a[k];
            a[k]=temp;
    }
    
}
//直接插入排序
//对一个顺序表L作直接插入排序
void insert_sort(SqList &L)
{
    int i,j;
    for(i=2;i<L.length;i++)
    {
        if(L.data[i]<L.data[i-1])//说明需要将L.data[i]插入到前面的有序子表
        {
            L.data[0]=L.data[1];//设置哨兵L.data[0]
            for(j=i-1;L.data[j]>L.data[0];j--)
                L.data[j+1]=L.data[j];//记录后移
                L.data[j+1]=L.data[0];//插入到正确位置
            
        }
    }
}
//冒泡排序
void bubble_sort(SqList &L)
{
    int i,j;
    for(i=1;i<L.length;i++)
        for(j=L.length-1;j>i;j--)//j从后往前推
        {
            if(L.data[j]>L.data[j+1])//若前者大于后者,则进行交换
            {
                int temp=L.data[j];
                L.data[j]=L.data[j+1];
                L.data[j+1]=temp;
            }
        }
}
//归并排序
//因为非递归归并相对于递归归并能够减少空间和时间性能上面的损耗
//采用非递归的方式实现二路归并排序
//该Merge函数的意思是将有序的SR[i..m]和SR[m+1..n]归并为有序的TR[i..n]
void Merge(int SR[],int TR[],int i,int m,int n)
{
    int j,k,l;
    for (j=m+1,k=i;i<=m&&j<=n;k++)//将SR中的记录由小到大归并到TR
    {
        if(SR[i]<SR[j])
            TR[k]=SR[i++];//将此时较小的SR[i]录入TR,同时i累加1
        else
            TR[k]=SR[j++];//将此时较小的SR[j]录入TR,同时j累加1
    }
    if(i<=m)              //说明还剩下SR[i..m]
    {
        for(l=1;l<=m-i;l++)
            TR[k+1]=SR[i+1];//将剩余的SR[i..m]复制到TR
    }
    if(j<=n)                //说明还剩下SR[j..n]
    {
        for(l=0;l<=n-j;l++)
            TR[k+1]=SR[j+1];//将剩余的SR[j..n]复制到TR
    }
}
//该MergePass函数的意思是将SR[]中相邻长度为S的子序列两两归并到TR[]
void MergePass (int SR[],int TR[],int s,int n)
{
    int i=1;
    int j;
    while(i<=n-2*s+1)
    {
        Merge(SR,TR,i,i+s-1,i+2*s-1);//两两归并
        i=i+2*s;
    }
    if(i<n-s+1)                    //归并最后2个序列
        Merge(SR,TR,i,i+s-1,n);
    else                           //若只剩下单个序列
        for(j=i;j<=n;j++)
            TR[j]=SR[j];
}
//该函数对顺序表L作归并非递归排序
void MergeSort(SqList &L)
{
    int *TR=(int *)malloc(L.length*sizeof(int));//申请额外空间
    int k=1;
    while(k<L.length)
    {
        MergePass(L.data,TR,k,L.length);//将data[]数组中相邻长度为k的序列合并到TR[]
        k=2*k;//子序列长度加倍
        MergePass(TR,L.data,k,L.length);//再将TR[]中相邻长度为k的子序列合并到data[]
        k=2*k;//子序列长度加倍
    }
}

//快速排序算法
//快排的基本思想是:通过一趟排序将待排序记录分割成独立的两部分,其中一部分记录的关键字
//比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序的目的。

//交换顺序表L中子表的记录,使枢轴记录到位,并返回其位置
//j此时在它之前(后)的记录均不大(小)于它。
int partition(SqList &L,int low,int high)
{
    int pivotkey;
    pivotkey=L.data[low]; //用子表的第一个记录作枢轴记录
    while(low<high)       //从表的两端交替向中间扫描
    {
        while(low<high&&L.data[high]>=pivotkey)
            high--;
        int temp1=L.data[high];  //将比枢轴小的记录交换到低端
        L.data[high]=L.data[low];
        L.data[low]=temp1;
        while(low<high&&L.data[low]<=pivotkey)
            low++;
        int temp2=L.data[low];   //将比枢轴记录大的记录交换到高端
        L.data[low]=L.data[high];
        L.data[high]=temp2;
    }
    return low;
}
//对顺序表L中的子序列L->data[low..high]作快速排序
void QSort(SqList &L,int low,int high)
{
    int pivot;
    if(low<high)
    {
        pivot=partition(L,low,high);//将L->[low..high]一分为二
                                    //算出枢轴值pivot
        QSort(L,low,pivot-1);      //对低子表进行递归排序
        QSort(L,pivot+1,high);     //对高子表进行递归排序
    }
}
//对顺序表L作快速排序
void QuickSort(SqList &L)
{
    QSort(L,1,L.length);
}

你可能感兴趣的:(冒泡排序,简单选择排序,直接插入排序,归并排序,快速排序算法)