经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C 语言 » 查看文章
C语言面试常见考点排序总结
来源:jb51  时间:2021/11/23 12:52:55  对本文有异议

排序算法有两块比较重要的知识点

  • 内存消耗 :算法的内存消耗可以通过空间复杂度来衡量,排序算法也不例外。不过,针对排序算法的空间复杂度,有一个概念是原地排序。原地排序算法是指空间复杂度是O(1)的排序算法。其中冒泡排序,插入排序、选择排序都属于原地排序算法
  • 稳定性:针对排序算法,我们还有一个衡量指标是稳定性。这个概念是说,如果待排序的序列中存在值相等的元素,经过排序之后,相等元素之间原有的先后顺序不变。

例如我们有一组数据 2 9 3 4 8 3 按照从小到大的排序是 2 3 3 4 8 9,经过某种排序算法之后,如果两个3的前后顺序没有改变,就称为稳定的排序算法,否则就是不稳定的排序算法

算法名称 时间复杂度 是否稳定排序 是否原地排序
冒泡排序 O(N^2)
插入排序 O(N^2)
选择排序 O(N^2)
归并排序 O(nlogn)
快速排序 O(nlogn)
堆排序 O(nlogn)

冒泡排序

  • 平均复杂度是O(N^2)
  • 最好情况是O(1) 本身就是排好序的
  • 最坏就是倒序O(N^2)
  • 空间复杂度是O(1)

冒泡排序只会操作相邻的两个数据。每次冒泡操作都会对相邻的两个元素进行比较,看是否满足大小关系要求。如果不满足就让它俩互换。一次冒泡会让至少一个元素移动到它应该在的位置,重复 n 次,就完成了 n 个数据的排序工作。

  1. class Sort{
  2. public:
  3. void MaoPao_Sort(vector<int> &arr){
  4. //1.判断溢出条件
  5. if(arr.size() <2) return;
  6. int length =arr.size();
  7. for(int i =0;i < length;i++){
  8. for(int j=0; j < length -i -1 ;j++){
  9. if(arr[j] >arr[j+1]){
  10. int temp = arr[j];
  11. arr[j]= arr[j+1];
  12. arr[j+1]=temp;
  13. }
  14. }
  15. }
  16. }
  17. };

插入排序

插入排序思想的由来,其实就是按照在一个有序的数组中插入一个元素的思想,找到合适的位置进行插入并迁移后面的元素

首先,我们将数组中的数据分为两个区间,已排序区间和未排序区间。初始已排序区间只有一个元素,就是数组的第一个元素。插入算法的核心思想是取未排序区间中的元素,在已排序区间中找到合适的插入位置将其插入,并保证已排序区间数据一直有序。重复这个过程,直到未排序区间中元素为空,算法结束。

  1. class Sort{
  2. public:
  3. void Insert_Sort(vector<int> &arr){
  4. //1.判断溢出条件
  5. if(arr.size() < 2) return;
  6. int length =arr.size();
  7. int j =0;//初始的已排序区间的下标
  8. for(int i =1;i < length ;i++){ //从未排序的区间里面取元素
  9. int temp =arr[i];
  10. j =i-1; //不断更新已排序区间
  11. while(j >= 0 && temp <a[j]){
  12. //如果小的话就往后移动,找到合适的插入位置
  13. arr[j+1]=arr[j];
  14. j--;
  15. }
  16. arr[j+1]=temp; //插入元素
  17. }
  18. }
  19. };

选择排序

选择排序算法的实现思路有点类似插入排序,也分已排序区间和未排序区间。但是选择排序每次会从未排序区间中找到最小的元素,将其放到已排序区间的末尾

  1. class Sort{
  2. public:
  3. void Select_Sort(vector<int> &arr ,int length){
  4. for(int i =0;i < length -1;i++){
  5. int min_number =arr[i];
  6. int flag = i;
  7. for(int j =i;j <length ;j++){
  8. if(min_number > arr[j]){
  9. min_number = arr[j];
  10. flag =j;
  11. }
  12. }
  13. //交换数字
  14. arr[flag] =arr[i];
  15. arr[i]=min_number;
  16. }
  17. }
  18. };

归并排序

归并排序是由下而上,采用分治的思想,把数据先拆分在合并,并把合并后的数据存入临时数组中,保证原先的数据位置不发生变化,是一种稳定的排序但不是原地排序,时间复杂度是O(nlogn),空间复杂度是O(N)

  1. class Sort{
  2. public:
  3. //归并排序
  4. void MergeSort(vector<int> & arr){
  5. if(arr.size() < 2){
  6. return ;
  7. }
  8. //拆分函数
  9. Merge_Process(arr,0,arr.size())-1);
  10. }
  11. //先拆分,这是拆分函数
  12. void Merge_Process(vector<int> &arr,int start,int end){
  13. //递归拆分,首先需要递归的终止条件
  14. if(end -start == 0) return;
  15. int mid =((end -start)/2) +start;
  16. Merge_Process(arr,start,mid);
  17. Merge_Process(arr,mid+1,end);
  18. //在合并
  19. Merge(arr,start,mid,end);
  20. }
  21. //合并函数
  22. void Merge(vector<int> &arr,int start,int mid, int end){
  23. vector<int> temp(end-start+1,0);//初始化一个临时数组
  24. int tempIndex =0; //辅助空间索引
  25. int leftIndex =start;
  26. int rightIndex =mid+1;
  27. while(leftIndex <= mid && rightIndex <= end){
  28. if(leftIndex <rightIndex){
  29. temp[tempIndex++] =arr[leftIndex++];
  30. }else{
  31. temp[tempIndex++] =arr[rightIndex++];
  32. }
  33. }
  34. while(leftIndex <= mid){
  35. temp[tempIndex++]=arr[leftIndex++];
  36. }
  37. while(rightIndex <= end){
  38. temp[tempIndex++]=arr[rightIndex++];
  39. }
  40. for(int i =0;i< temp.size();i++){
  41. arr[start+i]=temp[i];
  42. }
  43. }
  44. };

快速排序

快速排序是先分区,在处理子问题,通过找到区间后取得任意一个分区点,小的放分区点左边,大的放分区点右边,时间复杂度是O(nlong),空间复杂度是O(1),是原地排序但不是稳定排序

快排优化的话,有:三数取中法,和随机法,都是为了防止要排序的数组中有重复元素,这块我演示的是随机法

  1. class Sort{
  2. public:
  3. void quickSort(vector<int> &arr,int begin, int low){
  4. if(begin <end){
  5. //产生一个随机值
  6. int index =rand()%(end-begin+1)+begin;
  7. //然后把产生的这个随机值,替换到数组的首位
  8. swap(arr[begin],arr[index]);
  9. int i =begin;
  10. int j =end;
  11. int base =arr[i];//基准位
  12. while(i <j){
  13. while(i<j&& arr[j] >= base){
  14. j--;
  15. }
  16. num[i]=num[j];
  17. while(i<j && arr[i] < base){
  18. i++;
  19. }
  20. num[j]=num[i];
  21. }
  22. //回归基准位
  23. num[i]=base;
  24. //递归开始处理子问题
  25. quickSort(arr,begin,i-1);
  26. quickSort(arr,i+1,end);
  27. }
  28. }
  29. };

以上就是C语言面试常见考点排序总结的详细内容,更多关于C语言 排序的资料请关注w3xue其它相关文章!

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号