数据结构与C++ 知识量:9 - 32 - 91
归并排序(Merge Sort)是一种分治策略的排序算法,它将一个无序数组分成两个子数组,对子数组递归地进行排序,然后将有序的子数组合并成一个有序的数组。
以下是使用C++实现归并排序的代码:
#include <iostream> #include <vector> using namespace std; void merge(vector<int>& arr, int left, int mid, int right) { vector<int> temp(right - left + 1); // 创建临时数组 int i = left, j = mid + 1, k = 0; // i指向左子数组的起始位置,j指向右子数组的起始位置,k指向临时数组的起始位置 // 合并左右子数组到临时数组 while (i <= mid && j <= right) { if (arr[i] <= arr[j]) { temp[k++] = arr[i++]; } else { temp[k++] = arr[j++]; } } // 将剩余元素复制到临时数组中 while (i <= mid) { temp[k++] = arr[i++]; } while (j <= right) { temp[k++] = arr[j++]; } // 将临时数组中的元素复制回原数组中 for (int p = 0; p < temp.size(); p++) { arr[left + p] = temp[p]; } } void mergeSort(vector<int>& arr, int left, int right) { if (left < right) { int mid = left + (right - left) / 2; // 计算中间位置 mergeSort(arr, left, mid); // 递归地对左右子数组进行排序 mergeSort(arr, mid + 1, right); // 递归地对左右子数组进行排序 merge(arr, left, mid, right); // 合并左右子数组 } } int main() { vector<int> arr = {5, 2, 9, 1, 5, 6}; mergeSort(arr, 0, arr.size() - 1); for (int i = 0; i < arr.size(); i++) { cout << arr[i] << " "; } cout << endl; return 0; }
多关键码排序是指使用多个关键码进行排序的方法。在处理实际问题时,一个对象可能包含多个属性,这些属性都可能影响对象的排序。为了得到更准确、更符合实际需求的排序结果,可以使用多关键码排序。
多关键码排序的基本思想是将多个关键码组合成一个优先级序列,然后按照优先级序列的顺序对对象进行比较和排序。在比较过程中,先按照优先级最高的关键码进行比较,如果两个对象在该关键码上的值相等,则继续按照下一个关键码进行比较,以此类推,直到比较完所有的关键码。
多关键码排序的实现方式有多种,其中一种常用的方法是使用“快速排序”算法的变种。具体来说,可以将每个对象看作是一个“键值对”,其中键是关键码的集合,值是对象的值。然后使用类似于快速排序的分治策略,将对象按照关键码的顺序分成不同的子集,再递归地对子集进行排序。最后将所有有序的子集合并成一个有序的整体。
多关键码排序的应用非常广泛,例如在数据库查询、搜索引擎、推荐系统等领域都有广泛的应用。通过使用多关键码排序,可以更好地处理具有多个属性、多个特征的数据,得到更准确、更符合实际需求的排序结果。
链式基数排序是一种排序算法,它基于“分配式排序”的思想,特别是一种叫做“多关键字排序”的方法。该算法将一个单关键字视为多个关键字,例如对于数字0~999,可以把每一位上的十进制数字都视为一个关键字。
链式基数排序使用LSD(最低位优先法)进行排序,从最低位的关键字开始,按照关键字的值将原始序列中的记录分配到多个“桶”中,然后依次收集,组成新的序列。再按照次低位的关键字重新将记录分配并收集,如此重复操作,直到按照最高位关键字对序列分配收集完毕,方可获得一个按关键字有序的序列。
这种排序方法结合了多关键字排序和桶排序,解决了桶排序中时间效益与空间效益不可兼得的矛盾。对于10个一千以内的整数,使用桶排序时,若每个桶中存储的键值依次加1,那么这10个数据会被分配到这1000个桶中,显然很多桶都为空;使用链式基数排序时,一千以内的整数被视为由三个0~9之间的数字组成的数据,关键字的范围从原来的0~999缩小到了0~9,只需要根据每一位的数字,对这10个一千以内的数进行三次分配与收集,就能得到需要的序列。
各种内部排序方法的比较可以从时间复杂度、空间复杂度、稳定性以及适用场景等多个维度进行。以下是一些常见的内部排序方法的比较:
时间复杂度:不同的内部排序方法具有不同的时间复杂度。其中,直接插入排序、选择排序和冒泡排序的时间复杂度较高,为O(n^2),而快速排序、归并排序和堆排序的时间复杂度较低,为O(nlogn)。在最坏情况下,快速排序的时间复杂度会退化到O(n^2),但其平均时间复杂度仍然是O(nlogn)。
空间复杂度:归并排序和快速排序需要额外的空间来存储临时数据,其空间复杂度为O(n),而其他的排序方法如选择排序、冒泡排序和插入排序的空间复杂度为O(1)。链式基数排序的空间复杂度为O(rd),其中rd是基数。
稳定性:当两个元素的比较结果相同时,稳定的排序方法会保持它们的相对位置不变。在稳定排序方法中,插入排序、归并排序和基数排序最为常见。
适用场景:选择排序和插入排序在n较小时更为有效,特别是当数据量小且大部分元素已经近似有序时。对于大型数据集,快速排序、堆排序和归并排序通常更为高效。链式基数排序适用于处理非常大的数据集,特别是当数据的关键字位数较少时。
综上所述,各种内部排序方法各有其特点,应根据实际需求和应用场景来选择合适的排序方法。
Copyright © 2017-Now pnotes.cn. All Rights Reserved.
编程学习笔记 保留所有权利
MARK:3.0.0.20240214.P35
From 2017.2.6