数据结构-排序课后题

今天我们来简单的说说关于排序的一些课后练习题.
对应的知识点博客: LINK.

目录

    • 1. 每一单趟都能确定一个数字的最终位置的排序
    • 2. 根据序列变化确定排序方式
    • 3. 排序顺序对哪些排序效率影响不大?
    • 4. 对有序序列排序最费力的排序方式是什么?
    • 5. 对接近有序序列排序最快的排序方式是什么?
    • 6. 最好时间复杂度 与 最坏时间复杂度差异最大的是?
    • 7. 各个排序方式的最坏时间复杂度是多少?
    • 8. 最占空间的排序方式?
    • 9. 各排序方式的时间复杂度
    • 10. 不稳定的排序算法?
    • 11. 快排的特性
    • 12. 三数取中对快排影响的理解
    • 13. 快排的空间复杂度
    • 14. 快排过程
    • 15. 快排的过程
    • 16. 实现一下选择排序
    • 17. 实现一下堆排序
    • 18. 简单实现一下冒泡排序
    • 19. 实现一下快排
    • 20. 实现一下直接插入排序
    • 21. 简单实现以下希尔排序
    • 22. 简单实现归并排序

1. 每一单趟都能确定一个数字的最终位置的排序

在这里插入图片描述
答案: C.
解析:
这个题目选啥呢?
我们挨个选项进行分析.
①: 选择排序, 选择排序每次选一个最值放在一端, 也可以选两个/多个最值… 因此是满足条件的.
②: 归并排序, 归并排序是逐步分割, 分割完之后回归的时候才开始合并的, 而且每次合并的结果并不是最终结果, 因此归并排序不满足条件.
③: 快速排序, 快排每次都选一个关键字, 使得关键字左边比key小, 右边比key小…因此快排是满足条件的.
④: 堆排, 每次堆排都是首尾交换, size–, 因此最后一个数是确定位置的, 因此说堆排也是满足条件的.
综上, 答案是①, ③, ④.

2. 根据序列变化确定排序方式

在这里插入图片描述
答案: D.
解析:
这个挨个根据排序特性去试一下就好了. 直接看快排.
变化过程如下:
在这里插入图片描述

3. 排序顺序对哪些排序效率影响不大?

在这里插入图片描述
答案:B

解析:
快排: 初始顺序影响较大,有序时,性能最差. n*logn -> n^2
插入: 接近有序,性能最好.
希尔:希尔是对插入排序的优化,这种优化是在无序的序列中才有明显的效果,如果序列接近有序,反而是插入最优。
堆排归并,选择对初始顺序不敏感

4. 对有序序列排序最费力的排序方式是什么?

在这里插入图片描述
答案: D
解析: 快排选key, 然后递归很吃亏.

5. 对接近有序序列排序最快的排序方式是什么?

在这里插入图片描述
答案: A
解析: 前面提到过, 归并和堆排以及选择排序对排序效率影响不大. 直接插入排序是对接近有序序列效率最高的了, 希尔排序的话是借用了直接插入排序对接近有序序列排序很高的效率这一想法, 弄了"预排", 希尔排序的作用就是原先直接插入排序对接近有序的序列效率很好, 希尔加入了预排之后, 扩大了插入排序的使用范围, 使的插入排序即使面对不太有序的序列也可以从容应对.

6. 最好时间复杂度 与 最坏时间复杂度差异最大的是?

在这里插入图片描述
答: A.
解析: 快排算是一种非常不稳定的排序. 在大部分情况下都比较快, 效率接近n*logn, 但是在特殊情况下, 效率会达到N^2的一个情况. 比如说对有序序列进行排序.

7. 各个排序方式的最坏时间复杂度是多少?

在这里插入图片描述
答案: A.
解析:
堆排算是一种效率比较稳定的排序, 最好时间复杂度是O(N), 最差时间复杂度是O(NlogN).
快排是一种非常不稳定的排序, 一般情况下效率是O(N
logN), 但是特殊情况下效率是O(NN).
选择排序是一种特别稳定的排序, 稳定到永远是O(N
N)的时间复杂度.
插入排序是一种对数据适应性特别强的排序方式, 如果数据接近有序, 那么效率很高, 如果数据直接逆序, 那么时间复杂度是O(N*N).

8. 最占空间的排序方式?

在这里插入图片描述
答案: A.
解析: 归并在合并的时候, 不是直接在原数据上操作的, 而是申请一块新空间, 在新空间上合并完了再拷贝回去.
为啥不直接再原数组上操作? ①因为不好操作(代码不好写). ②很难控制归并排序的稳定性问题.

9. 各排序方式的时间复杂度

在这里插入图片描述
答案: D.

10. 不稳定的排序算法?

在这里插入图片描述
答案: C.
解析:
首先要理解我们说的排序算法什么是稳定的?
所谓稳定, 就是排序前和排序后尽量使得各个元素前后的相对位置不变.
我们知道, 快排是出了名的不稳定, 包括效率和相对位置. 除此之外, 其他排序稳定性如下:

  • 直接插入一般可以从前向后进行元素的插入,相同元素的相对位置可以不发生变化。
  • 归并也可以保证相对位置不变。
  • 冒泡排序在元素相同的情况下也可以不进行交互,也可以保证稳定。
  • 选择排序的思想是每次选出最值,放在已排序序列的末尾,如果最值有多个,而选出的为最后一个最值,会导致相对位置发生变化。
    当然选择排序也可以变成稳定的,只要保证相同的值选择第一个就可以。

11. 快排的特性

在这里插入图片描述
答案:C
解析:
快排的非递归是在模拟递归的过程,所以时间复杂度并没有本质的变化,但是没有递归,可以减少栈空间的开销。栈和队列都可以实现。这个地方用队列实现快排也可以, 因为队列跟栈的区别就是出入顺序的不同, 对于快排来说, 先后都可以.

12. 三数取中对快排影响的理解

在这里插入图片描述
答案: D.
解析: 见上图.

13. 快排的空间复杂度

在这里插入图片描述
答案: C.
解析: 这里的额外空间大小并不是一个准确的空间值, 这里说的是空间复杂度. 也就是要重点去看思想.
如果是递归算法,所递归的深度大概为二叉树的深度,即logn
如果是非递归算法,需要模拟递归的过程,即需要保存子区间的索引,每次都会成对的保存,最多保存的索引也和二叉树的高度有关:2 * logn
所以空间复杂度为logn

14. 快排过程

在这里插入图片描述
答案: C.
解析: 见上图.

15. 快排的过程

在这里插入图片描述
答案: B
解析:
在这里插入图片描述

16. 实现一下选择排序

// 选择排序
void SelectSort(int* a, int n);

答案:

void SelectSort(int* a, int n)
{int begin = 0;int end = n - 1;// 2.多趟控制 while (begin <= end){// 1.先控制单趟int maxi = begin;int mini = begin;for (int j = begin; j <= end; j++){if (a[maxi] < a[j]) maxi = j;if (a[mini] > a[j]) mini = j;}swap(a[begin], a[mini]);if (maxi == begin) maxi = mini; //更新特殊情况 swap(a[end], a[maxi]);begin++, end--;//PrintArray(a, 12);}
}

17. 实现一下堆排序

// 堆排序
void AdjustDwon(int* a, int n, int root);
void HeapSort(int* a, int n);

答案:

// 假设要升序, 那我们就建立大堆.
void AdjustDwon(int* a, int n, int root)
{int child = 2 * root + 1; //默认是左孩子while (child <= n - 1){if (child + 1 <= n - 1 && a[child + 1] > a[child]){child += 1;}if (a[child] > a[root]){swap(a[child], a[root]);root = child;child = 2 * root + 1;}else break;}
}// 假设要升序, 那我们就建立大堆. 
void HeapSort(int* a, int n)
{// 1.建堆for (int i = (n - 1 - 1) / 2; i >= 0; i--){AdjustDwon(a, n, i);}// 2.首尾交换int end = n - 1;while (end){swap(a[0], a[end]);AdjustDwon(a, end, 0);end--;PrintArray(a, 12);}
}

18. 简单实现一下冒泡排序

// 冒泡排序
void BubbleSort(int* a, int n);

答案:

void BubbleSort(int* a, int n)
{// 控制多趟, 冒多少次? for (int i = 0; i < n - 1; i++){int f = false;// 单趟控制 for (int j = 0; j < n - i - 1; j++){if (a[j] > a[j + 1]){swap(a[j], a[j + 1]);f = true;}}if (!f) break;}
}

19. 实现一下快排

// 快速排序递归实现
// 快速排序hoare版本
int PartSort1(int* a, int left, int right);
// 快速排序挖坑法
int PartSort2(int* a, int left, int right);
// 快速排序前后指针法
int PartSort3(int* a, int left, int right);
void QuickSort(int* a, int left, int right);// 快速排序 非递归实现
void QuickSortNonR(int* a, int left, int right);

答案:

// 快速排序递归实现
// 三数取中
static int getMid(int* arr, int begin, int end)
{int midi = (begin + end) / 2;//找一个较大的值if (arr[begin] < arr[end]) // begin < end{if (arr[midi] < arr[begin]) return begin;else if (arr[midi] > arr[end]) return end;else return midi;}else // end < begin{if (arr[midi] < arr[end]) return end;else if (arr[midi] > arr[begin]) return begin;else return midi;}
}// 快速排序hoare版本
int PartSort1(int* a, int left, int right)
{int l = left;int r = right;int keyi = getMid(a, left, right);swap(a[keyi], a[left]);keyi = left;while (l < r){while (l < r && a[r] >= a[keyi]){r--;}while (l < r && a[l] <= a[keyi]){l++;}swap(a[r], a[l]);}swap(a[r], a[keyi]);keyi = r;return keyi;
}// 快速排序挖坑法
int PartSort2(int* a, int left, int right)
{int holei = getMid(a, left, right);swap(a[holei], a[left]);holei = left;int r = right;int l = left;int hole = a[holei];while (l < r){while (l < r && a[r] >= hole) r--;swap(a[holei], a[r]);holei = r;while (l < r && a[l] <= hole) l++;swap(a[holei], a[l]);holei = l;}a[holei] = hole;return holei;
}
// 快速排序前后指针法
int PartSort3(int* a, int left, int right)
{int keyi = getMid(a, left, right);swap(a[keyi], a[left]);keyi = left;int prev = left;int pcur = left + 1;while (pcur <= right){if (a[pcur] < a[keyi]) swap(a[pcur], a[++prev]);pcur++;}swap(a[prev], a[keyi]);keyi = prev;return keyi;
}void QuickSort(int* a, int left, int right)
{if (right - left + 1 <= 1) return;//int keyi = PartSort1(a, left, right);//int keyi = PartSort2(a, left, right);int keyi = PartSort3(a, left, right);PrintArray(a, 12);QuickSort(a, left, keyi - 1);QuickSort(a, keyi + 1, right);
}// 快速排序 非递归实现
void QuickSortNonR(int* a, int left, int right)
{stack<pair<int, int>> st;st.push({ left, right });// [begin, keyi-1] keyi [keyi+1, end]while (!st.empty()){pair<int, int> t = st.top();st.pop();//int keyi = PartSort1(a, t.first, t.second);//int keyi = PartSort2(a, t.first, t.second);int keyi = PartSort3(a, t.first, t.second);if (((keyi - 1) - t.first) + 1 > 1) st.push({ t.first, keyi - 1 });if ((t.second - (keyi + 1)) + 1 > 1) st.push({ keyi + 1, t.second });}
}

20. 实现一下直接插入排序

static void InsertSort(int* arr, int n)
{// 2.再写整体for (int i = 0; i < n - 1; i++){// 1.先写单趟排序 [0, end] end+1int end_i = i;int t_i = end_i + 1;while (end_i >= 0){// 如果arr[t_i] < arr[end_i], 两者交换if (arr[t_i] < arr[end_i]){swap(arr[t_i], arr[end_i]);end_i--;t_i--;}// 如果arr[t_i] >= arr[end_i], 直接跳出循环即可. else{break;}}PrintArray(arr, n);}
}

21. 简单实现以下希尔排序

static void ShellSort(int* arr, int n)
{// 1.预排int gap = n;while (gap >= 1){// 2.gap == x的情况下, 控制多组直接插入排序for (int i = 0; i < gap; i++){// 3.具体到每一组的一个直接插入排序for (int j = 0 + i; j < n - gap; j+=gap){int end_i = j;int t_i = end_i + gap;// 4. 具体的一个数插入到数组中去while (end_i >= 0){// 如果arr[end_i] <= arr[t_i]if (arr[end_i] <= arr[t_i])break;else{swap(arr[end_i], arr[t_i]);t_i -= gap;end_i -= gap;}}}}printf("gap == %d: ", gap);gap /= 2;PrintArray(arr, n);}
}

22. 简单实现归并排序

static void MergeSort(int* arr, int begin, int end)
{vector<int> v(end - begin + 1);_MergeSort(arr, begin, end, v);
}
static void _MergeSort(int* arr, int begin, int end, vector<int>& v)
{if (begin >= end) return;int midi = (begin + end) / 2;// 递归// [begin, midi] [midi+1, end]_MergeSort(arr, begin, midi, v);_MergeSort(arr, midi + 1, end, v);// 合并int begin1 = begin, end1 = midi;int begin2 = midi + 1, end2 = end;int i = begin;while (begin1 <= end1 && begin2 <= end2){if (arr[begin1] < arr[begin2]) v[i++] = arr[begin1++];else v[i++] = arr[begin2++];}while (begin1 <= end1) v[i++] = arr[begin1++];while (begin2 <= end2) v[i++] = arr[begin2++];// 拷贝赋值for (int i = begin; i <= end; i++){arr[i] = v[i];}
}static void MergeSortNonR(int* a, int n)
{// 1. 开一块空间, 用来合并vector<int> v(n+1);int gap = 1; //每组多少个元素while (gap < n){// 控制所有组的起点for (int i = 0; i < n; i += 2 * gap){int begin1 = i, end1 = i + gap - 1;int begin2 = i + gap, end2 = i + 2 * gap - 1;// [begin1, end1][begin2, end2] 归并// 边界的处理if (end1 >= n || begin2 >= n) break;if (end2 >= n) end2 = n - 1;int j = begin1;int left1 = begin1, right1 = end1;int left2 = begin2, right2 = end2;while (left1 <= right1 && left2 <= right2){if (a[left1] < a[left2]) v[j++] = a[left1++];else v[j++] = a[left2++];}while (left1 <= right1) v[j++] = a[left1++];while (left2 <= right2) v[j++] = a[left2++];for (int k = begin1; k <= end2; k++){a[k] = v[k];}}gap *= 2;}
}

EOF.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/658.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL 架构

MySQL架构 MySQL8.0服务器是由连接池、服务管理⼯具和公共组件、NoSQL接⼝、SQL接⼝、解析器、优化 器、缓存、存储引擎、⽂件系统组成。MySQL还为各种编程语⾔提供了⼀套⽤于外部程序访问服务器的连接器。整体架构图如下所⽰&#xff1a; MySQL Connectors&#xff1a;为使⽤…

【数据结构】二叉搜索树

目录 1. 二叉搜索树的概念 2. 二叉搜索树的性能分析 3.二叉搜索树的实现 3. 1.二叉搜索树的插入 3.2. 二叉搜索树的查找 3.3. 二叉搜索树的删除 3.4. 二叉搜索树的实现代码 4. 二叉搜索树key和key/value两种使用场景 4.1 key搜索场景&#xff1a; 4.2 key/value搜索场…

【C++】string的关系运算与比较分析

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 &#x1f4af;前言&#x1f4af;基础知识&#xff1a;C 中的 string 关系运算器1. 关系运算器概述2. 字符串比较的本质 &#x1f4af;代码解析与扩展代码例一&#xff1a;相等比较代码解析输出 代码例二&a…

高性能网络模式:Reactor 和 Proactor

Reactor Reactor 采用I/O多路复用监听事件&#xff0c;收到事件后&#xff0c;根据事件类型分配给某个进程/线程。 实际应用中用到的模型&#xff1a; 单 Reactor 单进程 单 Reactor 多线程 优点&#xff1a;能充分利用多核CPU性能。 缺点&#xff1a;存在多线程竞争共享资源…

有限元分析学习——Anasys Workbanch第一阶段笔记(10)桌子载荷案例分析_实际载荷与均布载荷的对比

目录 0 序言 1 桌子案例 2 模型简化 3 方案A 前处理 1&#xff09;分析类型选择 2&#xff09;材料加载 3&#xff09;约束、载荷及接触 4&#xff09;控制网格(网格大小需要根据结果不断调整) 初始计算结果 加密后计算结果 4 方案B、C 前处理 1&#xff09;分析…

用HTML + CSS实现太极图

目录 一、效果图 二、实现思路 三、完整代码 四、总结 一、效果图 如图所示&#xff0c;太极图一半为黑色&#xff08;代表阴&#xff09;&#xff0c;另一半为白色&#xff08;代表阳&#xff09;。这两部分相互环绕&#xff0c;形成一种流动的、旋转的感觉。 二、实现思…

【Rust自学】11.7. 按测试的名称运行测试

喜欢的话别忘了点赞、收藏加关注哦&#xff0c;对接下来的教程有兴趣的可以关注专栏。谢谢喵&#xff01;(&#xff65;ω&#xff65;) 11.7.1. 按名称运行测试的子集 如果想要选择运行的测试&#xff0c;就将测试的名称&#xff08;一个或多个&#xff09;作为cargo test的…

标准应用 | 2025年网络安全服务成本度量实施参考

01 网络安全服务成本度量依据相关新变化 为了解决我国网络安全服务产业发展中面临的服务供需两方对于服务成本组成认知偏差较大、网络安全服务成本度量缺乏依据的问题&#xff0c;中国网络安全产业联盟&#xff08;CCIA&#xff09;组织北京赛西科技发展有限责任公司、北京安…

HAMi + prometheus-k8s + grafana实现vgpu虚拟化监控

最近长沙跑了半个多月&#xff0c;跟甲方客户对了下项目指标&#xff0c;许久没更新 回来后继续研究如何实现 grafana实现HAMi vgpu虚拟化监控&#xff0c;毕竟合同里写了需要体现gpu资源限制和算力共享以及体现算力卡资源共享监控 先说下为啥要用HAMi吧&#xff0c; 一个重要原…

某地武警海警总队建筑物自动化监测

1. 项目概述 该项目分布于三个不同的地级市&#xff0c;都是位于临海港口的码头&#xff0c;由中国武警海警总队驻扎&#xff0c;守卫人民安全。 1号建筑物自动化监测系统项目由一道伸缩缝划分为两个监测单元&#xff0c;建筑物为三层混合结构&#xff0c;采用350mm厚石墙、2…

负载均衡原理及算法

什么是负载均衡&#xff1f; 负载均衡 指的是将用户请求分摊到不同的服务器上处理&#xff0c;以提高系统整体的并发处理能力以及可靠性。负载均衡服务可以有由专门的软件或者硬件来完成&#xff0c;一般情况下&#xff0c;硬件的性能更好&#xff0c;软件的价格更便宜&#x…

Windows 下Mamba2 / Vim / Vmamba 环境安装问题记录及解决方法终极版(无需绕过triton)

导航 安装教程导航 Mamba 及 Vim 安装问题参看本人博客&#xff1a;Mamba 环境安装踩坑问题汇总及解决方法&#xff08;初版&#xff09;Linux 下Mamba 及 Vim 安装问题参看本人博客&#xff1a;Mamba 环境安装踩坑问题汇总及解决方法&#xff08;重置版&#xff09;Windows …

LLMs之VDB:LanceDB的简介、安装和使用方法、案例应用之详细攻略

LLMs之VDB&#xff1a;LanceDB的简介、安装和使用方法、案例应用之详细攻略 目录 LanceDB的简介 1、LanceDB的主要特性 2、为何选择 LanceDB&#xff1f; LanceDB的安装和使用方法 1、安装方法 Javascript/Typescript Python 2、使用方法 Javascript Python LanceDB…

《拉依达的嵌入式\驱动面试宝典》—计算机网络篇(二)

《拉依达的嵌入式\驱动面试宝典》—计算机网络篇(二) 你好,我是拉依达。 感谢所有阅读关注我的同学支持,目前博客累计阅读 27w,关注1.5w人。其中博客《最全Linux驱动开发全流程详细解析(持续更新)-CSDN博客》已经是 Linux驱动 相关内容搜索的推荐首位,感谢大家支持。 《…

Java面试核心知识4

公平锁与非公平锁 公平锁&#xff08;Fair&#xff09; 加锁前检查是否有排队等待的线程&#xff0c;优先排队等待的线程&#xff0c;先来先得 非公平锁&#xff08;Nonfair&#xff09; 加锁时不考虑排队等待问题&#xff0c;直接尝试获取锁&#xff0c;获取不到自动到队尾…

探索AGI:智能助手与自我赋能的新时代

目录 1 AGI1.1 DeepMind Levels&#xff08;2023年11月)1.2 OpenAI Levels&#xff08;2024年7月&#xff09;1.3 对比与总结1.4 AGI可能诞生哪里 2 基于AI的智能自动化助手2.1 通用型大模型2.2 专业的Agent和模型工具开发框架2.3 编程与代码生成助手2.4 视频和多模态生成2.5 商…

python迷宫寻宝 第4关 自动寻路(找宝箱、宝石、终点、获取企鹅信息)

目录 地图 ​编辑 1、成功获取粉宝石或黄宝石。 2、获取企鹅的信息 3、获取红宝石 (1)api.get.item获取红宝石 (2)context.items获取红宝石 4、获取宝箱 &#xff08;1&#xff09;api.get.item获取宝箱 &#xff08;2&#xff09;context.items获取宝箱 5、达到终点 …

慧集通(DataLinkX)iPaaS集成平台-业务建模之业务对象(二)

3.UI模板 当我们选择一条已经建好的业务对象点击功能按钮【UI模板】进入该业务对象的UI显示配置界面。 右边填写的是UI模板的编码以及对应名称&#xff1b;菜单界面配置以业务对象UI模板编码获取显示界面。 3.1【列表-按钮】 展示的对应业务对象界面的功能按钮配置&#xff1…

PyCharm 引用其他路径下的文件报错 ModuleNotFound 或报红

PyCharm 中引用其他路径下的文件提示 ModuleNotFound&#xff0c;将被引用目录添加到系统路径&#xff1a; # # 获取当前目录 dir_path os.path.dirname(os.path.realpath(__file__)) # # 获取上级目录 parent_dir_path os.path.abspath(os.path.join(dir_path, os.pardir))…

mysql本地安装和pycharm链接数据库操作

MySQL本地安装和相关操作 Python相关&#xff1a;基础、函数、数据类型、面向、模块。 前端开发&#xff1a;HTML、CSS、JavaScript、jQuery。【静态页面】 Java前端&#xff1b; Python前端&#xff1b; Go前端 -> 【动态页面】直观&#xff1a; 静态&#xff0c;写死了…