当前位置:   article > 正文

史上最全基础排序算法(动图)_基础的排序算法

基础的排序算法

目录

1.冒泡排序

 2.选择排序

3.二分查找(前提顺序结构-已序结构)

4.插入排序

5.希尔排序(插入排序的优化)

6.*快速排序

7.基数排序(桶子法)空间复杂度利用最高

8.归并排序(分治法)

1.冒泡排序

原理: 元素之间两两比较,大的往上冒

趟数+次数 =元素数量

实现 :内外循环

外层: 确定核心事件做的次数:趟数

内层:确定每一趟的次数

 以下是代码

  1. void Bubble_sort (int *arr, int length)
  2. {
  3. for(int i =0;i<size-1;i++)//趟数
  4. {
  5. for(int j =0;j<size -i-i;i++)//内层次数-每一趟次数
  6. {
  7. if(arr[j]>arr[j+1])
  8. swap(arr[j],arr[j+1]);
  9. }
  10. }
  11. }
  12. *优化 数据保存在栈
  13. 将temp ,j 定义在函数外

*异或交换

c^a=b;

c^b=a;

可以很惊奇的发现,将两数异或的结果与其中一数再进行异或,可以得到另一个数。 原理很简单,两数异或的结果保存了两个数上每一个二进制位不同或相同的信息,如果相应的二进制位不同,就标志为1,如果相同,则标志为0。

 2.选择排序

原理:每一次从待排序的元素中挑出最小(最大的)放到已序末尾

1.选取一个最小的(最大的)放在待序元素的开头(末尾)

比较趟数 =元素-1

每一趟次数 =趟数 -1

 

  1. void select_sort(int *arr,int size)
  2. {
  3. for(int i =size-1;i>0;i++)//for(int i=0;i<size;i++)趟数
  4. {
  5. for(int j=0;j<i;j++)
  6. {
  7. if(arr[i]<arr[j])
  8. {
  9. arr[i] =arr[i]^arr[j];
  10. arr[j] =arr[i]^arr[j];
  11. arr[i]=arr[i]^arr[j];
  12. }
  13. }
  14. }
  15. }

3.二分查找(前提顺序结构-已序结构)

原理:mid =left + (right -left)/2

定义左右中游标

每次分一半

  1. int binary_search(int *arr,int size,int findval)
  2. {
  3. int mid,left,right;//定义游标
  4. left =0;
  5. right = size -1;
  6. while(left<=right)
  7. {
  8. //1.确定中位数
  9. mid = left +((right+left)>>1);
  10. //2.和中位数比较
  11. if(arr[mid] ==findval)
  12. return mid;
  13. //如果不是中位数缩小范围 -升序
  14. if(findval<arr[mid])//说明在左侧
  15. right = mid-1;
  16. if(findval>arr[mid])//说明在右侧
  17. left =mid +1;
  18. }
  19. return -1;
  20. }

4.插入排序

原理:每轮插入一个进行比较

每一轮排序完前面都是有序的

 代码

  1. //while 版本
  2. void insert_sort(int *arr, int len)
  3. {
  4. int j, tempVal;
  5. for (int i = 1; i < len; ++i)//从第二个数开始排
  6. {
  7. tempVal = arr[i];
  8. j = i - 1;
  9. while (j >= 0&&tempVal <arr[j])//每次都和前面比较直到遇到比他小的数
  10. {
  11. arr[j + 1] = arr[j];
  12. j -= 1;
  13. }
  14. arr[j + 1] = tempVal;
  15. }
  16. }
  17. //for循环优化版本
  18. void insert_sortyh(int *arr, int len)
  19. {
  20. int tempVal, j;
  21. for (size_t i = 0; i < len; ++i)
  22. {
  23. tempVal = arr[i];
  24. for (j = i - 1; j >= 0 && tempVal < arr[j]; --j)
  25. arr[j + 1] = arr[j];
  26. arr[j + 1] = tempVal;
  27. }
  28. }//while 版本
  29. void insert_sort(int *arr, int len)
  30. {
  31. int j, tempVal;
  32. for (int i = 1; i < len; ++i)//从第二个数开始排
  33. {
  34. tempVal = arr[i];
  35. j = i - 1;
  36. while (j >= 0&&tempVal <arr[j])//每次都和前面比较直到遇到比他小的数
  37. {
  38. arr[j + 1] = arr[j];
  39. j -= 1;
  40. }
  41. arr[j + 1] = tempVal;
  42. }
  43. }
  44. //for循环优化版本
  45. void insert_sortyh(int *arr, int len)
  46. {
  47. int tempVal, j;
  48. for (size_t i = 0; i < len; ++i)
  49. {
  50. tempVal = arr[i];
  51. for (j = i - 1; j >= 0 && tempVal < arr[j]; --j)
  52. arr[j + 1] = arr[j];
  53. arr[j + 1] = tempVal;
  54. }
  55. }

5.希尔排序(插入排序的优化)

原理:除二分组再插入排序

  1. void shell_sort(int *arr, int len)
  2. {
  3. int tempVal, j;
  4. int jump = len >> 1;//初始分组为长度的一半
  5. while (jump != 0)//组长不为0持续执行
  6. {//将插入排序的1改为组长
  7. for (size_t i = jump; i < len; ++i)
  8. {
  9. tempVal = arr[i];
  10. for (j = i - jump; j >= 0 && tempVal < arr[j]; j-=jump)
  11. arr[j + jump] = arr[j];
  12. arr[j + jump] = tempVal;
  13. }
  14. jump >>= 1;
  15. }
  16. }

6.*快速排序

基本思想:分堆

划分标杆

小的数据分小堆,大的数据分大堆

一次确定一个

1.左右指针法 

 

r小于l 区间存在

左指针遇到比自己小的往后走,遇到大的停下,右指针遇到比自己大的往前走,遇到小的停下,两数交换,最后标杆换位重置,递归执行

  1. void _quick_sort(int *arr, int low, int hight);//换函数的声明
  2. void quick_sort(int *arr, int len)
  3. {
  4. _quick_sort(arr, 0, len - 1);//换函数
  5. }
  6. void _quick_sort(int *arr, int low, int hight)
  7. {
  8. int key = arr[low];//确定标杆
  9. int left =low +1, right =hight;//确定游标(索引)的值
  10. if (low >= hight)//说明区间只有一个元素,结束递归
  11. return;
  12. int temp;//数据交换
  13. //开始排序, 大前提 left<right
  14. while (left < right)
  15. {
  16. //游标移位 与标杆比较
  17. while (left <= right&&arr[left] < key) left++;
  18. while (left <= right&&arr[right]>key) right--;
  19. //交换
  20. if (left < right)
  21. {
  22. temp = arr[left];
  23. arr[left] = arr[right];
  24. arr[right] = temp;
  25. /*
  26. arr[left] =arr[right]^arr[left];
  27. arr[right]=arr[right]^arr[left];
  28. arr[left]=arr[right]^arr[left];
  29. */
  30. left++;
  31. right--;
  32. }
  33. }
  34. //完成分区,标杆归位
  35. arr[low] = arr[right];
  36. arr[right] = key;
  37. //递归左区间
  38. _quick_sort(arr, low, right - 1);
  39. //递归右区间
  40. _quick_sort(arr, right + 1, hight);
  41. }

2.挖坑法

 

  1. //快速排序法 挖坑法
  2. void QuickSort1(int* arr, int begin, int end)
  3. {
  4. if (begin >= end)
  5. return;
  6. int left = begin,right = end;
  7. int key = arr[begin];
  8. while (begin < end)
  9. {
  10. //找小
  11. while (arr[end] >= key && begin < end)
  12. {
  13. --end;
  14. }
  15. //小的放到左边的坑里
  16. arr[begin] = arr[end];
  17. //找大
  18. while (arr[begin] <= key && begin < end)
  19. {
  20. ++begin;
  21. }
  22. //大的放到右边的坑里
  23. arr[end] = arr[begin];
  24. }
  25. arr[begin] = key;
  26. int keyi = begin;
  27. //[left,keyi-1]keyi[keyi+1,right]
  28. QuickSort1(arr, left, keyi - 1);
  29. QuickSort1(arr, keyi + 1, right);
  30. }

7.基数排序(桶子法)空间复杂度利用最高

动画阐释各种排序算法(之前误删了大家也不用再点赞投币了)

原理:

第一轮除一%10

第二轮除10%10...

行存下数据

列往下遍历取出

全程没有进行数据的比较

1.准备桶子

2.初始化桶

3.循环放入

4.循环取出

  1. void radix_sort(int *arr, int len)
  2. {
  3. //准备桶子
  4. int temp[N][10] = {};
  5. int i, j, k,tempIdx;
  6. for (int n = 1; n < 10000; n *= 10)//步长 基于最大数的位数
  7. {
  8. //初始化桶
  9. for (i = 0; i < N; ++i)
  10. {
  11. for (j = 0; j < 10; ++j)
  12. {
  13. //初始化的值不会在数据里出现
  14. temp[i][j] = -1;
  15. }
  16. }
  17. //数据入桶
  18. for (i = 0; i < len; ++i)
  19. {
  20. tempIdx = (arr[i] / n) % 10;
  21. temp[i][tempIdx] = arr[i];
  22. }
  23. k = 0;
  24. //数据出桶
  25. for (i = 0; i < 10; ++i)
  26. {
  27. for (j = 0; j < N; ++j)
  28. {
  29. if (temp[j][i] != -1)
  30. arr[k++] = temp[j][i];
  31. }
  32. }
  33. }
  34. }

8.归并排序(分治法)

动画阐释各种排序算法(之前误删了大家也不用再点赞投币了)

递归再排序

先分后合

两两比较

代码实现:1.递归拆分

1.1 递归结束条件

1.2 递归左区间

1.3递归右区间

2.两路合并

2.1 准备一个辅助数组 两个游标

2.2 合并过程 - 两个数组至少遍历完一个

2.3 剩余部分拷贝进辅助数组

3.剩余拷贝进原数组

  1. void _merge_sort(int *arr, int left, int right);
  2. void _merge_in_arr(int *arr, int left, int mid, int right);
  3. void merge_sort(int *arr, int len)
  4. {
  5. _merge_sort(arr, 0, len);
  6. }
  7. void _merge_sort(int *arr, int left, int right)
  8. {
  9. // 递归结束条件
  10. if (left >= right)//说明区间只剩一个元素
  11. return;
  12. int mid = ((right-left) >> 1) + left;
  13. //递归左区间
  14. _merge_sort(arr, left, mid);
  15. //递归右区间
  16. _merge_sort(arr, mid + 1, right);
  17. //两路合并
  18. _merge_in_arr(arr, left, mid, right);
  19. }
  20. void _merge_in_arr(int *arr, int left, int mid, int right)
  21. {
  22. //每次合并数组长度不一致,动态规划
  23. int length = right - left + 1;
  24. //准备一个辅助数组 三个游标
  25. int *Pdata = new int[length];
  26. memset(Pdata, 0, sizeof(int)*length);
  27. int low = left;
  28. int hig = mid;
  29. int key = 0;
  30. //合并过程 - 两个数组至少遍历完一个
  31. while (low <= mid&&hig <= right)
  32. {
  33. //左区间存在元素且比右区间小 落下
  34. while (low <= mid&&arr[low] < arr[hig])
  35. {
  36. Pdata[key++] = arr[low++];
  37. }
  38. //右区间存在元素且比左区间小 落下
  39. while (hig <= right&&arr[low]>arr[hig])
  40. {
  41. Pdata[key++] = arr[hig++];
  42. }
  43. }
  44. //出循环,则至少有一个数组落完 剩余部分拷贝进辅助数组
  45. if (low <= mid)//说明左区间还有东西
  46. memmove(&Pdata[key], &arr[low], sizeof(int)*(mid - low + 1));
  47. if (hig <= right)//说明右区间还有东西
  48. memmove(&Pdata[key], &arr[hig], sizeof(int)*(right - hig + 1));
  49. //剩余拷贝进原数组
  50. memmove(&arr[left], Pdata, length*sizeof(int));
  51. delete[] Pdata;
  52. }

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号