各种排序算法思想

快速排序

主要思想: 主要是基于分治。(分治解读)

基本步骤:

1.确定分界点x ,常用方式q[l]  q[l + r >> 1] , q[r] , 左右部分未必长度相等

2.根据分界点x调整区间,使得满足小于等于x的在左边,大于等于x的在右边

3.左右两端,递归缩小规模处理,然后进行拼接,即两个区间合并

注释:其中使用了双指针算法思想中的,从两侧向中间移动来维护一段区间的方法

// 快速排序算法模板
void quick_sort(int q[], int l, int r)
{if (l >= r) return;int i = l - 1, j = r + 1, x = q[l + r >> 1];while (i < j){do i ++ ; while (q[i] < x);do j -- ; while (q[j] > x);if (i < j) swap(q[i], q[j]);}quick_sort(q, l, j);quick_sort(q, j + 1, r);
}

归并排序

主要思想: 主要是基于分治。(分治解读)

基本步骤:

1.确定分界点mid,常用方式l + r >> 1 

2.递归排序左边和右边

3.归并合二为一,双指针算法。两个有序的序列进行二合一排序存到额外空间

注释:其中使用了双指针算法思想中的,从两侧向中间移动来维护一段区间的方法

// 归并排序算法模板
void merge_sort(int q[], int l, int r)
{if (l >= r) return;int mid = l + r >> 1;merge_sort(q, l, mid);merge_sort(q, mid + 1, r);int k = 0, i = l, j = mid + 1;while (i <= mid && j <= r)if (q[i] < q[j]) tmp[k ++ ] = q[i ++ ];else tmp[k ++ ] = q[j ++ ];while (i <= mid) tmp[k ++ ] = q[i ++ ];while (j <= r) tmp[k ++ ] = q[j ++ ];for (i = l, j = 0; i <= r; i ++, j ++ ) q[i] = tmp[j];
}

 归并排序 自带时间复杂度测试

//时间复杂度  O(N*log2N) 
//稳定程度: 稳定
/*
确定分界点,中间位置
两端排序
归并,合二为一
*/#include<iostream>
#include<time.h>
using namespace std;
int tmp[250001];
void Sort(int List[], int l, int r);int main()
{int a[250000];int k, j;// 设置种子srand((unsigned)time(NULL));/* 生成 10 个随机数 */for (k = 0; k < 250000; k++){// 生成实际的随机数j = rand();a[k] = j;}clock_t start_time = clock();Sort(a,0,250000-1);clock_t end_time = clock();//for (int i = 0; i < 200000; i++)//{//	cout << a[i] << " ";//}cout << "\n程序段运行时间:" << static_cast<double> (end_time - start_time) / CLOCKS_PER_SEC * 1000 << "ms" << endl;system("pause");
}
void Sort(int List[], int l, int r)
{if (l >= r) return;int mid = l + r >> 1;  //取中间数Sort(List, l, mid), Sort(List, mid + 1, r); //左右递归排序int k = 0, i = l, j = mid + 1; //k表示已合并数组中有几个元素,分开两个有序数组while (i <= mid && j <= r) //进行双指针比较if (List[i] <= List[j]) tmp[k++] = List[i++];  else tmp[k++] = List[j++];while (i <= mid) tmp[k++] = List[i++]; //分别处理剩余部分while (j <= r) tmp[k++] = List[j++];for (i = l, j = 0; i <= r; i++, j++) List[i] = tmp[j]; //拷入原空间}

快速排序 自带时间复杂度检测

//时间复杂度   O(N*log2N
//稳定性:不稳定
//来源于分治思想
/*
确定分界点
调整区间
递归处理两端
算法思想,快排是基于冒泡排序的优化,冒泡排序从一侧开始进行,而快排是两边同时进行从而时间复杂度折半,同时包含了二分的思想在里面
*/#include<iostream>
#include<time.h>
using namespace std;void Sort(int List[], int l, int r);int main()
{int a[80000];int k, j;// 设置种子srand((unsigned)time(NULL));/* 生成 10 个随机数 */for (k = 0; k < 80000; k++){// 生成实际的随机数j = rand();a[k] = j;}clock_t start_time = clock();Sort(a,0,80000-1);clock_t end_time = clock();for (int i = 0; i < 80000; i++){cout << a[i] << " ";}cout << "\n程序段运行时间:" << static_cast<double> (end_time - start_time) / CLOCKS_PER_SEC * 1000 << "ms" << endl;system("pause");
}
void Sort(int List[], int l, int r)
{if (l >= r) return; //边界判断int i = l - 1, j = r + 1, x = List[l];  //x为分界点while (i < j){//两次do,主要在于找到左右两侧<x和>x的第一个数do i++; while (List[i] < x); do j--; while (List[j] > x);if (i < j) swap(List[i], List[j]);else break;}Sort(List, l, j), Sort(List, j + 1, r);}

冒泡排序 自带时间复杂度测试

#include<iostream>
#include<time.h>
using namespace std;void Sort(int List[], int n);int main()
{int a[10000];int k, j;// 设置种子srand((unsigned)time(NULL));/* 生成 10 个随机数 */for (k = 0; k < 10000; k++){// 生成实际的随机数j = rand();a[k] = j;}clock_t start_time = clock();Sort(a, 10000);clock_t end_time = clock();for (int i = 0; i < 10000; i++){cout << a[i] << " ";}cout << "\n程序段运行时间:" << static_cast<double> (end_time - start_time) / CLOCKS_PER_SEC * 1000 << "ms" << endl;system("pause");
}
void Sort(int List[], int n)
{for (int i = 0; i < n - 1; i++){for (int j = 0; j < n - i - 1; j++) //j<n-i-1:首先j不与自己比较所以-1,其次每次外循环都会产生一个已经排序的最大数,所以内循环要排除已经排好的,即总数为n-i。if (List[j] > List[j + 1])swap(List[j], List[j + 1]);}
}

冒泡排序优化

#include<iostream>
#include<time.h>
using namespace std;void Sort(int List[], int n);int main()
{int a[10000];int k, j;// 设置种子srand((unsigned)time(NULL));/* 生成 10 个随机数 */for (k = 0; k < 10000; k++){// 生成实际的随机数j = rand();a[k] = j;}clock_t start_time = clock();Sort(a, 10000);clock_t end_time = clock();for (int i = 0; i < 10000; i++){cout << a[i] << " ";}cout << "\n程序段运行时间:" << static_cast<double> (end_time - start_time) / CLOCKS_PER_SEC * 1000 << "ms" << endl;system("pause");
}
void Sort(int List[], int n)
{bool sorted = false; //整体排序标志标志,首先假定尚未排序while (!sorted){sorted = true; //假定已经排序for (int j = 1; j < n -1; j++) //j<n-i-1:首先j不与自己比较所以-1,其次每次外循环都会产生一个已经排序的最大数,所以内循环要排除已经排好的,即总数为n-i。if (List[j - 1] > List[j]){swap(List[j - 1], List[j]);sorted = false;//因整体排序不能保证,需要清除排序标志}}n--;//至此元素必然就位,故可以缩短待排序序列的有效长度}//借助布尔型标志位sorted,可及时提前退出,而丌致总是蛮力地做n - 1趟扫描交换

选择排序 自带时间复杂度分析

从当前未排序的整数中找到最小的整数,将它放在已排序的整数列表的最后。
#include<iostream>
#include<time.h>
using namespace std;void Sort(int List[], int n);int main()
{int a[10000];int k, j;// 设置种子srand((unsigned)time(NULL));/* 生成 10 个随机数 */for (k = 0; k < 10000; k++){// 生成实际的随机数j = rand();a[k] = j;}clock_t start_time = clock();Sort(a, 10000);clock_t end_time = clock();for (int i = 0; i < 10000; i++){cout << a[i] << " ";}cout << "\n程序段运行时间:" << static_cast<double> (end_time - start_time) / CLOCKS_PER_SEC * 1000 << "ms" << endl;system("pause");
}
void Sort(int List[], int n)
{for (int i = 0; i < n - 1; i++){int min = i;//min处,假设第一个是最小的,是;数组的下标for (int j = i + 1; j < n; j++) //j=i+1是因为之前已经扫描过了{if (List[j] < List[min]){min = j;    //移动记录下来}}swap(List[i], List[min]);   //扫描一遍结束后,交换一次}
}

选择排序与冒泡排序的区别

冒泡排序:
 
冒泡排序(BubbleSort)的基本概念是:依次比较相邻的两个数,将小数放在前面,大数放在后面。即在第一趟:首先比较第1个和第2个数,将小数放前,大数 放后。
 
然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后。至此第一趟结束,将最大的数放到了最后。
 
在第二趟:仍从第一对数开始比较(因为可能由于第2个数和第3个数的交换,使得第1个数不再小于第2个数),将小数放前中,大数放后,一直比较到倒数第二个数(倒数第一的位置上已经是最大的),第二趟结束,在倒数第二的位置上得到一个新的最大数(其实在整个数列中是第二大的数)。如此下去,重复以上过程,直至最终完成排序。
 
选择排序
 
第一次从下标为0的开始下标为0的这个数与后面的n-1个进行比较;找出最小或者最大的放在下标为0的这个位置;第二次从下标为1的开始比较;查询剩下的最大或者最小值;放在下标为1的位置;以此类推;直到排序完成。
 
总结
 
从上两段代码可以看出,它们处于同一个数量级,即时间复杂度是相同的,都用了两层循环,为O(n^2)(n:排序个数); 但是内层循环中,冒泡排序的互换位置的操作从概率上讲要明显多于选择排序. 整个排序算法,选择排序换位操作为O(n),冒泡排序为O(n^2/2). 所以综合来讲选择排序的时间效率要高于冒泡排序.

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

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

相关文章

ios点击大头针气泡不弹出_iOS高德地图之自定义大头针and泡泡view

啥都不说先看效果图demoIMG_0270.PNG先来说说如何自定义大头针以及点击大头针时弹出的泡泡view一 : 自定义大头针新建CustomAnnotationView 继承自MAAnnotationView添加属性重写- (id)initWithAnnotation:(id)annotation reuseIdentifier:(NSString *)reuseIdentifier重写- (BO…

数据结构【单调栈】

详细解读 至此我们可以解答最开始的疑问&#xff0c;单调栈的根本作用在于求得「每一个数字在原始序列中左 / 右边第一个大于 / 小于它自身的数字」&#xff0c;并且由于每一个数字只会入栈一次且最多出栈一次&#xff0c;因此总的时间复杂度为 O ( n ) 。 另外需要注意&#…

java名 java_Java Syncrhonisers

java名 java线程通信主要通过共享对字段和对象的访问来发生。 尽管这种通信方式非常高效&#xff0c;但它易于出现诸如线程干扰和内存一致性之类的错误。 同步是一种有助于防止此类错误的工具。 但是&#xff0c;同步不是免费提供的&#xff0c;并且在访问当前由另一个线程持有…

leetcode(二分查找算法专题)

二分模板一共有两个&#xff0c;分别适用于不同情况。 算法思路&#xff1a;假设目标值在闭区间[l, r]中&#xff0c; 每次将区间长度缩小一半&#xff0c;当l r时&#xff0c;我们就找到了目标值。 * 其中mid需要在while内部进行更新 * 最小R&#xff0c;最大L , R来加&…

html 完全复制div中的内容_LOL手游现在远非完全体,未来还有哪些端游内容会加入手游中?...

LOL手游上线已经有一段时间了&#xff0c;虽然绝大多数情况下LOL端游的内容被继承到了手游当中&#xff0c;但是仍然有一部分端游的内容尚未出现在手游之内。今天小编就带领大家来盘点一下&#xff0c;那些未来可能出现在手游当中的端游内容。排位赛ban选英雄机制Moba游戏排位赛…

因此,Oracle杀死了java.net

好吧&#xff0c;还没有……但是他们宣布要在2017年5月之前关闭java.net和 kenai。JohnK . Waters 在ADTmag的Kenai和java.net的“ Sunset”一文中接受了我的采访。 由于Oracle很少提供有关已经托管在java.net上的关键项目会发生什么的信息&#xff0c;因此本文中编写的大部分…

【Python科学计算系列】概率论与数理统计

计算排列数 def arrangement(n, m):if n m:return math.factorial(n)else:return math.factorial(n) / math.factorial(n - m) 计算组合数 def arrangement(n, m):return math.factorial(n) / (math.factorial(m) * math.factorial(n - m))

proc编译手册_Expect 手册 中文版

Expect 手册 中文版本文由gunman翻译&#xff0c;在此感谢&#xff5e;EXPECT(1)名字&#xff1a;Expect-----能与交互式程序进行“可程序化”会话的脚本语言大纲&#xff1a;(命令选项概述)expect [ -dDinN ] [ -c cmds ] [ -[f|b] ] cmdfile ] [ args ]概述&#xff1a;Expec…

光盘 机密_使用保险柜管理机密

光盘 机密您如何存储秘密&#xff1f; 密码&#xff0c;API密钥&#xff0c;安全令牌和机密数据属于秘密类别。 那是不应该存在的数据。 在容易猜测的位置&#xff0c;不得以纯文本格式提供。 实际上&#xff0c;不得在任何位置以明文形式存储它。 可以使用Spring Cloud Confi…

OS X下使用OpenGL做离屏渲染

本文为转载内容&#xff0c;原地址 有时&#xff0c;我们想通过GPU做一些视频、图像处理&#xff0c;而处理的结果不需要显示在显示器上&#xff0c;而是直接交给主存&#xff0c;这时候我们可以通过OpenGL的离屏渲染来实现。 由于我们不需要将渲染好的像素显示到屏幕上&…

jpa 循环引用_JPA中按身份引用

jpa 循环引用在上一篇文章中 &#xff0c;我提到我选择通过其主键而不是类型来引用其他聚合。 在处理大型或复杂域模型时&#xff0c;我通常使用这种方法&#xff08;也称为断开域模型&#xff09;。 在本文中&#xff0c;让我尝试进一步解释如何在JPA中完成它。 请注意&#x…

自然辩证法小论文选题_自然辨证法论文题目

与《自然辨证法论文题目》相关的范文2010年研究生课程论文 成绩: 题目:_中西医结合的发展前景_ _ 中西医结合的发展前景 [摘要]立足于中西医结合的现状,从方法论角度,就中西医融合的时间进行了探讨.中西医结合,是在我国既有传统的中医药学,又有现代的西医药学的特定环境和条件下…

Leetcode 14.最长公共前缀

原题链接 解题思路: 1.本题使用模拟法 2.取第一个字符串的首元素&#xff0c;与剩余字符串对应位置相比较&#xff0c;如果全部相等将此字符加入结果中&#xff0c;继续到下一个字符一次比较&#xff0c;直至出现不相同的位置&#xff0c;返回结果。 3.需要注意每个字符串是…

aws lambda_带有API网关的AWS Lambda

aws lambda在上一篇文章中&#xff0c;我向您展示了如何创建和部署AWS Lambda。 我们将继续这项工作&#xff0c;并只考虑更新该lambda的代码。 我们还将使用AWS API Gateway将REST端点添加到AWS Lambda。 因此&#xff0c;在继续之前……&#xff08;如果还没有&#xff09;&…

git pull不同步_git回退版本,再返回最新分支git pull失败的解决经验

本文转载自【微信公众号&#xff1a;羽林君&#xff0c;ID&#xff1a;Conscience_Remains】总述一篇解决gti分支切换问题的文章&#xff0c;大家应该都有过这种情况&#xff0c;就是git最新的代码进行编译的时候&#xff0c;发现最新代码有bug&#xff0c;有些不确认问题点&am…

junit5 动态测试_JUnit 5 –动态测试

junit5 动态测试在定义测试时&#xff0c;JUnit 4有一个很大的弱点&#xff1a;它必须在编译时发生。 现在&#xff0c;JUnit 5将解决此问题&#xff01; Milestone 1 刚刚发布 &#xff0c;它带有全新的动态测试&#xff0c;可以在运行时创建测试。 总览 本系列中有关JUnit 5…

ioc spring 上机案例_通过实例解析Spring Ioc项目实现过程

0. Ioc主要是实现一个控制反转&#xff0c;耦合性大大降低。1. 建maven项目建立一个空的maven项目&#xff0c;然后pom.xml添加spring-context的依赖:org.springframeworkspring-context5.2.7.RELEASE2. 创建pojo java对象package com.aca;public class Hello {private String …

C++ 11 深度学习(十)原始字面量

你是否曾经为了各种json格式无法写入string中而烦恼&#xff0c;为了各种转义而烦恼。如下图 c11为我们带来了全新的解决方法 其新特性为使用. R"(xxxxxxxxxxxx)" ,此种形式可以使得以原有形式进行表现出来

java日期时间转日期_Java时间和日期指南

java日期时间转日期长期以来&#xff0c;正确处理日期&#xff0c;时间&#xff0c;时区&#xff0c;夏令时&#xff0c;and年等一直是我的烦恼。 本文并不是一个全面的指南时域&#xff0c;请参阅日期和时间在Java中 -更详细&#xff0c;但略有下降&#xff0c;ekhem&#xff…