【算法】C++用链表实现一个箱子排序附源代码详解

01 箱子排序

1.1 什么是分配排序?

分配排序的基本思想:排序过程无须比较关键字,而是通过"分配"和"收集"过程来实现排序.它们的时间复杂度可达到线性阶:O(n)。

1.2 什么是箱子排序?

箱子排序是分配排序的一种,箱子排序也称桶排序(Bucket Sort),其基本思想是:设置若干个箱子,依次扫描待排序的记录 R[0],R[1],…,R[n-1],把关键字等于 k 的记录全都装入到第 k 个箱子里(分配),然后按序号依次将各非空的箱子首尾连接起来(收集)。

比如,要将一个班的同学按分数排序,分数范围是0-100分。需设置 101 个"箱子"(R[0],R[1],…,R[100]),排序时依次将每个同学按分数放入相应的箱子里,然后依次将这些箱子首尾相接,就得到了按分数递增序排列的一个班的同学。

1.3 关于箱子个数

箱排序中,箱子的个数取决于关键字的取值范围。

若关键字的取值范围是0到m-1的整数,则必须设置 m 个箱子。因此箱排序要求关键字的类型是有限类型,否则可能要无限个箱子。

02 链表实现箱子排序

一般情况下每个箱子中存放多少个关键字相同的记录是无法预料的,故箱子的类型应设计成链表为宜。

我们现在来讲解一个简单的例子,以便来让大家更好了解这个过程。

2.1 example

下面是一个学生链表。为了更好说明问题,我们简化了学生的存储结构。每个学生节点保存一个字符,表示学生的姓名,再存一个数字,表示学生的分数。分数范围为0-5。

2.2 箱子排序的步骤

有了上面的输入链表以后。我们采用以下步骤进行箱子排序:
1) 逐个删除输入链表的节点,然后把删除的节点分配到相应的箱子中。

2) 把每个箱子中的元素收集并链接起来,使其成为一个有序链表。

比如上面的输入链表,我们要做的是:
1) 连续删除链表的首元素,并将其插入到相对应箱子的链表头部。

2) 从最后一个箱子开始,逐个删除每个箱子的元素,并将其插入一个初始为空的链表的头部。

如下图所示:

那么排序好的链表如下:

03 动手写代码

3.1 studentRecord结构体

先来看看代码:

 1struct studentRecord
2{

3    int score;
4    string name;
5
6    studentRecord() {}
7    studentRecord(int theScore, string theName) :score(theScore), name(theName) {}
8
9    int operator != (const studentRecord & x) const
10    {
11        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是用 C++ 链表实现多项式相加的源代码,带有详细的注释: ```c++ #include <iostream> using namespace std; // 定义一个链表节点 struct Node { int coef; // 系数 int exp; // 指数 Node *next; // 指向下一个节点的指针 Node(int c, int e) : coef(c), exp(e), next(NULL) {} // 构造函数 }; // 定义多项式类 class Polynomial { private: Node *head; // 多项式链表的头节点 public: Polynomial() : head(NULL) {} // 构造函数,初始化头节点为 NULL ~Polynomial() { // 析构函数,释放链表内存 Node *p = head; while (p) { Node *q = p; p = p->next; delete q; } } void addTerm(int c, int e) { // 向多项式中添加一项 if (c == 0) return; // 如果系数为 0,不添加 Node *p = head, *q = NULL; while (p && p->exp > e) { // 找到合适的插入位置 q = p; p = p->next; } if (p && p->exp == e) { // 如果已经有相同指数的项,系数相加 p->coef += c; if (p->coef == 0) { // 如果系数为 0,删除该节点 if (q) q->next = p->next; else head = p->next; delete p; } } else { // 否则插入新节点 Node *newNode = new Node(c, e); if (q) q->next = newNode; else head = newNode; newNode->next = p; } } Polynomial operator+(const Polynomial &other) const { // 重载加法运算符 Polynomial res; Node *p1 = head, *p2 = other.head; while (p1 != NULL && p2 != NULL) { // 遍历两个多项式链表 if (p1->exp > p2->exp) { // 如果第一个链表的指数大,将第一个链表的节点加入结果链表 res.addTerm(p1->coef, p1->exp); p1 = p1->next; } else if (p1->exp < p2->exp) { // 如果第二个链表的指数大,将第二个链表的节点加入结果链表 res.addTerm(p2->coef, p2->exp); p2 = p2->next; } else { // 如果两个链表的指数相同,将它们的系数相加 int sum = p1->coef + p2->coef; res.addTerm(sum, p1->exp); p1 = p1->next; p2 = p2->next; } } // 将剩余的节点加入结果链表 while (p1 != NULL) { res.addTerm(p1->coef, p1->exp); p1 = p1->next; } while (p2 != NULL) { res.addTerm(p2->coef, p2->exp); p2 = p2->next; } return res; } void print() const { // 输出多项式 Node *p = head; if (p == NULL) { // 如果链表为空,输出 0 cout << "0" << endl; return; } while (p) { if (p->coef > 0 && p != head) cout << "+"; // 系数为正,输出 "+" cout << p->coef; if (p->exp > 0) cout << "x^" << p->exp; // 指数大于 0,输出 "x^exp" p = p->next; } cout << endl; } }; int main() { Polynomial p1, p2, p3; p1.addTerm(2, 3); p1.addTerm(1, 2); p1.addTerm(3, 1); p1.addTerm(4, 0); p2.addTerm(1, 4); p2.addTerm(2, 3); p2.addTerm(-3, 2); p2.addTerm(2, 1); p2.addTerm(1, 0); p3 = p1 + p2; p1.print(); p2.print(); p3.print(); return 0; } ``` 以上代码实现了多项式相加的功能,其中 Node 结构体表示链表节点,Polynomial 类表示多项式,addTerm 方法用于向多项式中添加一项,operator+ 方法重载了加法运算符,print 方法用于输出多项式。在 main 函数中,我们定义了两个多项式 p1 和 p2,并将它们相加得到 p3,最后输出三个多项式的结果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值