桶排序,基数排序

桶排序

在这里插入图片描述
这里是百度百科桶排序介绍图,排序方法描述就是:对于要排序的目标取值范围在0~n-1的m个数,实例说明,排序3,5,6,1,2,4,3这7个数字,取值在0~9之间;

  1. 首先建立10个桶子,编号分别为0、1、2……9,
  2. 按照这7个数字,把他们分别放到相应编号的桶子中
  3. 从桶子中按顺序收集数据

注明:源数据为按链表排列,每个桶子也是一个链表。
代码如下:


template<class T>
void chain<T>::binSort(int range)
{// Sort the nodes in the chain.
   // create and initialize the bins
   chainNode<T> **bottom, **top;
   bottom = new chainNode<T>* [range + 1];
   top = new chainNode<T>* [range + 1];
   for (int b = 0; b <= range; b++)
      bottom[b] = NULL;

   // 把节点放到箱子中
   // 箱排序是每个箱子往头结点插入
   for (; firstNode != NULL; firstNode = firstNode->next)
   {// add firstNode to proper bin
      int theBin = firstNode->element; // type conversion to int
      if (bottom[theBin] == NULL) // 箱子是空的,直接把插入节点设为头结点

        bottom[theBin] = top[theBin] = firstNode;
      else
      {// bin not empty
        top[theBin]->next = firstNode;
        top[theBin] = firstNode;
      }
   }

   // collect from bins into sorted chain
   // 把箱子中的节点收集到排序的链表中
   chainNode<T> *y = NULL;
   for (int theBin = 0; theBin <= range; theBin++)
      if (bottom[theBin] != NULL)
      {// bin not empty
         if (y == NULL) // first nonempty bin
            firstNode = bottom[theBin];
         else // not first nonempty bin
            y->next = bottom[theBin];
         y = top[theBin];
      }
   if (y != NULL)
      y->next = NULL;
    //把用来排序的箱子空间释放
   delete [] bottom;
   delete [] top;
}

基数排序

基数排序是桶排序的升级版
基数排序是多个桶排序,比如二位数的基数排序,取模10,然后对于个位、十位,有0~9共10个箱子,先按照各位排序,把整个数字放到桶子中,放到桶子中相应位置的编号为该数字的个位数,放进去之后,进行桶排序,结果是一个个位有序,而十位无序的表,然后把该表按照十位为其编号放到桶子中,桶排序,进行收集,之后的结果就是整体有序的数字了。

计算执行步数的话,例如对于取值在0~10^6的1000个数字,如果按照模1000的基数排序,一共需要两次桶排序,每次桶排序共需要1000+1000+1000=3000个步骤,共2*3000=6000
为什么是3000?
1000个桶子初始化->分配1000个整数->从1000个桶子中收集;
因此,如果按照模100的计数排序共需要3*(100+1000+100)=3600个执行步
把数分解为数字需要出发和取模操作。如果用基数10来分解,那么从最低位到最高位的数字分解式为x%10;(x%100)/10;(x%1000)/100;……

template<class T>
int chain<T>::decompose(int value,int range,int time)
{
    if(time == 1)
        return value%range;
    for(int i = 1; i < time; i++)
    {
        range *=10;
    }
    return (value%range)/(range/10);
}
template<class T>
void chain<T>::binSort(int range)
{
    for(int time = 1;time < 3; time++)
    {
        // Sort the nodes in the chain.
        // create and initialize the bins
        chainNode<T> **bottom, **top;
        bottom = new chainNode<T>* [range + 1];
        top = new chainNode<T>* [range + 1];
        for (int b = 0; b <= range; b++)
            bottom[b] = NULL;

        // 把节点放到箱子中
        // 箱排序是每个箱子往头结点插入
        for (; firstNode != NULL; firstNode = firstNode->next)
        {
            // add firstNode to proper bin
            int theBin = decompose(firstNode->element,range,time); // type conversion to int
            if (bottom[theBin] == NULL) // 箱子是空的,直接把插入节点设为头结点

                bottom[theBin] = top[theBin] = firstNode;
            else
            {
                // bin not empty
                top[theBin]->next = firstNode;
                top[theBin] = firstNode;
            }
        }

        // collect from bins into sorted chain
        // 把箱子中的节点收集到排序的链表中
        chainNode<T> *y = NULL;
        for (int theBin = 0; theBin <= range; theBin++)
            if (bottom[theBin] != NULL)
            {
                // bin not empty
                if (y == NULL) // first nonempty bin
                    firstNode = bottom[theBin];
                else // not first nonempty bin
                    y->next = bottom[theBin];
                y = top[theBin];
            }
        if (y != NULL)
            y->next = NULL;
        //把用来排序的箱子空间释放
        delete [] bottom;
        delete [] top;
    }
}
template<class T>
void chain<T>::RadixSort(int range)
{
    // Sort the nodes in the chain
    binSort(range);//对个位进行排序
}

希尔排序

希尔排序
希尔排序就是增量逐渐减少的插入排序,每次通过不同的增量把数据分组,通过增量依次减少,最终是普通的插入排序,因为插入排序在数组基本有序的情况下效率更高

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值