排序

一,使用排序对象测试排序;

建立一个头文件adt.h,加上头文件
建立一个Sort.h文件加入以下代码

#include"adt.h"

class Sort
{
public:
    void keep(int a[],int b[]);                                             //使数组始终保持无序的状态
    void show(int a[])                                                      //内联函数
    {
        for(int i = 0;i < 12;i++)
        {
            printf("%d ",a[i]);
        }
        printf("%d",a[12]);
    }
    void Q_Sort(int a[],int left,int right);
    void Shell_sort(int a[],int n);
    void Choose_sort(int a[],int n);
    void mopao_sort(int a[],int n);
    void ins_sort(int a[],int n);
    void Merge_sort(int a[],int n);
    void dui_sort(int a[],int n);
};


在cpp文件中加入

#include"adt.h"
#include"Sort.h"

//声明为内敛函数
inline void Swap(int &a,int &b)
{
    int temp = a;
    a = b;
    b = temp;
}

void Sort::keep(int a[],int b[])
{
    for(int i = 0;i < 13;i++)
        a[i] = b[i];
}

int Partition(int a[],int left,int right)     //快排的主函int数体,排区间[left,right);不包括右端点
{
    right--;            //不包括右边界
    int i,j;
    int povite = a[right];
    i = left;
    j = right;       //从枢轴开始,因为是等于
    while(i != j)
    {
        while(a[i] <= povite && i < j)i++;
        while(a[j] >= povite && i < j)j--;
        if(i < j)
            Swap(a[i],a[j]);
    }
    Swap(a[right],a[i]);                       //交换枢轴,最终使左边的比枢轴小,右边的比枢轴大
    return i;
}

void Sort::Q_Sort(int a[],int left,int right)
{
    Sort s;
    if(right > left)  //区间中最少有一个数字,因为不包括右边界所以不能等于
    {
        int p = Partition(a,left,right);
        s.show(a);
        printf("\n");
        Q_Sort(a,left,p);                     //不包括枢轴
        Q_Sort(a,p + 1,right);

    }
}

void Sh_sort(int a[],int n,int d)
{
    Sort s;
    for(int i = d;i < n;i++)              //从后向前进行查看
    {
        int j = i;
        int temp = a[i];
        while(j >= d && temp < a[j - d])
        {
            a[j] = a[j - d];
            j -= d;
        }
        a[j] = temp;
    }
}

void Sort::Shell_sort(int a[],int n)
{
    Sort s;
    int d = n;
    while(d)
    {
        d = d / 2;
        Sh_sort(a,n,d);
        s.show(a);
        printf("\n");
    }
}

//选择排序
void Sort::Choose_sort(int a[],int n)
{
    Sort s;
    for(int i = 0;i < n - 1;i++)
    {
        int temp = a[i];
        int t = i;                      //每循环一次记录最小的下标数下标
        for(int j = i + 1;j < n;j++)
        {
            if(a[j] < a[i])
            {
                t = j;
                a[i] = a[j];
            }
        }
        if(i != t)
        {
            a[t] = temp;
        }
        s.show(a);
        printf("\n");
    }
}

//冒泡排序
void Sort::mopao_sort(int a[],int n)
{
    Sort s;
    for(int i = 0;i < n - 1;i++)
    {
        for(int j = i + 1;j < n;j++)  //交换相邻的两个,如果前面的比后面的大的话
        {
            if(a[i] > a[j])
                Swap(a[i],a[j]);
        }
        s.show(a);
        printf("\n");
    }
}

//插入排序
void Sort::ins_sort(int a[],int n)
{
    Sort s;
    for(int i = 1;i < n;i++)
    {
        int temp = a[i];
        int j = i;
        while(temp < a[j - 1] && j > 0)                                //从后向前找,找到第一个比他小的数记录下
        {
            a[j] = a[j - 1];
            j--;
        }
        a[j] = temp;
        s.show(a);
        printf("\n");
    }
}

//归并排序
void mergea(int a[],int first,int mid,int last,int p[])               //合并数组[first,mid)和[mid,last)
{
    int t = 0;
    int i = first;
    int j = mid;
    while(i < mid && j < last)
    {
        if(a[i] < a[j])                                             //将小的一项加入数组
        {
            p[t++] = a[i++];
        }
        else
        {
            p[t++] = a[j++];
        }
    }
                                                                    //合并后两个有剩余的将其剩余项加入临时数组
    while(i < mid)
    {
        p[t++] = a[i++];
    }
    while(j < last)
    {
        p[t++] = a[j++];
    }
    for(int k = 0;k < t;k++)
    {
        a[first + k] = p[k];                                       //将数拷贝到元素组中
    }
}

void mergesort(int a[],int first,int last,int temp[])               //分治
{
    if(first + 1 < last)                                            //里面有一个数不能进行分组了就
    {
        int mid = (first + last) / 2;
        mergesort(a,first,mid,temp);                                //左边有序
        mergesort(a,mid,last,temp);                                 //右边有序
        mergea(a,first,mid,last,temp);                              //合并
    }
}

void Sort::Merge_sort(int a[],int n)                                //调用函数
{
    int *p = new int[n];
    if(p == NULL)
    {
        printf("没有空间了,删除点东西把\n");
    }
    mergesort(a,0,n,p);
    delete[] p;
    return ;
}

//堆排序
void AdjuHeap(int a[],int pos,int n)                              //调整堆调整的堆为[pos,n-1],或者说是[pos,n);
{
    int tmp = a[pos];
    int pos_mchild ;
    //因为从下至上对根进行排序,所以子树已经排好了顺序,直接找到第一个比tmp小的,插入就可以了,相当于插入排序。
    while(pos * 2 + 1 < n)
    {
        pos_mchild = pos * 2 + 1;                                 //左孩子为2 * n + 1,右孩子为2 * n + 2;
        if(a[pos_mchild] < a[pos_mchild + 1] && pos_mchild != n - 1) //找到左右孩子中较大的一个记录下标
            pos_mchild++;
        if(tmp < a[pos_mchild])
            a[pos] = a[pos_mchild];
        else
            break;
        pos = pos_mchild;
    }
    a[pos] = tmp;
}
//[n/2,n)为叶子节点;
void createHeap(int a[],int n)                                    //创建大根堆
{
    for(int i = n / 2 - 1;i >= 0;i--)
    {
        AdjuHeap(a,i,n);
    }
}

void Sort::dui_sort(int a[],int n)                               //堆排序
{
    createHeap(a,n);
    for(int i = n - 1;i > 0;i--)                                 //大根堆,第一个最大,应该是a[n - 1];
    {
        int tmp = a[i];
        a[i] = a[0];
        a[0] = tmp;
        AdjuHeap(a,0,i);
    }
}

主函数

#include"adt.h"
#include"Sort.h"
int main()
{
    int a[] = {2,5,8,51,7,1,58,5,5,8,4,2,5};
    int b[] = {2,5,8,51,7,1,58,5,5,8,4,2,5};
    Sort s;

    //快排测试
    printf("快速排序\n");
    s.Q_Sort(a,0,13);
    printf("输出为:\n");
    s.show(a);
    printf("\n");

    s.keep(a,b);           //打乱a的顺序

    //希尔排序
    printf("希尔排序\n");
    s.Shell_sort(a,13);
    printf("输出为:\n");
    s.show(a);
    printf("\n");

    s.keep(a,b);

    //堆排序
    printf("堆排序\n");
    s.dui_sort(a,13);
    printf("输出为:\n");
    s.show(a);
    printf("\n");

    s.keep(a,b);

    //归并排序
    printf("归并排序\n");
    s.Merge_sort(a,13);
    printf("输出为:\n");
    s.show(a);
    printf("\n");
    printf("完成\n");

    s.keep(a,b);

    //简单选择排序
    printf("\n");
    printf("简单选择排序\n");
    s.Choose_sort(a,13);
    printf("输出为:\n");
    s.show(a);
    printf("\n");

    s.keep(a,b);

    //冒泡排序
    printf("\n");
    printf("冒泡排序\n");
    s.mopao_sort(a,13);
    printf("输出为\n");
    s.show(a);
    printf("\n");

    s.keep(a,b);

    //简单插入排序
    printf("\n");
    printf("简单插入排序\n");
    s.ins_sort(a,13);
    printf("输出为\n");
    s.show(a);
    printf("\n\n");

    printf("所有排序测试完成\n");
    printf("按任意键继续\n");
    getch();
    return 0;
}

输出的结果是将每一遍的排序输出,将具体的细节展现出来方便学习

二.具体讲解
插入排序
插入排序的思想是将假设已经有一个有序的序列,将后面没有顺序的序列插入这个有序的序列之中。具体细节如下:


//插入排序
void ins_sort(int a[],int n)
{
    Sort s;
    for(int i = 1;i < n;i++)						//第一个是已经有序的,因为就一个数字,所以从第二个数字开始插入
    {
        int temp = a[i];
        int j = i;
        while(temp < a[j - 1] && j > 0)                                //从后向前找,找到第一个比他小的数记录下
        {
            a[j] = a[j - 1];							//不断把前面的位置腾出来
            j--;
        }
        a[j] = temp;
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值