十大排序算法函数声明

时间复杂度表

主函数

#include<iostream>
#include<cstdlib>
#include<srand>
using namespace std;void BubbleSort(int length, int array[]);//冒泡排序
void SelectSort(int length, int array[]);//选择排序
void InsertSort(int length, int array[]);//插入排序
void ShellSort(int length, int array[]);//希尔排序
void MergeSort(int length, int array[]);//归并排序
void QuickSort( int begin,int end,int array[]);//快速排序
void Swap(int i, int j, int array[]);//交换数组内的两个元素
int Partition(int begin, int end, int array[]);//快排中分割函数,结果返回中间项
void CountSort(int length, int array[]);//计数排序
void BucketSort(int length, int array[]);//桶排序
void RadixSort(int length, int array[]);//基数排序int main() {//int array[6] = { 2,9,1,5,3,6 };int array[6];srand((unsigned int )time(NULL));//随机数生成器初始化cout << "排序前";for (int i = 0; i < 6; i++){array[i]=rand()%100;//每次生成0-100的随机数cout << array[i]<<",";}cout << endl;//BubbleSort(6, array);//SelectSort(6, array);//InsertSort(6, array);//ShellSort(6, array);QuickSort(0, 5, array);cout << "排序后";for (int i = 0; i < 6; i++){cout << array[i] << ",";}system("pause");return 0;
}

1冒泡排序(加入flag标记简单优化)

void BubbleSort(int length, int array[])//冒泡排序,注意flag的位置
{for (int i = 0; i < length; i++){bool flag = true;//初始flag,一趟排序刚开始for (int j = 0; j < length-i-1; j++){if (array[j] > array[j + 1]){int temp = array[j];array[j] = array[j + 1];array[j + 1] = temp;flag = false;//只要完成过一次交换flag就为false}}if (flag)//如果flag一次冒泡后仍为true说明不需要交换,排序已经完成,不必要继续浪费资源return;//退出循环排序完成}
}

2插入排序

void InsertSort(int length, int array[])//插入排序
{int current;for (int i = 0; i < length-1; i++)//a[i+1]项限制,第一项默认排好序,{current = array[i + 1];//将需要操作位置的值保存在current中,可以理解为腾出空位,从第二项开始向后int preindex = i;//current的前一项下标while (preindex>=0 && array[preindex]> current)//如果前面项每次都大于固定current值 ,最终前项为a[0]项{array[preindex + 1] = array[preindex];//前项值覆盖后项,不同于冒泡的交换,二是直接覆盖,preindex--;//每次向前遍历}array[preindex+1] = current;//覆盖到前项比后项小,current直接赋值给刚刚移动过剩下的空位}
}

3希尔排序(优化插排)

void ShellSort(int length,int array[])//希尔排序O(nlog2n),优化插排
{int temp, gap = length / 2;//初始定义gap为整个数组长度的一半while (gap>0){for (int i = gap; i < length; i++){temp = array[i];//i=gap,gap+1....int preIndex = i - gap;while (preIndex>=0&& array[preIndex]>temp){array[preIndex + gap] = array[preIndex];preIndex -= gap;}array[preIndex + gap] = temp;}gap /= 2;}}

4选择排序(选择最小元素下标)

void SelectSort(int length,int array[]) {//选择排序,选择最小值下标,注意比较双方for (int i = 0; i < length-1; i++) {int minindex =i;//初始指定i为最小元素下标for (int j = minindex; j < length - 1; j++) {if (array[minindex] > array[j + 1]) {//下一个与最小值下标对应的元素比较minindex = j + 1;//选出最小值下标}//比较条件下标j/j+1: j+1与length-1一组,j和length一组}int temp = array[i];//最小值与当前最小值下标位置的元素交换array[i] = array[minindex];array[minindex] = temp;}
}

5归并排序(优化选择排序)

void Mergesort( int L, int R,int array[])//归并排序O(nlogn),优化选择排序{if (L < R){int mid = L + ((R - L) >> 1);//>>1右移1位,等价于/2但是余数直接舍去Mergesort( L, mid,array);//左边归并排序,使左子序列有序Mergesort( mid + 1, R,array);//右边归并排序,使得右子序列有序Merge( L, mid, R,array);//合并左右两个有序子序列}
}void Merge( int L, int mid, int R,int array[])//归并函数{int *temp= new int[R - L + 1];//新建一个原数组一样大的临时数组tempint i = 0;//临时数组的下标int p1 = L;//左侧指针int p2 = mid + 1;//右侧指针// 比较左右两部分的元素,哪个小,把那个元素填入temp中while(p1 <= mid && p2 <= R) {temp[i++] = array[p1] < array[p2] ? array[p1++] : array[p2++];}// 上面的循环退出后,把剩余的元素依次填入到temp中// 以下两个while只有一个会执行while(p1 <= mid) {//1左侧剩余元素,依次全部移入temp[i++] = array[p1++];}while(p2 <= R) {//2右侧剩余元素temp[i++] = array[p2++];}// 把最终的排序的结果复制给原数组for (i = 0; i < R - L +1; i++) {//R-L+1是当前动态数组temp的大小array[L + i] = temp[i];}/*或者用下面的方法赋值i = 0;while (L <= R){array[L++] = temp[i++];}*/delete[]temp;//别忘了释放内存空间
}

6.1快速排序(单向扫描)

void Swap(int i, int j, int array[])//交换数组内两个元素{int temp;temp = array[i];array[i] = array[j];array[j] = temp;}
void QuickSort(int begin, int end, int array[])//快速排序
{if (begin<end){int mid = Partition(begin, end, array);//mid返回中间项QuickSort(begin, mid-1, array);//递归调用,对mid左边的进行快排QuickSort(mid + 1,end, array);//递归调用,对mid右边的进行快排}}int Partition(int begin, int end, int array[])//快排中分割函数,结果返回中间项
{int pivot = array[begin];//初始中间项值=首元素int sp = begin + 1;//扫描指针下标int bigger = end;//bigger指针初始在尾部while (sp<=bigger)//当扫描指针位于bigger左边或者重合,{if (array[sp] > pivot)//如果扫描到的值大于中间项值{Swap(sp,bigger,array);//交换两者bigger--;//左移1位}else//<=中间项{sp++;//继续向后扫描}}//此时sp指向最后一个比中间项(首元素)大的值,bigger指向最后一个<=中间项的元素Swap(begin, bigger, array);//交换,此时新的bigger位置为中间项(值是初始的中间项值)。左边都是小的,右边都是大的return bigger;//返回中间项bigger(即pivot)
}

6.2快速排序(双向扫描法)


int DoubblePartition(int begin,int end,int array[])//双向扫描法左右指针left,right
{int pivot = array[begin];int left = begin + 1;//左侧指针指向pivot后1个元素int right = end;//右侧指针指向尾元素while (left<=right){if (array[left]<=pivot && left <= right)//左指针扫描元素都小于pivot{//最终arrayleft肯定是大于pivotleft++;//继续往右}if (array[right] > pivot&&left <= right)//右指针都大于pivot{//最终array[right]肯定是小于pivotright--;//继续向左}//注意!:上面2个加上left <= right条件防止,排序完成后left和right再次移动,因为最后一次left会一直往后跑,外层循环不一定控制的住内层循环//虽然我测试很多次并没有遇到这个情况。。else if(left<right)//以上两者都不满足,左右指针停止,条件left!=right等于时候交换,没有意义的{Swap(left, right,array);//先交换二者值,再继续扫描}}Swap(begin, right, array);return right;
}void DoubbleQuickSort(int begin, int end, int array[])//双向扫描快排
{if (begin < end){int mid = DoubblePartition(begin, end, array);//mid返回中间项DoubbleQuickSort(begin, mid - 1, array);//递归调用,对mid左边的进行快排DoubbleQuickSort(mid + 1, end, array);//递归调用,对mid右边的进行快排}
}

7堆排序(大顶堆升序排)

static int len=10;//定义全局变量数组长度
void HeapSort(int arr[])
{//1将乱序数组初始化为大堆BuildHeap(arr);//2更新大堆while(len>1)//最后剩余1个元素不需要再比较{swap(arr,0,len-1);//每次大堆顶的元素肯定是最大的哪个值,//与堆顶元素交换后的堆尾即可脱离待排序堆//并且成为最终有序数组的尾元素len--;//每次选出1最大元素脱离堆,待排序的堆长度减1AdjusHeap(arr,0);//更新大堆,重新检查首元素是否为最大堆顶}
}
void BuildMaxHeap(int arr[])
{/*如图所示len=7最小的父亲节点为第三个a[2]##   #(a[2])最小父亲 7/2-1=2# # #a5#a[6]*/
//从最后一个非叶子节点(最小的父亲节点)len/2 -1开始
//i--到0向上构造最大堆for(int i=len/2 -1 ;i>=0;i--){AdjustHeap(arr,i);//每次更新当前父节点对应的堆//共更新len/2次,因为共len/2个父亲节点}
}
/*
更新大顶堆函数
@param 数组名,堆顶父节点下标
*/
void AdjustHeap(int arr[],int i)
{int maxindex=i;//初始默认当前父节点为最大元素//如果左孩值大于当前最大元素下标对应值,//且下标没有越界,原左孩子下标成为maxindexif(a[2*i+1]>a[maxindex]&&2*i+1<=len-1)maxindex=i*2+1;//原左孩子下标成为maxindex//如果右孩子大于当前堆顶元素,且下标未越界if(a[2*i+2]>a[maxindex]&&i*2+2<len)maxindex=i*2+2;//右孩子为最大下标 /*上述if判断,如有变化只更新下标而不着急直接交换Swap(arr,i*2+2,maxindex);类似选择排序思想如果以上条件不成立,即堆顶仍未最大下标,则不需要破坏堆结构,使用下面的if进行判断*/if(maxindex!=i)//如果最大值下标变化,即堆顶不是最大值//交换当前最大值为堆顶,破坏当前堆{Swap(arr,i,maxindex);//破坏堆AdjustHeap(arr,maxindex);//此时这个maxindex对应值是被替换的一开始的父节点1的值,并位置是被交换的的子节点1的位置,//因为交换后,原来子节点1对应的子堆(以原来的子节点1为堆顶的堆)也会被破坏,父1节点不一定再是新堆的最大值了(都不一定有资格成为子堆顶),//所以需要更新被破坏的子堆。也即对子堆进行递归调用AdjustHeap,直到子堆不存在,也就是AdjustHeap(arr,i)函数参数i为叶子节点时,停止递归}
}
//通过下标对数组内元素进行交换
void Swap( int *a , int i,int j)
{int temp=a[i];a[i]=a[j];a[j]=temp;
}

8计数排序


9桶排序


10基数排序


一篇文章快速搞懂排序算法(含实现源码)相关推荐

  1. 一篇文章快速搞懂十大排序算法(C++实现源码)

    十大排序算法函数声明 时间复杂度表 主函数 #include<iostream> using namespace std;void BubbleSort(int length, int a ...

  2. mysql snowflake_一篇文章彻底搞懂snowflake算法及百度美团的最佳实践

    写在前面的话 一提到分布式ID自动生成方案,大家肯定都非常熟悉,并且立即能说出自家拿手的几种方案,确实,ID作为系统数据的重要标识,重要性不言而喻,而各种方案也是历经多代优化,请允许我用这个视角对分布 ...

  3. 八、一篇文章快速搞懂MySQL 常见的数据类型(整型、小数、字符型、日期型详解)

    常见的数据类型 1.数值型: 整型 小数: 定点数 浮点数 2.字符型: 较短的文本:char.varchar 较长的文本:text.blob(较长的二进制数据) 3.日期型: 一.整型 1)分类: ...

  4. 一篇文章快速搞懂C++生成随机数

    使用rand()函数 头文件<stdlib.h> 如果你只要产生随机数而不需要设定范围的话,你只要用rand()就可以了:rand()会返回一随机数值, 范围在0至RAND_MAX 间. ...

  5. qt上传文件到iis文件服务器,一篇文章快速搞懂Qt文件读写操作

    导读:Qt当中使用QFile类对文件进行读写操作,对文本文件也可以与QTextStream一起使用,这样读写操作会更加简便.QFileInfo可以用来获取文件的信息.QDir可以用于对文件夹进行操作. ...

  6. 一篇文章彻底搞懂Android事件分发机制

    本文讲的是一篇文章彻底搞懂Android事件分发机制,在android开发中会经常遇到滑动冲突(比如ScrollView或是SliddingMenu与ListView的嵌套)的问题,需要我们深入的了解 ...

  7. C语言实现冒泡排序(bubble排序)算法(附完整源码)

    冒泡排序bubble排序算法 冒泡排序(bubble排序)算法的完整源码(定义,实现,main函数测试) 冒泡排序(bubble排序)算法的完整源码(定义,实现,main函数测试) #include ...

  8. C语言递归方式实现冒泡排序(bubble排序)算法(附完整源码)

    递归方式实现冒泡排序算法 递归方式实现冒泡排序算法的完整源码(定义,实现,main函数测试) 递归方式实现冒泡排序算法的完整源码(定义,实现,main函数测试) #include <assert ...

  9. 数据结构与算法——列表排序(一篇文章带你了解排序算法)

    数据结构与算法基础 列表排序: 什么是列表排序? 排序:将一组"无序"的记录序列调整为"有序"的记录序列. 列表排序:将无序列表变为有序列表. 内置函数:sor ...

最新文章

  1. 新进展!英伟达用 AI 给纪录片配音,情绪语调拿捏得稳稳地
  2. 知道为啥失败么?87%的机器学习项目都是这么栽了的……
  3. javascript和“主流大型语言”(c# JAVA C++等)的差异
  4. manifold learning 流形学习 zz
  5. 根据SAP SAP Cloud Connector的日志排查错误
  6. system的相关用法
  7. 全面取消校园全封闭管理!这个省发通知了!那北京呢?
  8. 极测未来|淘宝千人千面内容下的智能评测技术与实践
  9. Java快逸报表展现demo_快逸报表导出成XML文件
  10. 跨时代作品:超级IE缓存提取器
  11. html pre标签样式,pre标签的基本样式设置
  12. XTU-oj 字符矩阵
  13. 开源看板 wekan docker-compose部署
  14. 二手房“反价”越来越多 部分学区房涨价10万
  15. Windows 隐藏小电影?
  16. java--获取当前时间
  17. 基于黄金正弦与自适应融合的蜉蝣优化算法
  18. 解决eclipse中overlaps the location of another project: 'xxxx'
  19. 【强化学习论文】Decision Transformer:通过序列建模进行强化学习
  20. 如何使用远程Linux虚拟机的图形界面

热门文章

  1. 【数据结构笔记29】最小生成树问题:Prim算法与Kruskal算法
  2. 计算机网络 职中,职中计算机网络基础期中考试试卷.pdf
  3. 在opencv3中实现机器学习之:利用逻辑斯谛回归(logistic regression)分类
  4. 当子元素设置position absolute的时,父元素必须设置position属性
  5. 育碧2k微软服务器,育碧服务器出现大规模的BUG:影响到多个平台
  6. java学习 - 函数
  7. 使用“swap技巧”除去多余的容量
  8. 共同努力做好NBear!
  9. MongoDB的Go语言驱动----mgo的使用指南
  10. Android TTS 初体验