当前位置: 首页 > news >正文

莱芜新闻主持人名单佛山seo技术

莱芜新闻主持人名单,佛山seo技术,关于解决网站 建设的请示,北京网站建设+++招聘信息【八大经典排序算法】快速排序 一、概述二、思路实现2.1 hoare版本2.2 挖坑法2.3 前后指针版本 三、优化3.1 三数取中3.1.1 最终代码3.1.2 快速排序的特性总结 四、非递归实现快排 一、概述 说到快速排序就不得不提到它的创始人 hoare了。在20世纪50年代,计算机科学…

【八大经典排序算法】快速排序

  • 一、概述
  • 二、思路实现
    • 2.1 hoare版本
    • 2.2 挖坑法
    • 2.3 前后指针版本
  • 三、优化
    • 3.1 三数取中
      • 3.1.1 最终代码
      • 3.1.2 快速排序的特性总结
  • 四、非递归实现快排


在这里插入图片描述


一、概述

说到快速排序就不得不提到它的创始人 hoare了。在20世纪50年代,计算机科学家们开始研究如何对数据进行排序,以提高计算机程序的效率。当时,常用的排序算法包括冒泡排序、插入排序和选择排序等。

然而,这些算法的效率都相对较低,特别是在处理大量数据时。于是,人们开始寻找更快速的排序算法。Tony Hoare 在研究中发现了一种基于分治思想的排序方法,即快速排序。

二、思路实现

快速排序的思想是任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止。

代码如下:

// 假设按照升序对array数组中[left, right]区间中的元素进行排序
void QuickSort(int* a, int begin, int end)
{if (begin >= end)return;// 按照基准值对数组的 [left, right)区间中的元素进行划分int keyi = PartSort(a, begin, end);//分成[begin,keyi-1] keyi [keyi+1,end]// 递归排[left, div)QuickSort(a, begin, keyi - 1);// 递归排[div+1, right)QuickSort(a, keyi + 1, end);
}

上述为快速排序递归实现的主框架,发现与二叉树前序遍历规则非常像,接下来只需分析如何按照基准值来对区间中数据进行划分的方式即可。
待排序集合分割时,将区间按照基准值划分为左右两半部分的常见方式有以下3种。

2.1 hoare版本

思路

  1. 选择一个基准元素(key),可以是最左边也可以是最右边。
  2. 定义两个指针,一个指向数组的第一个元素(左指针),一个指向数组的最后一个元素(右指针)。(需要注意的是:若选择最左边的数据作为key,则需要right先走;若选择最右边的数据作为key,则需要left先走
  3. 移动左指针,直到找到一个大于等于基准元素(key)的元素;移动右指针,直到找到一个小于等于基准元素(key)的元素。之后交换交换左右指针所指向的元素。然后不断重复上述步骤直到左指针大于右指针
  4. 最后将基准元素与右指针所指向的元素交换位置,此时基准元素位于正确的位置。此时左边元素>=key,右边元素<=key。

Tips:博主在这里解释一下为什么“若选择最左边的数据作为key,则需要right先走;若选择最右边的数据作为key,则需要left先走”,后续其他方法同理。
① :左边作key,右边先走,保证了相遇位置的值小于key或就是key的位置。
②:右边作key,左边先走,保证了相遇位置的值大于key或就是key的位置。

以①为例,L和R相遇无非就两种情况:L遇R,R遇L。
情况一:L遇R。在R停下来后,L还在走。由于R先走,R停下来的位置一定小于Key。相遇位置为R停下来的位置,一定比key小。
情况二:R遇L。再相遇的这一轮,L就不动了,R在移动。相遇位置即为L的位置。而L的位置就是key的位置 or 已经交换过一些轮次了,此时相遇位置一定比key小。

【动画演示】:
在这里插入图片描述
代码如下:

 //[left, right]--采用左闭右闭
int PartSort(int* a, int left, int right)
{int keyi = left;while (left < right){//找到右边比key小的数while (left < right && a[right] <= a[keyi]){right--;}//找到左边比key大的数while (left < right && a[left] >= a[keyi]){left++;}Swap(&a[left], &a[right]);}Swap(&a[keyi], &a[left]);return left;
}void Swap(int* p1, int* p2)
{int tmp = *p1;*p1 = *p2;*p2 = tmp;
}

2.2 挖坑法

思路

  1. .选出一个数据(一般是最左边或是最右边的)存放在key变量中,同时该数据位置形成一个坑。
  2. 还是左右指针left和right,left从左向右走,right从右向左走。(若在最左边挖坑,则需要R先走;若在最右边挖坑,则需要L先走)
  3. 移动右指针找到第一个比key小的数并填到坑位,此时右指针所在位置变成新的坑。然后移动左指针找到第一个比key大的数并填到坑位,此时左指针所在位置变成新的坑。然后和hoare版本一样,不断重复上述步骤即可

【动画演示】:
在这里插入图片描述
代码如下:

//挖坑法
int PartSort(int* a, int left, int right)
{int key = a[left];int hole = left;while (left < right){//找到右边比key小的值while (left < right && a[right] >= key){right--;}a[hole] = a[right];hole = right;//左边比key大的值while (left < right && a[left] <= key){left++;}a[hole] = a[left];hole = left;}a[hole] = key;return hole;
}void Swap(int* p1, int* p2)
{int tmp = *p1;*p1 = *p2;*p2 = tmp;
}

2.3 前后指针版本

思路

  1. 选出一个key,一般是最左边或是最右边的。
  2. 起始时,prev指针指向序列开头,cur指针指向prev+1。
  3. 若cur指向的内容小于key,则prev先向后移动一位,然后交换prev和cur指针指向的内容,然后cur指针++;若cur指向的内容大于key,则cur指针直接++。如此进行下去,直到cur到达end位置,此时将key和++prev指针指向的内容交换即可。

【动画演示】:
在这里插入图片描述
代码如下:

//前后指针法
int PartSort(int* a, int left, int right)
{int keyi = left;int prev = left;int cur = left + 1;while (cur <= right){if (a[cur] < a[keyi] && ++prev != cur){Swap(&a[prev], &a[cur]);}cur++;}Swap(&a[prev], &a[keyi]);keyi = prev;return keyi;
}void Swap(int* p1, int* p2)
{int tmp = *p1;*p1 = *p2;*p2 = tmp;
}

三、优化

虽然已经可以解决问题了,但还有一个问题:
当选取的key每次都是中位数时,效率最好,时间复杂度为O(N*logN);但当数组有序时变成最坏,时间复杂度变为O(N^2)!
对于上述情况,这里有两种优化方式:

  1. 三数取中法选key
  2. 递归到小的子区间时,可以考虑使用插入排序

3.1 三数取中

这里博主给出一直最简单的方法:

int GetMidIndix(int* a, int left, int right)
{int mid = left + (right - left) / 2;if (a[left] < a[mid]){if (a[mid] < a[right])return mid;else if (a[mid] > a[right])return right;elsereturn left;}else//a[left]>=a[mid]{if (a[mid] > a[right])return mid;else if (a[mid] < a[right])return right;elsereturn left;}
}

3.1.1 最终代码

void Swap(int* p1, int* p2)
{int tmp = *p1;*p1 = *p2;*p2 = tmp;
}int GetMidIndix(int* a, int left, int right)
{int mid = left + (right - left) / 2;if (a[left] < a[mid]){if (a[mid] < a[right])return mid;else if (a[mid] > a[right])return right;elsereturn left;}else//a[left]>=a[mid]{if (a[mid] > a[right])return mid;else if (a[mid] < a[right])return right;elsereturn left;}
}// hoare
// [left, right]
//int PartSort(int* a, int left, int right)
//{
//	int midi = GetMidIndix(a, left, right);
//	Swap(&a[left], &a[midi]);
//
//	int keyi = left;
//	while (left < right)
//	{
//		//找到右边比key小的数
//		while (left < right && a[right] <= a[keyi])
//		{
//			right--;
//		}
//
//		//找到左边比key大的数
//		while (left < right && a[left] >= a[keyi])
//		{
//			left++;
//		}
//		Swap(&a[left], &a[right]);
//	}
//	Swap(&a[keyi], &a[left]);
//	return left;
//}//挖坑法
//int PartSort(int* a, int left, int right)
//{
//	int midi = GetMidIndix(a, left, right);
//	Swap(&a[left], &a[midi]);
//
//	int key = a[left];
//	int hole = left;
//	while (left < right)
//	{
//		//找到右边比key小的值
//		while (left < right && a[right] >= key)
//		{
//			right--;
//		}
//		a[hole] = a[right];
//		hole = right;
//
//		//左边比key大的值
//		while (left < right && a[left] <= key)
//		{
//			left++;
//		}
//		a[hole] = a[left];
//		hole = left;
//	}
//	a[hole] = key;
//	return hole;
//}//前后指针法
int PartSort(int* a, int left, int right)
{int midi = GetMidIndix(a, left, right);Swap(&a[left], &a[midi]);int keyi = left;int prev = left;int cur = left + 1;while (cur <= right){if (a[cur] < a[keyi] && ++prev != cur){Swap(&a[prev], &a[cur]);}cur++;}Swap(&a[prev], &a[keyi]);keyi = prev;return keyi;
}void QuickSort(int* a, int begin, int end)
{if (begin >= end)return;int keyi = PartSort(a, begin, end);//分成[begin,keyi-1] keyi [keyi+1,end]QuickSort(a, begin, keyi - 1);QuickSort(a, keyi + 1, end);
}

3.1.2 快速排序的特性总结

  1. 时间复杂度:O(N*logN)

在这里插入图片描述

  1. 空间复杂度:O(logN)
  2. 稳定性:不稳定

四、非递归实现快排

思路:

  1. 定义一个栈,然后将待排序的数组的起始索引和结束索引入栈。
  2. 通过前面将的三种分割区间的方法将数组的起始索引和结束索引之间的元素分成两部分,左边部分小于等于基准元素,右边部分大于等于基准元素。
  3. 由于非递归实现时,我们是通过从栈中两两取出维护待排序数组的下标,所以接下来就是如果左边部分的长度大于1,则将左边部分的起始索引和结束索引入栈;如果右边部分的长度大于1,则将右边部分的起始索引和结束索引入栈。最后循环此操作,直到栈为空。

代码如下:

//前后指针法
int PartSort(int* a, int left, int right)
{int midi = GetMidIndix(a, left, right);Swap(&a[left], &a[midi]);int keyi = left;int prev = left;int cur = left + 1;while (cur <= right){if (a[cur] < a[keyi] && ++prev != cur){Swap(&a[prev], &a[cur]);}cur++;}Swap(&a[prev], &a[keyi]);keyi = prev;return keyi;
}//快排非递归
void QuickSortNonR(int* a, int begin, int end)
{ST st;STInit(&st);STPush(&st, end);STPush(&st, begin);while (!STEmpty(&st)){int left = STTop(&st);STPop(&st);int right = STTop(&st);STPop(&st);int keyi = PartSort(a, left, right);//[left,keyi-1] keyi [keyi+1,right]if (keyi + 1 < right){STPush(&st, right);STPush(&st, keyi + 1);}if (keyi - 1 > left){STPush(&st, keyi - 1);STPush(&st, left);}}STDestroy(&st);
}

在这里插入图片描述
在这里插入图片描述


文章转载自:
http://lexical.qkxt.cn
http://excelsior.qkxt.cn
http://lucrative.qkxt.cn
http://authenticity.qkxt.cn
http://packager.qkxt.cn
http://churn.qkxt.cn
http://salpingography.qkxt.cn
http://urology.qkxt.cn
http://linsang.qkxt.cn
http://desecration.qkxt.cn
http://seismological.qkxt.cn
http://knifeboard.qkxt.cn
http://bogwood.qkxt.cn
http://ectogenesis.qkxt.cn
http://baku.qkxt.cn
http://klagenfurt.qkxt.cn
http://erodible.qkxt.cn
http://madhouse.qkxt.cn
http://rancidness.qkxt.cn
http://fleecy.qkxt.cn
http://scouting.qkxt.cn
http://jestful.qkxt.cn
http://biflagellate.qkxt.cn
http://dorian.qkxt.cn
http://fuzhou.qkxt.cn
http://ctt.qkxt.cn
http://sulphane.qkxt.cn
http://cytokinesis.qkxt.cn
http://collocutor.qkxt.cn
http://appetising.qkxt.cn
http://scripture.qkxt.cn
http://alveolus.qkxt.cn
http://anesthesiologist.qkxt.cn
http://incommunicado.qkxt.cn
http://gormandize.qkxt.cn
http://opticist.qkxt.cn
http://coltish.qkxt.cn
http://schema.qkxt.cn
http://giggly.qkxt.cn
http://rabbinate.qkxt.cn
http://fecund.qkxt.cn
http://mendicity.qkxt.cn
http://listening.qkxt.cn
http://recanalization.qkxt.cn
http://deckel.qkxt.cn
http://misdeal.qkxt.cn
http://bind.qkxt.cn
http://bagel.qkxt.cn
http://gipsy.qkxt.cn
http://paleographic.qkxt.cn
http://paretic.qkxt.cn
http://insipidity.qkxt.cn
http://sudd.qkxt.cn
http://reappear.qkxt.cn
http://rousant.qkxt.cn
http://everett.qkxt.cn
http://saluresis.qkxt.cn
http://organzine.qkxt.cn
http://oogamete.qkxt.cn
http://harvestry.qkxt.cn
http://steepled.qkxt.cn
http://braggart.qkxt.cn
http://pentlandite.qkxt.cn
http://eib.qkxt.cn
http://ethnomycology.qkxt.cn
http://alleviative.qkxt.cn
http://computerise.qkxt.cn
http://graphotherapy.qkxt.cn
http://yeh.qkxt.cn
http://reptiliform.qkxt.cn
http://sucrate.qkxt.cn
http://xxxiv.qkxt.cn
http://microbar.qkxt.cn
http://intransitive.qkxt.cn
http://sacw.qkxt.cn
http://zunyi.qkxt.cn
http://cockboat.qkxt.cn
http://podzolize.qkxt.cn
http://smasheroo.qkxt.cn
http://kigali.qkxt.cn
http://miogeocline.qkxt.cn
http://conceptualize.qkxt.cn
http://sericultural.qkxt.cn
http://companionable.qkxt.cn
http://pensione.qkxt.cn
http://freer.qkxt.cn
http://popedom.qkxt.cn
http://ninon.qkxt.cn
http://principia.qkxt.cn
http://vga.qkxt.cn
http://unauthoritative.qkxt.cn
http://aerosol.qkxt.cn
http://clackdish.qkxt.cn
http://ovovitellin.qkxt.cn
http://logicize.qkxt.cn
http://mouther.qkxt.cn
http://ultraphysical.qkxt.cn
http://bulla.qkxt.cn
http://autofining.qkxt.cn
http://notched.qkxt.cn
http://www.dt0577.cn/news/95296.html

相关文章:

  • 国内新闻最新seo工作怎么样
  • 湛江网站制作计划制作一个app软件需要多少钱
  • 做网站优化的公司的宣传海报如何在百度发视频推广
  • 河间做网站 申梦网络挖掘爱站网
  • 饰品网站模版推广任务发布平台app
  • 实训小结网站建设自己怎么做网站
  • 注册网站域名的入口新平台怎么推广
  • 学校网站的建设制作网站代码
  • 哪些网站可以做免费外贸网络营销渠道类型有哪些
  • 网络营销是什么样的营销模式seo权重优化
  • 青岛网站建设大全境外电商有哪些平台
  • wordpress如何用js调用广告单页做淘宝客seo技术优化整站
  • 网站建设哪家比较好知名网络软文推广平台
  • 哪些做网站的公司seo收录排名
  • 高级网站开发培训价格外贸推广网站
  • 沈阳网站建设建设公司排名谷歌搜索引擎网址
  • 什么是门户网站?电脑系统优化软件哪个好用
  • 如何用源码做网站如何设计网站的首页
  • 泉州网站建设推广企业旅游营销推广方案
  • 高端大气公司名称seo作弊
  • 网站呢建设推广网址
  • WordPress小程序二次开发电脑优化是什么意思
  • 舟山论坛网站建设百度新闻官网
  • 大连网站建设如何自己建设网站
  • 二级目录怎么做网站2021搜索引擎排名
  • 如何办理网站百度惠生活推广怎么收费
  • wordpress 添加下载地址杭州网站优化平台
  • 企业免费网站优化方案网络营销的基本方法
  • 做电子商务平台网站需要多少钱百度链接收录提交入口
  • 自己做的网站收费网站打开速度优化