算法学习笔记(5.1)-基于比较的高效排序算法(快速排序,堆排序)

##时间复杂度O(NlogN)

目录

##时间复杂度O(NlogN)

##快速排序

##原理

##图例

##代码实现

##堆排序

##原理

##图例

##代码实现


##快速排序

##原理

快速排序的核心操作是“哨兵划分”,其目标是:选择数组中的某个元素作为“基准数”,将所有小于基准数的元素移到其左侧,而大于基准数的元素移到其右侧。

1.选取数组最左端作为基准数,初始化两个指针 i 和 j 分别指向数组的两端

2.设置一个循环,在每轮使用中 i(j)分别寻找第一个比基准数大(小)的元素,然后交换这个元素

3.循环执行步骤2,直到 i 和 j 相遇时停止,最后将基准值交换至两个子数组的分界线 

##图例

##代码实现

#python代码示例
def partition(a, left, right) :"""哨兵划分-以a[left]为基准数"""i , j = left , rightwhile i < j :while i < j and a[j] >= a[left] :j -= 1while i < j and a[i] <= a[left] :i += 1a[i] , a[j] = a[j] , a[i]a[i] , a[left] = a[left] , a[i]return i def quick_sort(a, left, right) :if left >= right :return pivot = partition(a, left, right)quick_sort(a, left, pivot - 1 )quick_sort(a, pivot + 1 , right)
//c++代码示例
void swap(vector<int> &nums, int i , int j)
{int tmp = nums[i] ;nums[i] = nums[j] ;nums[j] = tmp ;
}int partition(vector<int> &nums, int left , int right)
{int i = left ;int j = right ;while ( i < j ){while (i < j && nums[j] >= nums[left]){j-- ;}while (i < j && nums[i] <= nums[left]){i++ ;}swap(nums, i, j) ;}swap(nums, i , left) ;return i ;
}void quickSort(vector<int> &a, int left, int right)
{if (left >= right){return ;}int pivot = partition(a, left, right) ;quickSort(a, left ,pivot - 1) ;quickSort(a, pivot + 1 , right) ;
}
#python代码示例
#快速排序
def QuickSortPivot(a, start, end) :pivot = startj = start + 1for i in range(start + 1 , end + 1) :if a[i] <= a[pivot] :a[i],a[j] = a[j],a[i]j += 1a[pivot],a[j-1] = a[j-1],a[pivot]pivot = j - 1print(a[pivot],a[start:pivot],a[pivot+1:end+1])return pivotdef QuickSortt(a, start, end) :if start >= end :returnpivot = QuickSortPivot(a,start,end)QuickSortt(a,start,pivot - 1)QuickSortt(a,pivot + 1,end)a = [8,5,12,6,4,3,7,9,2,1,10,11]
QuickSortt(a,0,len(a)-1)print()#随机快速排序-避免最坏情况的发生
import random
def RandomQuickSortPivot(a, start, end) :randomIdx = random.randint(start,end)a[randomIdx],a[start] = a[start],a[randomIdx]pivot  = startj = start + 1for i in range(start+1,end+1) :if a[i] <= a[pivot] :a[i],a[j] = a[j],a[i]j += 1a[pivot],a[j-1] = a[j-1],a[pivot]pivot = j - 1print(a[pivot],a[start:pivot],a[pivot+1:end+1])return pivotdef RandomQucikSort(a, start, end) :if start >= end :returnpivot = RandomQuickSortPivot(a, start, end)RandomQucikSort(a,start,pivot-1)RandomQucikSort(a,pivot+1,end)
a = [1,2,3,4,5,6,7,8,9,10,11,12]
RandomQucikSort(a,0,11)

##堆排序

##原理

基于堆(完全二叉树)数据结构实现的一种高效的算法

 构造堆

1.完全二叉树,从根节点开始,按照层序遍历,一定可以唯一的映射到顺序表中

2.idx = x 当前根节点的索引,idxLeft = idx * 2,idxRight = idx * 2 + 1

随机顺序表构造成为一个大顶堆(小顶堆)

1.从顺序表的最后一个元素开始自底向上的构造堆

2.对于某个元素取它左右子树中的大(小)者,如果比该元素大(小)则与该元素进行交换,直到叶子节点为止(下沉操作)

3.因为每个堆的子树都是满足堆的性质,当枚举完根节点后,这个大(小)顶堆就构造完成了

怎么实现堆排序呢

1.因为构造堆操作完成后,整个顺序表并不是一个排好序的数组

2.已知条件,堆数组的第一个元素,总是最大或者最小的,我们只需要第一个元素与最后一个元素进行交换,然后去掉被交换掉的对顶元素,重新构造成一个大(小)顶堆

3.重复操作2,直至剩余一个元素

##图例

##代码实现

#python代码示例
#堆排序-借助(堆)完全二叉树的性质来完成
#大顶堆的下沉操作
def maxHeapify(heap, start, end) :#start为堆的根节点标号,表示start - end 区间构成一个合法的堆son = start * 2 #左子树while son <= end : #左子树存在#判断右子树if son + 1 <= end and heap[son+1] > heap[son] :son += 1if heap[son] > heap[start] :heap[start] , heap[son]  = heap[son] , heap[start]start , son = son , son * 2 #继续往下找直至叶子节点else :breakdef HeapSort(a) :heap = [None] + a #下标从1开始,加上一个占位符root = 1 #根节点节点编号l = len(heap) #获取对元素个数for i in range(l-1,root-1,-1) : #自底向上构造堆maxHeapify(heap,i,l-1)for i in range(l-1,root,-1) : #使第一个元素与最后一个元素发生交换heap[i],heap[root] = heap[root] , heap[i]maxHeapify(heap,root,i-1)return heap[root:]
a = [1,2,3,4,5,6,7,8,9,10,11,12,13,14]
print(HeapSort(a))
#python代码示例
def sift_down(a, n , i) :"""堆的长度为n,从节点i开始,从顶至底堆化"""while True :#考虑到数组下标从0开始l = 2 * i + 1r = 2 * i + 2ma = iif l < n and a[l] > a[ma] :ma = lif r < n and a[r] > a[ma] :ma = rif ma == i :breaka[i],a[ma] = a[ma],a[i]i = madef heap_sort(a) :"""堆排序""""""构建堆,堆化除了叶子节点之外得到其他所有节点"""for i in range(len(a) // 2 - 1 , -1, -1) :sift_down(a,len(a) , i)#交换最大元素-保持堆的合法性for i in range(len(a)-1,0,-1):a[0],a[i] = a[i],a[0]sift_down(a,i,0)return a
a = [1,2,3,4,5,6,7,8,9,10,11,12,13,14]
print(heap_sort(a))
//c++代码示例
void swap(a,int i ,int j)
{int tmp = a[i] ;a[i] = a[j] ;a[j] = tmp ;
}void siftDown(vector<int> &a, int n , int i)
{while (true){int l = i * 2 + 1 ;int r = i * 2 + 2 ;int ma = i ;if (l < n && a[l] > a[ma]){ma = l ; }if (r < n && a[r] > a[ma]){ma = r ;}if (ma == i){break ;}swap(a[i],a[ma]) ;i = ma ;}
}void heapSor(vector<int> &a)
{for (int i = a.size()/2-1 ; i >=0 ; --i){siftDown(a,a.size(),i) ;}for (int i = a.size()-1; i > 0 ; --i){swap(a[0],a[i]) ;siftDown(a,i,0) ;}
}

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

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

相关文章

【编译原理复习笔记】语法分析(一)

分类 语法分析可以按照分析方向分为两类 自顶向下/自底向上 自顶向下的分析 从分析树的顶部向底部方向构造分析树 每一步推导需要做两个选择&#xff1a; &#xff08;1&#xff09;需要替换哪个非终结符 &#xff08;2&#xff09;用哪个产生式 最左推导 在最左推导中&am…

【重学C++】02 脱离指针陷阱:深入浅出 C++ 智能指针

前言 大家好&#xff0c;今天是【重学C】系列的第二讲&#xff0c;我们来聊聊C的智能指针。 为什么需要智能指针 在上一讲《01 C如何进行内存资源管理》中&#xff0c;提到了对于堆上的内存资源&#xff0c;需要我们手动分配和释放。管理这些资源是个技术活&#xff0c;一不…

正点原子LWIP学习笔记(一)lwIP入门

lwIP入门 一、lwIP简介&#xff08;了解&#xff09;二、lwIP结构框图&#xff08;了解&#xff09;三、如何学习lwIP&#xff08;熟悉&#xff09; 一、lwIP简介&#xff08;了解&#xff09; lwIP是一个小型开源的TCP/IP协议栈 阉割的TCP/IP协议 TCP/IP协议栈结构&#xff0…

C语言游戏实战(12):植物大战僵尸(坤版)

植物大战僵尸 前言&#xff1a; 本游戏使用C语言和easyx图形库编写&#xff0c;通过这个项目我们可以深度的掌握C语言的各种语言特性和高级开发技巧&#xff0c;以及锻炼我们独立的项目开发能力&#xff0c; 在开始编写代码之前&#xff0c;我们需要先了解一下游戏的基本规则…

基础2 JAVA图形编程桌面:探索图形程序的抽象实现

嘿&#xff0c;大家好&#xff01;我非常高兴又一次有机会与大家相聚&#xff0c;分享新的知识和经验。对于热爱编程和探索新技术的朋友们来说&#xff0c;今天的内容绝对不容错过。我为大家准备了一个详尽的视频教程&#xff1a;《基础2 JAVA 图形编程&#xff1a;主程序调用…

git拉取项目前需要操作哪些?

1.输入 $ ssh-keygen -t rsa -C "秘钥说明" 按enter键 2.出现 ssh/id_rsa&#xff1a;(输入也可以不输入也可以) 然后按enter键 3.出现empty for no passphrase&#xff1a;(输入也可以不输入也可以) 然后按enter键 4.出现same passphrase again: (输入也可以不输入也…

20240516-Flyme AIOS 特种兵发布会

目录 1 Flyme AIOS 2 路演功能 2.1 拖拽流转 2.2 任务剧本自定义 2.3 智能体商店 2.4 实况通知 2.5 AI壁纸 3 MYVU 3.1 翻译功能 3.2 AR导航-骑行 3.3 AI语音转文字-科技向善 3.4 Flyme AR-提词器增强 1 Flyme AIOS 1&#xff09;目标&#xff1a;All in AI&#…

AI绘图Stable Diffusion,如何无损高清放大图片,保姆级教程建议收藏!

前言 我们在用 stable diffusion 制作AI图片时&#xff0c;默认生成图片的尺寸为512*512&#xff0c;即使是竖图一般也就是512*768&#xff0c;如果再把尺寸设置大一些&#xff0c;就会因为硬件算力不够而造成系统崩溃&#xff0c;今天就来跟大家聊一聊&#xff0c;如何将制作…

RocketMQ-Dashboard 控制台使用详解

1 安装部署 具体部署启动请参考&#xff1a;RocketMQ从安装、压测到运维一站式文档_rocketmq benchmark压测-CSDN博客 RocketMq的dashboard&#xff0c;有运维页面&#xff0c;驾驶舱&#xff0c;集群页面&#xff0c;主题页面&#xff0c;消费者页面&#xff0c;生产者页面&…

【Kubenetes】边缘计算KubeEdge架构设计详解

文章目录 前言KubeEdge云边通信方式云端架构设计EdgeController:云到边&#xff1a;边到云 DeviceController:云到边边到云 边缘端架构设计EdgedPod的管理部分Pod的监控部分Pod的卷管理Pod的垃圾回收Pod同步管理 MetaMangger从云到边缘的更新 (Update From Cloud To Edge)从边缘…

Covalent长期数据设施,支持基于 “blob” 、总锁仓54亿美元的L2

Covalent Network&#xff08;CQT&#xff09;是领先的历史数据可用性网络&#xff0c;通过其在 Web3 中超过 225 个区块链上的结构化数据基础设施&#xff0c;为数千名客户和开发人员提供支持。Covalent Network&#xff08;CQT&#xff09;正在与未来以太坊的进步需求相匹配&…

SQL慢查询学习篇

https://www.cnblogs.com/isyues/p/17733015.html 1. 对扫到的SQL慢查询语句执行 explain explain select task_id, channel, count(task_id) as count from tablename where send_time > "2024-05-10 16:13:59" and send_time < "2024-05-14 16:13:59…

api接口、api文档、api调试、api测试

应用程序接口是一组定义、程序及协议的集合&#xff0c;通过 API 接口实现计算机软件之间的相互通信。API 的一个主要功能是提供通用功能集。程序员通过调用 API 函数对应用程序进行开发&#xff0c;可以减轻编程任务。 API 同时也是一种中间件&#xff0c;为各种不同平台提供数…

展馆展厅设计施工流程

1、需求分析和确定&#xff1a; 与客户沟通&#xff0c;了解客户需求&#xff0c;对展馆展厅的用途、面积、功能、展品特点等进行分析&#xff0c;并确定设计方案。 2、方案设计 根据需求确定设计方案&#xff0c;包括平面布局、展品陈列、展示方式、照明等。设计师需要提供设计…

如何在Spring启动的时候执行一些操作

如何在Spring启动的时候执行一些操作 在Spring启动的时候执行一些操作有多种方式。你可以通过实现ApplicationRunner或者CommandLineRunner接口&#xff0c;在Spring Boot应用程序启动后执行特定操作。另外&#xff0c;你也可以使用PostConstruct注解&#xff0c;在Spring Bea…

【考研数学】张宇《1000题》强化阶段正确率多少算合格?

张宇1000题真的很练人心态.... 基础不好&#xff0c;建议别碰1000题 基础好&#xff0c;1000题建议在两个月以内刷完 如果自己本身在基础阶段学的比较水&#xff0c;自己的薄弱点刷了一小部分题没有针对性完全解决&#xff0c;转身去刷1000题就会发现&#xff0c;会的题目刷…

shell脚本-重定向与管道符

一、重定向 因为shell脚本有着批量操作的特殊性&#xff0c;大部分操作处于后台执行&#xff0c;不需要用户进行干预&#xff0c;所以提取、过滤并执行信息十分需要重定向和管道。重定向的意思是不输出到默认设备上&#xff0c;而是输出到你指定的位置&#xff08;文件、其他输…

1.微信小程序开发之准备工作

1.微信小程序账号注册 小程序开发 与 网页开发不一样&#xff0c;在开始微信小程序开发之前&#xff0c;需要访问 微信公众平台&#xff0c;注册一个微信小程序账号。 在拥有了小程序的账号以后&#xff0c;我们才可以开发和管理小程序&#xff0c;后续可以通过该账号进行开发…

国网电力分公司、税务企业如何向央媒投稿?

税务、电力、银行等单位如果想要将稿件发布到中央媒体&#xff0c;可以遵循为大家整理的以下步骤和建议&#xff1a; 了解央媒的定位与要求&#xff1a;中央媒体&#xff0c;如新华社、人民日报、中央电视台等&#xff0c;都有其独特的报道风格和关注重点。在投稿前&#xff0…

【Web后端】会话跟踪技术及过滤器

1.会话跟踪技术 1.1 会话的概念 在web应用中&#xff0c;浏览器和服务器在一段时间内发送请求和响应的连续交互的全过程 1.2 会话跟踪概念 对同一个用户跟服务器的连续请求和接收响应的监视过程 1.3 会话跟踪作用 浏览器和服务器是以http协议进行通信&#xff0c;http协议是…