数据结构开发(16):选择排序和插入排序

0.目录

1.排序的基本概念
2.选择排序
3.插入排序
4.小结

1.排序的基本概念

排序的一般定义:

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

1250397-20181220145609034-534195717.png

排序的数学定义:
1250397-20181220145619567-801329120.png

排序的示例:
1250397-20181220145637087-1856762923.png

问题:

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

排序的稳定性:
1250397-20181220145658709-1049613827.png

稳定性排序示例:
1250397-20181220145710773-73394474.png

多关键字排序:

  • 排序时需要比较的关键字多余一个
  • 排序结果首先按关键字1进行排序
  • 关键字1相同时按关键字2进行排序
  • ......
  • 关键字n-1相同时按关键字n进行排序

多关键字排序示例:
1250397-20181220145739446-493633516.png

问题:

  • 多关键字排序是否比单关键字排序更复杂?

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

演示多关键字的比较:

#include <iostream>
#include "Object.h"

using namespace std;
using namespace StLib;

struct Test : public Object
{
    int key1;
    int key2;

    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) : " << (t1 > t2) << endl;
    cout << "(t1 > t3) : " << (t1 > t3) << endl;

    return 0;
}

运行结果为:

(t1 > t2) : 1
(t1 > t3) : 0

排序中的关键操作:

  • 比较
    1. 任意两个数据元素通过比较操作确定先后次序
  • 交换
    1. 数据元素之间需要交换才能得到预期结果

排序的审判:

  • 时间性能
    1. 关键性能差异体现在比较和交换的数量
  • 辅助存储空间
    1. 为完成排序操作需要的额外的存储空间
    2. 必要时可以“空间换时间”
  • 算法的实现复杂性
    1. 过于复杂的排序法可能影响可读性和可维护性

StLib中的排序类设计:
1250397-20181220145905278-755044327.png

定义StLib中的排序类(Sort.h):

#ifndef SORT_H
#define SORT_H

#include "Object.h"

namespace StLib
{

class Sort : public Object
{
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;
    }
public:

};

}

#endif // SORT_H

2.选择排序

选择排序的基本思想:
1250397-20181220145934330-1654883334.png

第 i 次选择排序示例:
1250397-20181220145944755-295529847.png
1250397-20181220145951306-1377811496.png
1250397-20181220145958364-449027608.png

实现选择排序(在Sort.h中):

public:
    template <typename T>
    static void Select(T array[], int len, bool min2max = true)
    {
        for(int i=0; i<len; i++)
        {
            int min = i;

            for(int j=i+1; j<len; j++)
            {
                if( min2max ? (array[min] > array[j]) : (array[min] < array[j]) )
                {
                    min = j;
                }
            }

            if( min != i )
            {
                Swap(array[i], array[min]);
            }
        }
    }

main.cpp测试:

#include <iostream>
#include "Sort.h"

using namespace std;
using namespace StLib;

int main()
{
    int array[] = {3, 1, 2, 5, 4};

    Sort::Select(array, 5);

    for(int i=0; i<5; i++)
    {
        cout << array[i] << endl;
    }

    cout << "~~~" << endl;

    Sort::Select(array, 5, false);

    for(int i=0; i<5; i++)
    {
        cout << array[i] << endl;
    }

    return 0;
}

运行结果为:

1
2
3
4
5
~~~
5
4
3
2
1

3.插入排序

插入排序的基本思想:
1250397-20181220150016904-1150317682.png

第 i 次插入排序示例:
1250397-20181220150027800-424958247.png
1250397-20181220150034115-931435382.png
1250397-20181220150043975-550228758.png
1250397-20181220150051944-1420932246.png

实现插入排序(在Sort.h中):

public:
    template <typename T>
    static void Insert(T array[], int len, bool min2max = true) // 一边比较一边移动
    {
        for(int i=1; i<len; i++)
        {
            int k = i;
            T e = array[i];

            for(int j=i-1; (j>=0) && (min2max ? (array[j]>e) : (array[j]<e)); j--)
            {
                array[j+1] = array[j];
                k = j;
            }

            if( k != i )
            {
                array[k] = e;
            }
        }
    }

mian.cpp测试:

#include <iostream>
#include "Sort.h"

using namespace std;
using namespace StLib;

int main()
{
    int array[] = {3, 1, 2, 5, 4};

    Sort::Insert(array, 5);

    for(int i=0; i<5; i++)
    {
        cout << array[i] << endl;
    }

    cout << "~~~" << endl;

    Sort::Insert(array, 5, false);

    for(int i=0; i<5; i++)
    {
        cout << array[i] << endl;
    }

    return 0;
}

运行结果为:

1
2
3
4
5
~~~
5
4
3
2
1

4.小结

  • 排序是数据元素从无序到有序的过程
  • 排序具有稳定性,是选择排序算法的因素之一
  • 比较和交换是排序的基本操作
  • 多关键字排序与单关键字排序无本质区别
  • 排序的时间性能是区分排序算法好坏的主要因素
  • 选择排序每次选择未排元素中的最小元素
  • 插入排序每次将第 i 个元素插入前面 i-1 个已排元素中
  • 选择排序是不稳定的排序法,插入排序是稳定的排序方法
  • 选择排序和插入排序的时间复杂度为 O(n²)

转载于:https://www.cnblogs.com/PyLearn/p/10150128.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值