数据结构与算法之箱子排序 (链表描述)

      问题描述:假定用一个链表保存一个班级学生的清单,每个节点的数据域有学生姓名和分数。我们需要对学生们的分数进行排序,其中n为学生总数,箱子排序的思想是首先将分数相同的节点放在同一个箱子里,然后将箱子连接起来就得到有序的链表。

      假设分数介于0-5之间,则需要6个箱子,每个箱子对应一个分数。每一个箱子都是一个链表。一个箱子的节点数介于0-n之间,n为总人数。开始时,所有的箱子全部是空的。

解决方案:

  1. 逐个删除输入链表的节点,将删除的节点分配到对应的箱子里面去
  2. 将每一个箱子中的链表收集并连接起来,并使之成为一个有序的链表

用于箱子排序的链表元素结构

struct studentRecord
{
  
int score;
string* name;
int operator != (const studentRecord &x) const
{
return (score != x.score);
}

};

ostream & operator<<(ostream & out, const studentRecord &x)
{
  out<<x.score<<' '<<*x.name<<endl;
 return out;

}

     使用链表的方法进行箱子排序

void binSort(Chain<studentRecord> & theChain, int range)
{
  //按分数排序
  //对箱子进行初始化
  Chain<studentRecord> *bin;
  bin = new chain<studentRecord>[range+1];   //每个箱子的容量需要比range多一
  
  //将分数进行装箱操作,从输入链表的首部拿节点,然后删除首节点
  int numberOfElements = theChain.size();
  for(int i=1;i<=nummberOfElements;i++)
  {
    studentRecord x = theChain.Get(0);   //取首节点数据
    theChain.erase(0);  //擦除首节点
    bin[x.score].insert(0,x);   //装箱
  }

  //从箱子中收集数据
  for(int j=range;j>=0;j--)
  {
   while(!bin[j].empty())
   {
     studentRecord x = bin[j].get(0); //取数据
     bin[j].erase(0);    //取完擦出首部节点
     theChain.insert(0,x);  //插入到theChain链表中
       
   }
  }

  delete[] bin;
  
}

           附链表Chain节点的结构定义

template<class T>
class chain
{
  public:
     //构造函数,复制构造函数和析构函数
     chain(int initialCapacity =10);
     chain(const chain<T> &x);
     ~chain();
     //相关方法
     bool empty() const {return listSize ==0 ;}
     int size() const{ return listSize;}
     T& get(int index) const;
     void erase(int index);
     void insert(int index, const T& x);
  protected:
     chainNode<T> *firstNode;  //指向链表第一个节点的指针
     int listSize;  //链表元素个数
};


template<class T>
struct chainNode
{
  //数据成员
  T element;
  chainNode<T> *next;
  
  //方法
  chainNode(){}
  chainNode(const T& element)
  { this->element = element;}
  chainNode(const T& element, chain<T> *next)
  {
    this->element = element;
    this->next = next;
  }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值