排序C++

排序即将一组杂乱无章的数据按照一定规律顺次排列起来

分类:

按数据存储介质:内部排序和外部排序

按比较器个数:串行排序和并行排序

按主要操作:比较排序和基数排序

按辅助空间:原地排序和非原地排序

按稳定性:稳定排序和非稳定排序

按自然性:自然排序和非自然排序

插入排序:

直接插入排序:
代码实现:
void InsertSort(SqList& L)
{
    int i, j;
    for (i = 2; i <= L.length; i++)
    {
        if (L.r[i].key < L.r[i - 1].key)
        {
            L.r[0] = L.r[i];
            for (j = i - 1; L.r[0].key < L.r[j].key; j--)
                L.r[j + 1] = L.r[j];
            L.r[j + 1] = L.r[0];
        }
    }
}
主函数:
int main()
{
    int i,key;
    SqList L;
    ifstream in;
    ofstream out;
    in.open("input.txt");
    out.open("output.txt");
    cout << "请输入数据总数" << endl;
    cin >> L.length;
    for (i = 1; i <= L.length; i++)
        in >> L.r[i].key;
    InsertSort(L);
    for (i = 1; i <= L.length; i++)
        out<< L.r[i].key<<" ";
    cout << "操作成功" << endl;
    out.close();
    return 0;
}
输出结果:

数据1

数据2

数据3

数据源

操作1

结果

操作2

结果

折半插入排序:

用折半查找法查找插入的位置

代码实现:
void BInsertSort(SqList& L)
{
    int low, high, mid,i, j;
    for (i = 2; i <= L.length; i++)
    {
         low = 1;
         L.r[0] = L.r[i];
         high = i - 1;
         while (low <= high)
         {
               mid = (low + high) / 2;
               if (L.r[0].key < L.r[mid].key) high = mid - 1;
               else low = mid + 1;
         }
         for (j = i - 1; j >= high + 1; j--)
              L.r[j + 1] = L.r[j];
         L.r[high + 1] = L.r[0];
    }
}
输出结果:

操作1

结果

操作2

结果

特点:

比顺序查找快;比较次数与初始排列无关;减少了比较次数,但没有减少移动次数;

希尔排序:
原理:
步骤:
代码实现:
void ShellInsert(SqList& L, int a/*间隔排序的间隔大小*/)
{
    int j,k;
    for (j = a + 1; j <= L.length; j++)
    {
        if (L.r[j].key < L.r[j - a].key)
        {
            L.r[0] = L.r[1];
            for (k = j - a; k > 0 && (L.r[0].key < L.r[k].key); k = k - a)
                L.r[k + a] = L.r[k];
            L.r[k + a] = L.r[0];
        }    
    }
}
void ShellSort(SqList&L, int s[], int t)
{
    int i;
    for (i = 0; i < t; i++)
        ShellInsert(L, s[i]);
}
特点:

缩小增量;多遍插入排序;不宜在链式存储结构上使用

举例:

交换排序:

思想:

两两比较,若逆序则交换,直到全部排好为止

冒泡排序:
原理:

两两比较,按从小到大排序

代码实现:
void BubbleSort(SqList& L)
{
    int i, j;
    RedType x;
    for (i = 1; i <= L.length - 1; i++)
    {
        for (j = 0; j <= L.length - 1; j++)
            if (L.r[j].key > L.r[j + 1].key)
            {
                x = L.r[j];
                L.r[j] = L.r[j + 1];
                L.r[j + 1] = x;
            }
    }
}
改进:

添加一个标志

void BubbleSortPro(SqList& L)
{
    int i, j,flag=1;
    RedType x;
    for (i = 1;(i <= L.length-1)&&flag==1; i++)
    {
        flag = 0;
        for (j = 0; j <= L.length-1; j++)
            if (L.r[j].key > L.r[j + 1].key)
            {
                flag = 1;
                x = L.r[j];
                L.r[j] = L.r[j + 1];
                L.r[j + 1] = x;
            }
    }
}

输出结果:

数据1

结果

数据2

结果

快速排序:
原理:

通过一趟排序,将待排序的数据分割成两部分,其中一个部分的数据都比关键字小,一个部分都比关键字大,则可分别对这两部分数据再排序,直到全部有序

代码实现:
void QSort(SqList& L, int low, int high)
{
    int foucus;
    if (low < high)
    {
        foucus = FoucusFind(L, low, high);/*寻找中心点位置*/
        QSort(L, low, foucus - 1);
        QSort(L, foucus + 1,high);
    }
}
int FoucusFind(SqList& L, int low, int high)
{
    int foucuskey;
    L.r[0] = L.r[low];
    foucuskey = L.r[low].key;
    while (low < high)
    {
        while (low < high && L.r[high].key >= foucuskey)
            high--;
        L.r[low] = L.r[high];
        while (low < high && L.r[low].key <= foucuskey)
            low++;
        L.r[high] = L.r[low];
    }
    L.r[low] = L.r[0];
    return low;
}
主函数:
QSort(L,1,L.length);
输出结果:

数据1

结果

数据2

结果

特点:不适用于对原本有序或基本有序的数据排序

选择排序:

简单排序:
原理:

选出最大或者最小的数据放在其最终位置

思路:
代码实现:
void SelectSort(SqList& L)
{
    int i, j, k;
    RedType t;
    for (i = 1; i < L.length; i++)
    {
        j = i;
        for (k = i + 1; k <= L.length; k++)
            if (L.r[k].key < L.r[j].key)
                j = k;
        if (j != i)
        {
            t = L.r[i];
            L.r[i] = L.r[j];
            L.r[j] = t;
        }
    }
}
输出结果:

数据1

结果

数据2

结果

堆排序:
概念:

实质就是一个完全二叉树存储结构

实现:
代码实现(调整):
void HeapAdjust(int R[], int s, int t)
{
    int i,a;
    a = R[s];
    for (i = 2 * s; i <= t; i = i*2)
    {
        if (i < t && R[i] < R[i + 1])
            i++;
        if (a >= R[i])break;
        R[s] = R[i];
        s = i;
    }
    R[s] = a;
}
调整:
优点:

仅需一个供交换用的辅助空间;在最坏情况下,时间复杂度也不大

缺点:

是不稳定的排序方法,不适用数据较少的情况

归并排序:
概念:

将两个或两个以上的有序子序列归并为一个有序序列

二路归并排序(建归并树):
基数排序:
基本思想:

分配加收集

举例:
排序比较总结:

总结:

排序的方法多种多样,应根据数据量的大小,和数据是否需要稳定(如*2,3,2;排序后为*2,2,3;则为稳定排序;如为2,*2,3;则为不稳定排序)来选择适合的排序方法

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值