排序的一般定义

  • 排序是计算机内经常进行的一种操作,其目的是将一组 "无序" 的数据元素调整为 "有序" 的数据元素。

例:
将下列关键字序列
52,49,80,36,14,58,61,23,97,75
调整为:
14,23,36,49,52,58,61,75,80,97

排序的数学定义

假设含 n 个元素的序列为:{R1, R2, ..., Rn}, 其相应关键字序列为:{K1, K2, ..., Kn}

这些关键字相互之间可以进行比较,即:在它们之间存在着这样一个关系:{Kp1, Kp2, ..., Kpn}

按此固有关系将上式记录序列重新排列为:{Rp1, Rp2, ..., Rpn} 的操作称为排序。

排序的示例

image.png

image.png

问题: 按总评排序后为什么张无忌的排名比郭靖靠前呢?

排序的稳定性

如果在序列中有两个数据元素 r[i] 和 r[j], 他们的关键字 k[i] == k[j],且在排序之前,对象 r[i] 排在 r[j] 前面; 如在排序之后,对象 r[i]任在对象 r[j] 的前面,则称这个排序方法是稳定的,否则称这个排序方法是不稳定的。

稳定性排序示例

image.png

image.png

多关键字排序

  • 排序时需要比较的关键字多于一个

    • 排序结果首先按 关键字1 进行排序
    • 当关键字1相同时按 关键字2 进行排序
    • ......
    • 当关键字 n -1 相同时按 关键字n 进行排序

多关键子排序示例

image.png

image.png

问题: 多关键字排序是否比单关键字排序更复杂?

对于多关键字排序,只需要在比较操作时同时考虑多个关键字即可!!!

编程实验:多关键字的比较操作

#include <iostream>

using namespace std;

struct Test
{
    int key1;  // heigh
    int key2;  // low

    Test(int k1, int k2) : key1(k1), key2(k2)
    {
    }

    bool operator == (const Test &t)
    {
        return (key1 == t.key1) && (key2 == t.key2);
    }

    bool operator != (const Test &t)
    {
        return !(*this == t);
    }

    bool operator < (const Test &t)
    {
        return (key1 < t.key1) || ((key1 == t.key1) && (key2 < t.key2));
    }

    bool operator >= (const Test &t)
    {
        return !(*this < t);
    }

    bool operator > (const Test &t)
    {
        return (key1 > t.key1) || ((key1 == t.key1) && (key2 > t.key2));
    }

    bool operator <= (const Test &t)
    {
        return !(*this > t);
    }
};

int main()
{
    Test t1(3, 4);
    Test t2(2, 5);
    Test t3(3, 5);

    cout << (t1 > t2) << endl;
    cout << (t1 < t3) << endl;

    return 0;
}

输出:

1
1

比较中的关键操作

  • 比较

    • 任意两个数据元素通过比较操作确定先后次序
  • 交换

    • 数据元素之间需要交换才能得到预期结果

排序的审判

  • 时间性能

    • 关键性能差异体现在比较和交换的数量
  • 辅助存储空间

    • 为完成排序操作需要的额外存储空间
    • 必要时可以 “空间换时间”
  • 算法的时间复杂性

    • 过于复杂的排序法可能影响可读性和可维护性

DTLib 中的排序列设计

image.png

class Sort : public Object
{
public:
    // ...
private:
    Sort();
    Sort(const Sort&);
    Sort &operator= (const Sort&);
    
    template <typename T>
    static void Swap(T &a, T &b)
    {
        T c(a);
        a = b;
        b = c;
    }
};

编程实验: DTLib 中的排序类

文件:Sort.h

#ifndef SORT_H
#define SORT_H

#include "Object.h"

namespace DTLib
{

class Sort : public Object
{
public:

private:
    Sort();
    Sort(const Sort&);
    Sort &operator= (const Sort&);

    template <typename T>
    static void Swap(T &a, T &b)
    {
        T c(a);
        a = b;
        b = c;
    }
};

}

#endif // SORT_H

小结

  • 排序是数据元素从无序到有序的过程
  • 排序具有稳定性,是选择排序算法的因素之一
  • 比较和交换是排序的基本操作
  • 多关键字排序与单关键字排序无本质区别
  • 排序的时间性能是区分排序算法好坏的主要因素

以上内容整理于狄泰软件学院系列课程,请大家保护原创!


TianSong
734 声望138 粉丝

阿里山神木的种子在3000年前已经埋下,今天不过是看到当年注定的结果,为了未来的自己,今天就埋下一颗好种子吧