排序下---(冒泡排序,快速排序,快速排序优化,快速排序非递归,归并排序,计数排序)

排序上

排序上

交换类排序

基本思想:所谓交换,就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置,交换排序的特点是:将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动。

冒泡排序

在这里插入图片描述

冒泡排序的特性总结:

  1. 冒泡排序是一种非常容易理解的排序
  2. 时间复杂度:O(N^2)
  3. 空间复杂度:O(1)
  4. 稳定性:稳定

代码实现

void BublleSort(int*array, int size)
{for (int i = 0; i < size - 1; ++i)       //总共冒泡的趟数{//冒泡的方式----->用相邻元素进行比较for (int j = 0; j < size - i - 1; ++j)		//一次冒泡{if (array[j]>array[j + 1])Swap(&array[j], &array[j + 1]);}}
}

冒泡排序优化

void BublleSort(int*array, int size)
{	for (int i = 0; i < size - 1; ++i)       //总共冒泡的趟数{int IsChange = 0;			//查看这一趟有没有交换//冒泡的方式----->用相邻元素进行比较for (int j = 0; j < size - i - 1; ++j)		//一次冒泡{if (array[j]>array[j + 1]){Swap(&array[j], &array[j + 1]);IsChange = 1;}	}if (!IsChange)  //如果没有交换return;}
}

快速排序

一种二叉树结构的交换排序方法,其基本思想为:任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止。

快速排序的特性总结:
  1. 快速排序整体的综合性能和使用场景都是比较好的,所以才敢叫快速排序
  2. 时间复杂度:O(N*logN),最差场景,单支树O(N2)
  3. 空间复杂度:O(logN)
  4. 稳定性:不稳定
  5. 快排参考链接

代码实现

int Partion(int*array, int left, int right)
{//划分基准值
}
void QuickSort(int *array, int left, int right)
{if (right - left > 1){int div = Partion(array, left, right);QuickSort(array, left, div);QuickSort(array, div + 1, right);}
}

划分基准值的方式

  1. hoare版本
int Partion(int*array, int left, int right)
{int key = array[right - 1];int begin = left;int end = right - 1;while (begin<end){//从前往后找比基准值大的元素,找到就停下来,等于也往前走,因为找的是大的while (begin < end&&array[begin] <= key)begin++;//end从后往前找比基准值小的元素,找到就停下来,等于也往前走,找的是小的,不是等于while (begin < end&&array[end] >= key)end--;if (begin < end)Swap(&array[begin], &array[end]);}if (begin != right - 1)Swap(&array[begin], &array[right-1]);return begin;
}
  1. 挖坑法
int Partion2(int*array, int left, int right)
{int key = array[right - 1];int begin = left;int end = right - 1;while (begin<end){while (begin<end&&array[begin] <= key)begin++;if (begin<end){//上一个坑是end,begin是比基准值大的数array[end] = array[begin];end--;}while (begin<end&&array[end] >= key)end--;if (begin<end){//上次坑是end,填坑的是begin,填完坑后,begin成坑,由新end比基准值小的数来填array[begin] = array[end];begin++;}}array[begin] = key;return begin;
}
  1. 前后指针版本
int Partion3(int*array, int left, int right)
{int key = array[right - 1];int cur = left;int pre = cur - 1;while (cur<right){if (array[cur] < key && ++pre != cur)Swap(&array[cur], &array[pre]);cur++;}if (++pre != right - 1)Swap(&array[pre], &array[right - 1]);return pre;
}

快排的优化

  1. 三数取中法选key
  2. 递归到小的子区间时,可以考虑使用插入排序
三数取中法
//三数取中法
int GetMiddleIdx(int*array, int left, int right)
{int mid = left + ((right - left) >> 1);//left mid right-1if (array[left] < array[right - 1]){if (array[mid] < array[left])return left;else if (array[mid]>array[right - 1])return right - 1;elsereturn mid;}else{if (array[mid] > array[left])return left;else if (array[mid] < array[right - 1])return right - 1;elsereturn mid;}
}
int Partion(int*array, int left, int right)
{int middle = GetMiddleIdx(array, left, right);if (middle != right - 1)Swap(&array[middle], &array[right - 1]);int key = array[right - 1];int begin = left;int end = right - 1;while (begin<end){//从前往后找比基准值大的元素,找到就停下来,等于也往前走,因为找的是大的while (begin < end&&array[begin] <= key)begin++;//end从后往前找比基准值小的元素,找到就停下来,等于也往前走,找的是小的,不是等于while (begin < end&&array[end] >= key)end--;if (begin < end)Swap(&array[begin], &array[end]);}if (begin != right - 1)Swap(&array[begin], &array[right - 1]);return begin;
}
元素个数小用直接插入排序
void QuickSort(int *array, int left, int right)
{if (right - left < 16)//如果快排的元素个数没有达到16及其以上,就用插入排序InsertSort(array, right - left);else{int div = Partion(array, left, right);QuickSort(array, left, div);QuickSort(array, div + 1, right);}
}

快速排序非递归写法

#include"stack.h"
//快排非递归
void QuickSortNor(int*array, int size)
{int left = 0;int right = size;Stack s;StackInit(&s);StackPush(&s,right);StackPush(&s,left); //后进去的先出来,先出来的是左while (!StackEmpty(&s)){left = StackTop(&s);StackPop(&s);right = StackTop(&s);StackPop(&s);if (left < right){int div = Partion3(array, left, right);//先保存右半部分,先进后出来StackPush(&s,right);//右半部分右边界StackPush(&s, div + 1);//右半部分左边界//再保存左边部分,后进先出来StackPush(&s, div);//左半部分右边界StackPush(&s, left);//左半部分左边界}}StackDestroy(&s);
}

归并排序

归并排序

基本思想:

归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide andConquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
在这里插入图片描述

归并排序的特性总结:

  1. 归并的缺点在于需要O(N)的空间复杂度,归并排序的思考更多的是解决在磁盘中的外排序问题。
  2. 时间复杂度:O(N*logN)
  3. 空间复杂度:O(N)
  4. 稳定性:稳定

代码实现

//归并到temp临时空间里
//两个有序序列合并成一个
void MergeData(int*array, int left, int mid, int right, int *temp)
{int begin1 = left, end1 = mid;int begin2 = mid, end2 = right;int index = left;while (begin1 < end1 && begin2 < end2)//第一个和第二个区间里的元素没有处理完{if (array[begin1] < array[begin2])temp[index++] = array[begin1++];elsetemp[index++] = array[begin2++];}//如果第一个空间里的数没有搬移完while (begin1 < end1)temp[index++] = array[begin1++];//第一个空间搬移完了,第二个空间里的元素没有搬移完while (begin2 < end2)temp[index++] = array[begin2++];
}
void _MergeSort(int*array, int left, int right,int*temp)
{//int*temp=(int*)malloc(sizeof(array[left])*(right-left));if (right - left>1) //区间里的元素超过一个,再排序{//找中间位置int mid = left + ((right - left) >> 1);_MergeSort(array, left, mid,temp);_MergeSort(array, mid, right,temp);MergeData(array, left, mid, right, temp);memcpy(array + left, temp + left, sizeof(array[left])*(right - left));}
}
void MergeSort(int *array, int size)
{int *temp = (int*)malloc(size*sizeof(array[0]));if (NULL == temp){assert(0);return;}_MergeSort(array, 0, size, temp);free(temp);
}

归并排序非递归

void MergeSortNor(int *array, int size)
{int *temp = (int*)malloc(size*sizeof(array[0]));if (NULL == temp){assert(0);return;}int gap = 1;while (gap < size){for (int i = 0; i < size; i += 2 * gap){int left = i;//左int mid = left + gap;//中int right = mid + gap;//右if (mid >= size)mid = size;if (right >= size)right = size;MergeData(array, left, mid, right, temp);}memcpy(array, temp, (sizeof(array[0])*size));gap *= 2;}free(temp);
}

非比较排序

思想:计数排序又称为鸽巢原理,是对哈希直接定址法的变形应用。

在这里插入图片描述
操作步骤:

  1. 统计相同元素出现次数
  2. 根据统计的结果将序列回收到原来的序列中

在这里插入图片描述

计数排序的特性总结:

  1. 计数排序在数据范围集中时,效率很高,但是适用范围及场景有限
  2. 时间复杂度:O(MAX(N,范围))
  3. 空间复杂度:O(范围)
  4. 稳定性:稳定

代码实现

//场景:数据密集集中在某个范围中
void CountSort(int*array, int size)
{int minVal = array[0];//范围的左边界值int maxVal = array[0];//范围的右边界值//1--找数据的范围for (int i = 1; i < size; ++i){if (array[i] < minVal)minVal = array[i];if (array[i]>maxVal)maxVal = array[i];}//2--计算保存计数的空间int range = maxVal - minVal + 1;int *temp = (int*)malloc(sizeof(int)*range);if (NULL == temp){assert(0);return;}//3---空间位置里全部置为0memset(temp, 0, sizeof(int)*range);//memeset 按一个一个字节赋值,赋值0可以,赋值其他值不行,例如100,给一个字节赋值100//4--统计每个数据出现的次数for (int i = 0; i < size; ++i){temp[array[i] - minVal]++;}//5--回收数据int index = 0;for (int i = 0; i < range; ++i){while (temp[i]--)  //当前元素值不为0,说明该下标还有个数	{array[index++] = i + minVal;}}free(temp);
}

计数排序参考链接

排序总结

在这里插入图片描述

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

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

相关文章

哈希的概念及其操作

哈希概念 顺序结构以及平衡树中&#xff0c;元素关键码与其存储位置之间没有对应的关系&#xff0c;因此在查找一个元素时&#xff0c;必须要经过关键码的多次比较。顺序查找时间复杂度为O(N)&#xff0c;平衡树中为树的高度&#xff0c;即O( Log2N)&#xff0c;搜索的效率取决…

软件工程---1.概述

软件的特征 抽象&#xff1a; 不可触摸&#xff0c;逻辑实体&#xff0c;可记录&#xff0c;但看不到复制成本低&#xff1a;不受物质材料的限制&#xff0c;不受物理定律或加工过程的制约&#xff0c;与开发成本相比&#xff0c;复制成本很低无折旧、受硬件制约、未完全摆脱手…

软件工程---2.软件过程

三个模型 瀑布模型增量模型集成和配置模型 没有适用于所有不同类型软件开发的过程模型。 瀑布模型 需求定义系统和软件的设计实现与单元测试集成与系统测试运行与维护 瀑布模型的特征 从上一项活动中接受该项活动的工作成果&#xff08;工作产品&#xff09;&#xff0c;作…

软件工程---4.需求工程

需求工程定义 找出、分析、文档化并且检查需求的过程被称为需求工程 需求的两个描述层次 用户需求&#xff0c;指高层的抽象需求。使用自然语言、图形描述需求。系统需求&#xff0c;指底层的详细需求。使用系统需求文档&#xff08;有时被称为功能规格说明&#xff09;应该…

软件工程---5.系统建模

从不同视角对系统建模 外部视角&#xff0c;上下文模型&#xff0c;对系统上下文或环境建模交互视角&#xff0c;交互模型&#xff08;功能模型&#xff09;&#xff0c;对系统与参与者或系统内构件之间的交互建模结构视角&#xff0c;结构模型&#xff08;静态模型&#xff0…

软件工程---6.体系结构设计

体系结构模型是什么&#xff1f; 体系结构模型&#xff0c;该模型描述系统如何被组织为一组相互通信的构件 体系结构分类 小体系结构关注单个程序的体系结构。在这个层次上&#xff0c;我们关注单个的程序是如何补分解为构件的。大体系结构关注包括其他系统、程序和程序构件…

【剑指offer】_07 矩形覆盖

题目描述 我们可以用21的小矩形横着或者竖着去覆盖更大的矩形。请问用n个21的小矩形无重叠地覆盖一个2*n的大矩形&#xff0c;总共有多少种方法&#xff1f; 解题思路 依旧是斐波那契数列 2n的大矩形&#xff0c;和n个21的小矩形 其中target*2为大矩阵的大小 有以下几种情形…

软件工程---07.设计与实现

软件设计和软件实现 软件设计是一个创造性的活动&#xff0c;在此活动中需要基于客户需求识别软件构件及其关系。软件实现是将设计实现为一个程序的过程 为开发一个系统设计&#xff0c;你需要 理解并定义上下文模型以及系统的外部交互设计系统体系结构识别系统中的主要对象…

软件工程---15.软件复用

复用的图(牢记) 软件复用的好处 开发加速有效的专家利用提高可依赖性降低开发成本降低过程风险符合标准 软件复用的缺点 创建&#xff0c;维护以及使用一个构件库查找&#xff0c;理解以及适配可复用构件维护成本增加缺少工具支持“不是在这里发明的”综合症 应用框架 现在…

软件工程---16.基于构件的软件工程

CBSE CBSE是定义、实现、集成或组装松散耦合的独立构件成为系统的过程。 基于构件的软件工程的要素有: 完全由接口进行规格说明的独立构件。构件标准使构件集成变得更为容易。中间件为构件集成提供软件支持。开发过程适合基于构件的软件工程。 CBSE的设计原则 构件是独立的…

软件工程---17.分布式软件工程

分布式系统的5个优点 资源共享开放性并发性可伸缩性容错性 分布式计算中必须考虑的设计问题 透明性&#xff1a;隐藏底层分布 开放性 可伸缩性 三个维度 规模&#xff1a;又分为增强扩展(单挑)&#xff0c;增加扩展(群殴)分布可靠性 信息安全性 主要防止以下类型的攻击 拦…

软件工程---18.面向服务的软件工程

什么是Web服务 一个松耦合、可复用的软件构件&#xff0c;封装了离散的功能&#xff0c;该功能是分布式的并且可以被程序访问。Web服务是通过标准互联网和基于XML的协议被访问的服务。 服务和软件构件之间的一个重要的区别是 服务应该总是独立的和松耦合的Web 服务没有“请求…

【剑指offer】_09二叉搜索树的后序遍历序列

题目描述 输入一个整数数组&#xff0c;判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。 解题思路 比如下面的这棵二叉搜索树 它的后序遍历为0214369875&#xff1b; 我们设当前根节点为root; 第一次…

【剑指offer】_12 数组中的逆序对

题目描述 在数组中的两个数字&#xff0c;如果前面一个数字大于后面的数字&#xff0c;则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007 解题思路 剑指offer的解法 看到这个题目&#xff0…

详解Linux下通过yum安装Mariadb/MySQL数据库(腾讯云也适用)

1. 安装Mariadb 安装命令 yum -y install mariadb mariadb-server安装完成MariaDB&#xff0c;首先启动MariaDB systemctl start mariadb设置开机启动 systemctl enable mariadbMariaDB的相关简单配置 此命令进入到配置相关界面 mysql_secure_installation首先是设置密码…

海量数据处理(位图和布隆过滤器)

哈希切割 给一个超过100G大小的log file, log中存着IP地址, 设计算法找到出现次数最多的IP地址&#xff1f; 与上题条件相同&#xff0c;如何找到top K的IP&#xff1f;如何直接用Linux系统命令实现 解决思路 找到出现次数最多的IP地址 要找到前TopK的IP地址&#xff0c;就…

C++中的lambda表达式和线程库

98中的一个例子 如果想要对一个数据集合中的元素进行排序&#xff0c;可以使用std::sort方法 #include <algorithm> #include <functional> int main() {int array[] {4,1,8,5,3,7,0,9,2,6};// 默认按照小于比较&#xff0c;排出来结果是升序std::sort(array, a…

文件压缩(Huaffman树的概念及其实现)

什么是压缩 想办法让源文件变得更小并能还原。 为什么要进行文件压缩 文件太大&#xff0c;节省空间提高数据再网络上传输的效率对数据有保护作用—加密 文件压缩的分类 无损压缩 源文件被压缩后&#xff0c;通过解压缩能够还原成和源文件完全相同的格式 有损压缩 解压缩之…

详解STL中的空间配置器(SGI版本)

空间配置器 1.什么是空间配置器 为各个容器高效的管理空间(空间的申请与回收)的 2.为什么需要空间配置器 各种容器----->可以存放元素---->底层需要空间 new 申请空间 operator new ---->malloc调用构造函数------完成对象的构造 动态内存管理总结 前面的容器…

大四阶段的社会实践的主要目的是_疫情当前,大三大四的学生“很惨”?大一大二的学生也别松懈...

大四毕业生不容易这次疫情对于高校学生而言&#xff0c;可以说是各有各的难处&#xff0c;“这届毕业生很惨”更是屡上热搜。不可否认&#xff0c;大四毕业生确实很不容易&#xff0c;论文答辩、毕业、求职就业等都受到了影响&#xff0c;虽然有困难&#xff0c;但各方都在积极…