当前位置: 首页 > article >正文

C++学习笔记(34)

三十六、队列
示例:
#include <iostream>
using namespace std;
typedef int ElemType; // 自定义队列的数据元素为整数。
struct LNode
{
ElemType data; // 存储队列中的元素。
struct LNode* next; // next 指针。
};
struct LinkQueue
{
LNode* head,*tail; // 队列的头指针和尾指针。
};
// 初始化队列。
bool InitQueue(LinkQueue& QQ)
{
QQ.head = new (std::nothrow) LNode; // 分配头结点。
if (QQ.head == nullptr) return false; // 内存不足,返回失败。
QQ.head->next = nullptr; // 头结点的下一结点暂时不存在,置空。
QQ.tail = QQ.head; // 尾指针指向头结点。
return true;
}
// 销毁队列 QQ。
void DestroyQueue(LinkQueue& QQ)
{
LNode* tmp;
while (QQ.head != nullptr)
{
tmp = QQ.head->next; // tmp 保存下一结点的地址。
delete QQ.head; // 释放当前结点。
QQ.head = tmp; // 指针移动到下一结点。
}
}
// 元素入队。
bool InQueue(LinkQueue& QQ, const ElemType& ee)
{
if (QQ.head == nullptr) { cout << "队列未初始化。\n"; return false; }
LNode* tmp = new (std::nothrow) LNode; // 分配一个新结点。
if (tmp == nullptr) return false;
tmp->data = ee; // 把元素的值存入新结点。
tmp->next = nullptr;
QQ.tail->next = tmp; // 把 tmp 追加到 QQ.tail 之后。
QQ.tail = tmp; // 重新设置 tail 指针。
return true;
}
// 元素出队。
bool OutQueue(LinkQueue& QQ, ElemType& ee)
{
if (QQ.head == nullptr) { cout << "队列未初始化。\n"; return false; }
if (QQ.head->next == nullptr) { cout << "队列为空。\n"; return false; }
LNode* tmp = QQ.head->next; // tmp 指向第一个结点。
ee = tmp->data; // 把第一个结点的数据保存到 ee 中。
QQ.head->next = tmp->next; // 头结点的 next 指针指向第二个结点。
// 如果出队的是最后一个结点。
if (tmp == QQ.tail) QQ.tail = QQ.head;
delete tmp; // 释放已出队的结点。
return true;
}
// 显示队列中全部的元素。
void PrintQueue(LinkQueue& QQ)
{
if (QQ.head == nullptr) { cout << "队列未初始化。\n"; return ; }
LNode* pp = QQ.head->next; // 从第 1 个数据结点开始。
while (pp != NULL)
{
cout << pp->data << " " ;
pp = pp->next;
}
cout << endl;
}
// 求队列的长度。
int Length(LinkQueue& QQ)
{
if (QQ.head == nullptr) { cout << "队列未初始化。\n"; return false; }
LNode* pp = QQ.head->next; // 头结点不算,从第 1 个结点开始。
int length = 0;
while (pp != nullptr) { pp = pp->next; length++; }
return length;
}
// 清空队列。
void Clear(LinkQueue& QQ)
{
if (QQ.head == nullptr) { cout << "队列未初始化。\n"; return; }
// 清空队列是指释放链表全部的数据结点,但保留头结点。
LNode* tmp = QQ.head->next, * tmpnext;
while (tmp != nullptr)
{
tmpnext = tmp->next; // tmpnext 保存下一结点的地址。
delete tmp; // 释放当前结点。
tmp = tmpnext; // tmp 指针移动到下一结点。
}
QQ.head->next = nullptr;
QQ.tail = QQ.head; // 尾指针指向头结点。
}
int main()
{
LinkQueue QQ; // 创建队列。
memset(&QQ, 0, sizeof(QQ));
InitQueue(QQ); // 初始化队列。
cout << "元素(1、2、3、4、5)入队。\n";
InQueue(QQ, 1);
InQueue(QQ, 2);
InQueue(QQ, 3);
InQueue(QQ, 4);
InQueue(QQ, 5);
cout << "队列的长度是:" << Length(QQ) << "。\n";
cout << "队列中的元素是:";
PrintQueue(QQ);
ElemType ee; // 创建一个数据元素。
while (OutQueue(QQ, ee))
cout << "出队的元素值为" << ee << endl;
cout << "元素(11、12、13、14、15)入队。\n";
InQueue(QQ, 11);
InQueue(QQ, 12);
InQueue(QQ, 13);
InQueue(QQ, 14);
InQueue(QQ, 15);
cout << "队列的长度是:" << Length(QQ) << "。\n";
cout << "队列中的元素是:";
PrintQueue(QQ);
while (OutQueue(QQ, ee))
cout << "出队的元素值为" << ee << endl;
DestroyQueue(QQ); // 销毁队列 QQ。
}
四十、冒泡排序
示例:
#include <iostream>
using namespace std;
// 采用两层循环实现的方法。
// 参数 arr 是待排序数组的首地址,len 是数组元素的个数。
void bubblesort1(int arr[], int len)
{
if (len < 2) return; // 数组小于 2 个元素不需要排序。
bool ifswap=false; // 记录每轮排序过程中是否交换过元素,false-未交换;true-有交换。
// 44,3,38,5,47,15,36,26,27,2,46,4,19,50,48
for (int ii = len - 1; ii > 0; ii--) // 一共进行 len-1 趟比较。
{
ifswap = false;
for (int jj = 0; jj < ii; jj++) // 每轮只需要比较 0......ii 之间的元素,ii 之后的元素是
已经排序好的。
{
if (arr[jj] > arr[jj + 1]) // 如果前面的元素大于后面的元素,则交换它位的
位置。
{
swap(arr[jj], arr[jj + 1]); // 交换两个元素的位置。
ifswap = true;
}
}
if (ifswap == false) return; // 如果这一轮没有交换过元素,说明数组已经是有序的
了。
}
}
// 采用递归实现的方法。
// 参数 arr 是待排序数组的首地址,len 是数组元素的个数。
void bubblesort2(int arr[], int len)
{
if (len < 2) return; // 数组小于 2 个元素不需要排序。
bool ifswap = false; // 记录每轮排序过程中是否交换过元素,false-未交换;true-有交换。
for (int jj = 0; jj < len - 1; jj++) // 每趟只需要比较 0......len-1 之间的元素,len-1 之后的元
素是已经排序好的。
{
if (arr[jj] > arr[jj + 1]) // 如果前面的元素大于后面的元素,则交换它位的
位置。
{
swap(arr[jj], arr[jj + 1]); // 交换两个元素的位置。
ifswap = true;
}
}
if (ifswap == false) return; // 如果这一轮没有交换过元素,说明数组已经是有序的了。
bubblesort2(arr, --len);
}
int main(int argc, char* argv[])
{
int arr[] = { 44,3,38,5,47,15,36,26,27,2,46,4,19,50,48 }; // 待排序的数组。
int len = sizeof(arr) / sizeof(int); // 求数组长度。
//bubblesort1(arr, len); // 采用循环的方法。
bubblesort2(arr, len); // 采用递归的方法。
// 显示排序结果。
for (int ii = 0; ii < len; ii++) cout << arr[ii] << " ";
cout << endl;
}
四十一、选择排序
示例(未优化):
#include <iostream>
using namespace std;
// 采用两层循环实现的方法。
// 参数 arr 是待排序数组的首地址,len 是数组元素的个数。
void selectsort1(int arr[], int len)
{
if (len < 2) return; // 数组小于 2 个元素不需要排序。
int iminpos; // 每趟循环选出的最小值的位置(数组的下标)。
// 44,3,38,5,47,15,36,26,27,2,46,4,19,50,48
for (int ii = 0; ii < len - 1; ii++) // 一共进行 len-1 趟比较。
{
iminpos = ii;
for (int jj = ii + 1; jj < len; jj++) // 每趟只需要比较 ii+1......len-1 之间的元素,ii 之前的
元素是已经排序好的。
{
// 找出值更小的元素,记下它的位置。
if (arr[jj] < arr[iminpos]) iminpos = jj;
}
// 如果本趟循环的最小的元素不是起始位置的元素,则交换它们的位置。
if (iminpos != ii) swap(arr[ii], arr[iminpos]);
}
}
// 采用递归实现的方法。
// 参数 arr 是待排序数组的首地址,len 是数组元素的个数。
void selectsort2(int arr[], int len)
{
if (len < 2) return; // 数组小于 2 个元素不需要排序。
int iminpos = 0; // 每趟循环选出的最小值的位置(数组的下标)。
for (int ii = 1; ii < len; ii++)
{
// 找出值更小的元素,记下它的位置。
if (arr[ii] < arr[iminpos]) iminpos = ii;
}
// 如果本趟循环的最小的元素不是起始位置的元素,则交换它们的位置。
if (iminpos != 0) swap(arr[0], arr[iminpos]);
selectsort2(arr + 1, --len);
}
int main(int argc, char* argv[])
{
int arr[] = { 44,3,38,5,47,15,36,26,27,2,46,4,19,50,48 }; // 待排序的数组。
int len = sizeof(arr) / sizeof(int); // 求数组长度。
selectsort1(arr, len); // 采用循环的方法。
//selectsort2(arr, len); // 采用递归的方法。
// 显示排序结果。
for (int ii = 0; ii < len; ii++) cout << arr[ii] << " ";
cout << endl;
}
示例(优化后):
#include <iostream>
using namespace std;
// 采用两层循环实现的方法。
// 参数 arr 是待排序数组的首地址,len 是数组元素的个数。
void selectsort1(int arr[], int len)
{
if (len < 2) return; // 数组小于 2 个元素不需要排序。
int ileft, iright; // 每趟排序的最左和最右的位置。
int iminpos; // 每趟循环选出的最小值的位置(数组的下标)。
int imaxpos; // 每趟循环选出的最大值的位置(数组的下标)。
ileft = 0; iright = len - 1; // ileft 从 0 开始,iright 从 len-1 开始。
while (ileft < iright)
{
iminpos = imaxpos = ileft;
for (int ii = ileft; ii <= iright; ii++) // 每趟循环从 ileft 和 iright 之间选取元素。
{
// 找出值更小的元素,记下它的位置。
if (arr[ii] < arr[iminpos]) iminpos = ii;
// 找出值更大的元素,记下它的位置。
if (arr[ii] > arr[imaxpos]) imaxpos = ii;
}
// 如果本趟循环的最小的元素不是最左边的元素,则交换它们的位置。
if (iminpos != ileft) swap(arr[ileft], arr[iminpos]);
// 如果 imaxpos 的位置是 ileft,在上面的代码中 ileft 已被交换到了 iminpos 的位置。
// 所以 imaxpos 的值要修改为 iminpos。
if (imaxpos == ileft) imaxpos = iminpos;
// 如果本趟循环的最大的元素不是最右边的元素,则交换它们的位置。
if (imaxpos != iright) swap(arr[iright], arr[imaxpos]);
ileft++;
iright--;
}
}
// 采用递归实现的方法。
// 参数 arr 是待排序数组的首地址,len 是数组元素的个数。
void selectsort2(int arr[], int len)
{
if (len < 2) return;
int iminpos = 0; // 每趟循环选出的最小值的位置(数组的下标)。
int imaxpos = 0; // 每趟循环选出的最大值的位置(数组的下标)。
int ileft = 0;
int iright = len - 1;
for (int ii = ileft; ii <= iright; ii++) // 循环从 ileft 和 iright 之间选取元素。
{
// 找出值更小的元素,记下它的位置。
if (arr[ii] < arr[iminpos]) iminpos = ii;
// 找出值更大的元素,记下它的位置。
if (arr[ii] > arr[imaxpos]) imaxpos = ii;
}
// 如果本趟循环的最小的元素不是最左边的元素,则交换它们的位置。
if (iminpos != ileft) swap(arr[ileft], arr[iminpos]);
// 如果 imaxpos 的位置是 ileft,在上面的代码中 ileft 已被交换到了 iminpos 的位置。
// 所以 imaxpos 的值要修改为 iminpos。
if (imaxpos == ileft) imaxpos = iminpos;
// 如果本趟循环的最大的元素不是最右边的元素,则交换它们的位置。
if (imaxpos != iright) swap(arr[iright], arr[imaxpos]);
len = len - 2;
selectsort2(++arr, len);
}
int main(int argc, char* argv[])
{
int arr[] = { 44,3,38,5,47,15,36,26,27,2,46,4,19,50,48 }; // 待排序的数组。
int len = sizeof(arr) / sizeof(int); // 求数组长度。
selectsort1(arr, len); // 采用循环的方法。
//selectsort2(arr, len); // 采用递归的方法。
// 显示排序结果。
for (int ii = 0; ii < len; ii++) cout << arr[ii] << " ";
cout << endl;
}
四十二、插入排序
示例:
#include <iostream>
using namespace std;
// 参数 arr 是待排序数组的首地址,len 是数组元素的个数。
void insertsort(int arr[], int len)
{
if (len < 2) return; // 数组小于 2 个元素不需要排序。
int itmp; // 当前需要排序的元素的值。
for (int ii = 1; ii < len; ii++) // ii 从 1 开始,因为第一个元素不需要排序,就像拿到第一张
牌一样。
{
itmp = arr[ii]; // 待排序元素。
// 从已排序元素的最右边开始,把大于当前排序的元素后移。
int jj; // 需要后移元素的计数器。
for (jj = ii - 1; jj >= 0; jj--)
{
if (arr[jj] <= itmp) break;
arr[jj + 1] = arr[jj]; // 逐个元素后移。
}
arr[jj + 1] = itmp; // 插入当前排序元素。
}
}
int main(int argc, char* argv[])
{
int arr[] = { 44,3,38,5,47,15,36,26,27,2,46,4,19,50,48 }; // 待排序的数组。
int len = sizeof(arr) / sizeof(int); // 求数组长度。
insertsort(arr, len);
// 显示排序结果。
for (int ii = 0; ii < len; ii++) cout << arr[ii] << " ";
cout << endl;
}
 


http://www.kler.cn/a/321033.html

相关文章:

  • MySQL初学之旅(3)约束
  • CentOS7.9 源码编译 FreeSWITCH 1.10.12
  • SpringBoot 2.2.10 无法执行Test单元测试
  • uniapp h5地址前端重定向跳转
  • 基于VUE实现语音通话:边录边转发送语言消息、 播放pcm 音频
  • flutter pigeon gomobile 插件中使用go工具类
  • 【MySQL】字符集与Collation
  • MySQL 预处理语句:强大的数据库工具
  • en造数据结构与算法C# 用Unity实现简单的群组行为算法 之 分散
  • 运算符两边的数据类型
  • [数据库] Redis学习笔记(一):介绍、安装、基本数据结构、常见命令
  • 在Windows系统上安装的 zstd C++ 库
  • ADB 安装教程:如何在 Windows、macOS 和 Linux 上安装 Android Debug Bridge
  • Spring 事务与 MySQL 事务:深度解析与实战指南
  • 使用docker创建zabbix服务器
  • 2024华为杯E题成品文章已出!
  • 使用Crawler实例进行网页内容抓取
  • 制造企业为何需要PLM系统?PLM系统解决方案对制造业重要性分析
  • Python Web 分布式系统性能监控与链路追踪技术解析
  • vue实现鼠标滚轮控制页面横向滑动
  • 你知道吗?制造手机芯片的关键竟然是一台“打印机”?
  • Redis配置文件详解(上)
  • 【报告阅读】chatgpt-o1 技术报告阅读 | 新的迭代开始了~
  • 大数据新视界 --大数据大厂之数据清洗工具 OpenRefine 实战:清理与转换数据
  • Java 入门指南:获取对象的内存地址
  • 美信监控易的优势:长期稳定运行