选择排序和插入排序

前言

所谓排序就是计算机内经常进行的一种操作,其目的就是将一组"无序"的数据元素调整为"有序"的数据元素,排序也存在稳定性的定义:如果在序列中有两个数据元素R[i]和R[j],它们的关键字(排序的依据)K[i]==K[j],且在排序之前,对象R[i]排在R[j]前面,如果在排序之后,对象R[i]仍在对象R[j]的前面,则称这个排序方法是最稳定的,否则称这个排序方法是不稳定的,在排序中也有多关键字排序,所谓多关键字排序就是有多个排序依据,且它们的优先级不同,当优先级相同时则看一下关键字,对于多关键字排序,只要在比较操作同时考虑多个关键字和定义好关键字优先级,多关键字和单关键字在排序上是没有本质区别的,排序的两个关键操作就是比较交换
例子

#include <iostream>
#include "object.h"
using namespace std;
using namespace CGSLib;
template <typename T>
class Test
{
   private:
   T key1;
   T key2;
   public:
   Test(T a,T b)
   {
       this->key1 = a;
       this->key2 = b;
   }
   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 (key1<t.key1)||((key1==t.key1)&&(key2<t.key2));
   }
   bool operator <=(const Test& t)
   {
       return !(*this>t);
   }
   bool operator >=(const Test& t)
   {
       return !(*this<t);
   }
};
int main()
{
    Test<int> b(6,4);
    Test<int> c(6,6);
    cout<<(c>b)<<endl;
    return 1;
}

结果:

1

可以看出只要定义好关键字优先级,多关键字排序和单关键字排序没有本质上的区别,排序的时间性能是区分排序算法好坏的主要因素,下面抽象出排序类的基类

#ifndef SORT_H
#define SORT_H
#include "object.h"
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(b);
        a = b;
        b = c;
    }
  public:
    //....
};
#endif // SORT_H

选择排序

基本思想
每次(例如第i次,i = 0,1,…,n-2)从后面n-i个待排的数据元素中选出关键字最小的元素,作为有序元素序列第i个元素,如下图所示有序序列部分在不断增加而无序序列部分在不断减少
在这里插入图片描述
下图是动画演示过程,可见将无序区的数据不断的搬移到有序区最后就形成的有序的状态,可以看出为不稳定排序
在这里插入图片描述在这里插入图片描述
代码演示:

 static void Select(T array[],int len,bool min2max = true)
 {
            int j;
            for(int i=0;i<len;i++)//外层循环确定无序区的起点
            {
                int min = i;
                for(j=i+1;j<len;j++)//内层循环确定无序区的最小值
                {
                    if(min2max?array[min]>array[j]:array[min]<array[j])//根据min2max确定是从小到大,还是从大到小排序
                    {
                        min = j;
                    }
                }
                if(min != ii)//如果min和j不相等则交换,否则如上图中图4,图5一样无须交换
                {
                    Swap(array[i],array[min]);
                }
           }
 }

main.c

#include <iostream>
#include "Sort.h"
using namespace std;
using namespace CGSLib;
int main()
{
    int  array[]={3,1,3,5,2};
    Sort::Select(array,5,false);//从大到小排
    for(int i=0;i<5;i++)
        cout<<array[i]<<endl;
    return 1;
}

结果
在这里插入图片描述

插入排序

基本思想
当插入第i(i>=1)个数据元素时,前面的V[0],V[1],…V[i-1]已经排好序,这时,用V[i]的关键字与V[i-1],V[i-2],…V[0]的关键字进行比较,找到位置后将V[i]插入,原来位置上的对象向后顺移,如下图所示,每次在无序序列区域加入一个元素到有序序列区域的特定位置,并使有序序列依旧有序
在这里插入图片描述
下图是动画演示过程,可以看出刚开始把第一个元素当作有序序列区域的第一个元素,后面不断从无序序列区域移动第一个元素加入到有序序列区域,每一次加入都选择正确的位置插入使其依旧保持有序,简单来说,我们看到第6步,将08从无序序列加入到有序序列时,先将08和49比较,发现49比08大则49后移直到08大于比较数就插入,而且从图中的25可以看出插入排序为稳定排序
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
代码演示

 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;j--)//在有序区域进行插入排序
       {
           if(min2max?array[j]<e:array[i]>e)
           {
               array[j+1] = array[j];
               k = j;//找到插入的位置
           }
           else
           {
              break;
           }
       }
       if(k!=i)//判断是否需要交换
       array[k] = e;//进行插入
    }
}

在这里插入图片描述
插入排序和选择排序都是用两个for循环,所以时间复杂度都为O(n*n)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值