【数据结构】-箱子排序

What

箱子排序是在链表的基础上进行排序,首先把值相同的节点,放在同一个箱子中,然后把箱子链接起来就得到了有序的链表。

Why:

箱子排序算法的时间复杂度基本保持在Θ(n+2*range),在特殊的场景中有非常好的效果(我不信,因为他排序的数据必须是整型,且如果要对0-999内的10个数进行箱子排序,则至少需要1000个箱子,即range=1000,时间复杂度瞬间升高)。

How:

假设班级里有30个人马上就业毕业了,每个人的本科学生信息表里有一项四学年成绩平均值(中国称为绩点,这里强制它为整数),学校要根据这项数据对这30人进行排名,采用箱子排序。(1)先定义两个数组(bottom[ ]和top[ ]),大小为成绩的最大值,假设全班最高分为100,则数组就有100个。(2)每个箱子都有两个指针,存放在bottom[ ]和top[ ]中,其中bottom[theBin]指向箱子theBin的首节点,top[theBin]指向箱子theBin的尾节点。(3)遍历链表,将数值相同的节点放到一个箱子中,并及时更新bottom和top两个指针,使箱子内形成一个有序链表。(4)链接箱子,根据箱子的标号将所有箱子链接起来。

下面的代码是将箱子排序作为链表的一个成员函数。

struct studentGrade
{
    string name;
    int grade;
    operator int() const{return grade;}
    int operator !=(const studentGrade& x)const
    {return (grade!=x.grade);}
};

template<class T>
void chainList<T>::binSort(int range)
{
    chainList<T> **bottom,**top;
    bottom = new chainNode<T> *[range+1];
    top = new chainNode<T>* [range+1];

    for(int i=0;i<=range;i++)
    {
        bottom[i]=nullptr;
    }
    for(;fristNode!=nullptr;fristNode=fristNode->next)
    {
        int theBin = fristNode->element;
        if(bottom[theBin]==nullptr)
        {
            bottom[theBin]= top[theBin]=fristNode;
        }
        else
        {
            top[theBin]->next=fristNode;
            top[theBin]=fristNode;
        }
    }
    chainNode<T>* y=nullptr;
    for(int i=0;i<=range;i++)
    {
        if(bottom[i]!=nullptr)
        {
            if(fristNode==nullptr)
            {
                fristNode=bottom[i];
            }
            else
            {
                y->next=bottom[i];
            }
            y=top[i];
        }
    }
    if(y!=nullptr)
    {
        y->next=nullptr;
    }
    delete []bottom;
    delete []top;
}

时间性能分析:

箱子初始化阶段->Θ(range);

箱子分配阶段->Θ(n);

箱子链接阶段->Θ(range);

总的时间性能分析Θ(n+range);

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值