继续读啊哈磊算法有感系列,继续升华。上一篇是冒泡排序,在结尾总结了一下冒泡排序的缺点——时间复杂度O(N*N)太大。这一篇来说一下快速排序,快速排序可以在多数情况下克服冒泡排序的缺点(最坏的情况下和冒泡排序的时间复杂度一样)。下面我们先来说说快速排序的思想与过程,与上一篇从过程到思想的思考方式不同,这一次我们的思考过程是从思想到过程——

快速排序的思想:

利用二分的思想,先在待排序子数组中选定一个基准数(作为中间值)、一个左初始位(待排序子数组的左端点位。若对整个数组进行排序,则左端点位为数组的0索引位),一个右初始位(待排序子数组的右端点位。若对整个数组进行排序,则右端点位为数组的length-1处索引位),然后找到一个位置,该位置左侧的数均小于基准数,右侧的数均大于基准数。在此基础上,对待排序子数组进行二分,分别为待排序子数组中基准数以左,左初始位以右的孙子数组1;和待排序子数组中基准数以右,右初始位以左的孙子数组2。之后进行递归,将孙子数组1和2分别作为待排序子数组进行同上排序。

快速排序的过程(与上一篇中思想就是对过程的抽象与总结相反,过程就是对思想的具体与落实):

1、选定待排序子数组及其基准数、左初始位、右初始位(若左初始位小于右初始位则继续,否则停止);

2、找到基准数的交换位置,在左初始位和右初始位分别安排一名哨兵,先是右哨兵向左走,直到找到第一个比基准数小的数为止;然后是左哨兵向右走,直到找到第一个比基准数大的数为止。交换左右哨兵位置处的数值,然后哨兵继续前行(先右后左),继续交换,直到左右哨兵相遇前,停止。至此第一轮排序结束了,左哨兵以左都小于等于基准数,右哨兵以右都大于等于基准数;

3、交换左哨兵和基准数的数值,至此基准数以左均小于等于基准数,基准数以右都大于等于基准数;

4、以基准数所在的位置对待排序子数组进行二分,分为孙子数组1和2;

5、对孙子数组1和2进行递归,回到第一步,孙子数组1的左初始位为待排序子数组的左初始位并依然以左初始位的数为新的基准数、右初始位为基准数位-1,孙子数组2的左初始位为基准数位+1并以左初始位的数位新的基准数、右初始位为待排序子数组的右初始位。

等到孙子数组2的左初始位和孙子数组1的右初始位相遇时,这场排序就结束了。整个待排序子数组将会按照从小到大进行排序。

接下来我们将具体的过程转换为代码:

#Exchange the two value.
function ExchangeValue($i,$j, $studentScore, $studentName)
{
#Exchange the score.
$s = $studentScore[$i]
$studentScore[$i] = $studentScore[$j]
$studentScore[$j] = $s
#Exchange the name.
$n = $studentName[$i]
$studentName[$i] = $studentName[$j]
$studentName[$j] = $n
}
function SortScores($left, $right, $studentScore, $studentName)
{
if($left -le $right)
{
#Sort begin.
#The $left is base number, the $left and $right also represents the location of the sentries' start points.
$i = $left
$j = $right
#The right sentry must go first every time while the sentries not meet each other.
while($i -ne $j)
{
while(($studentScore[$j] -ge $studentScore[$left]) -and ($j -gt $i))
{
$j--
}
#And then the left one.
while(($studentScore[$i] -le $studentScore[$left]) -and ($i -lt $j))
{
$i++
}
#If the left entry doesn't meet the right entry, exchange the left and right number.
If($i -lt $j)
{
ExchangeValue $i $j $studentScore $studentName
}
}
#Exchange the value from the locations of the left entry and the base number.
ExchangeValue $left $i $studentScore $studentName
#Now "$i" is the new location of the base number.
#Sort the new left part.
$newRight = $i-1
$newLeft = $i+1
SortScores $left $newRight $studentScore $studentName
SortScores $newLeft $right $studentScore $studentName
}
}
function PrintSortedScores($count, $studentScore, $studentName){
#Print the sorted result.
Write-Host "Below is the sorted result:"
for($i=0;$i -le $count-1;$i++)
{
$j=$i+1
$tip = "NO."+$j+":"+$studentName[$i]+",score:"+$studentScore[$i]
Write-Host $tip -ForegroundColor Green
}
}
#This is the entry of this program.
#Collect the students' scores.
$count = Read-Host "Enter the amout number of the students"
#Convert to int type.
$count = [int]$count
$studentName = New-Object System.Collections.ArrayList
$studentScore = New-Object System.Collections.ArrayList
for($i=1;$i -le $count;$i++)
{
$name = Read-Host "Enter the name"
$score= Read-Host "Enter the score"
#Convert to int type.
$score = [float]$score
$studentName.Add($name)
$studentScore.Add($score)
}
$leftNum = 0
$rightNum = $count - 1
SortScores $leftNum $rightNum $studentScore $studentName
PrintSortedScores $count $studentScore $studentName

函数SortScores是快速排序算法的核心,其中关键的判断我用橙色高亮了出来。

在PowerShell中运行这段代码,并输入一些测试数据,结果如下:

冒泡排序的交换距离是相邻的两个元素,而快速排序中左右哨兵并不是相邻的,所以交换的两个元素也不是相邻的,最坏的情况,左右哨兵碰头的时候交换才会交换相邻的两个元素。如果每次都是最坏的情况(每次都是左右哨兵相邻才交换),那快速排序的时间复杂度和冒泡排序是一样的。但只要不是最坏的情况,快速排序的时间复杂度都要小于冒泡排序,它的平均时间复杂度是O(NlogN)。

快速排序——PowerShell版的更多相关文章

  1. Ladon内网渗透扫描器PowerShell版

    程序简介 Ladon一款用于大型网络渗透的多线程插件化综合扫描神器,含端口扫描.服务识别.网络资产.密码爆破.高危漏洞检测以及一键GetShell,支持批量A段/B段/C段以及跨网段扫描,支持URL. ...

  2. [工具]法国神器mimikatz 2.1.1 一键版 & PowerShell版

    无需任何参数,运行EXE即可自动读取Windows系统密码 EXE版需要其它功能请使用原版 (参数已写死仅读密码) 结果保存于当前目录mz.log EXE https://github.com/k8g ...

  3. 链表——PowerShell版

    链表是由一系列节点串连起来组成的,每一个节点包括数值部分和指针部分,上一节点的指针部分指向下一节点的数值部分所在的位置. 在C语言中我们有两种方式来定义链表—— 1.定义结构体:来表示链表中的节点,节 ...

  4. 栈——PowerShell版

    上一篇讲过队列(queue),队列就像是居民楼里的垃圾管道,从楼道的垃圾管道的入口处将垃圾扔进去,清洁工会从一楼垃圾管道的出口处将垃圾拿走.每一层的垃圾通道入口与一楼的垃圾管道出口之间都形成了一个队列 ...

  5. 批量备份数据库脚本(PowerShell版)

    开始 昨天备份一个数据库拿来测试,发现备份后的文件非常大.后来去检查下使用的备份脚本,原来之前的备份脚本没有压缩功能. 现把之前的备份脚本修改下,支持压缩备份,和支持仅复制备份(CopyOnly). ...

  6. 队列——PowerShell版

    继续读啊哈磊<啊哈!算法>感悟系列——队列 地铁售票处排队,先来的人先到队首先买完先走,后来的人排在队尾等候后买完后走. 想买票,必须排在队尾:买完票,只能从队首离开. 这种先进先出(Fi ...

  7. 冒泡排序——PowerShell版

    继续读啊哈磊算法有感系列.上一篇是桶排序,在结尾总结了一下简化版桶排序的缺点.这一篇来说一下冒泡排序,冒泡排序可以很好的克服桶排序的缺点.下面我们先来说说冒泡排序的过程与思想—— 冒泡排序的过程: 第 ...

  8. 桶排序——PowerShell版

    读啊哈磊的算法书有感,十一期间想要重新学一学一些基本的算法和数据结构.不想下载编程工具了,毕竟是用室友的电脑,就用PowerShell写一下吧: $scores = @(88,13,99,26,62, ...

  9. windows基线检测脚本编写指南-powershell版

    前言:   因为工作的原因,要写windows下的基线检查脚本.之前没接触过,在网上找了半天也没找到现成的,无奈只好自己研究,最后还是成功完成了工作. 在我编写之后发现windows下的基线基本就是检 ...

随机推荐

  1. poi读取execl的日期

    当execl中的列为日期格式时,后台读取到是一个数字,通过如下代码可以直接读取并转换到Date类型 HSSFDateUtil.getJavaDate(cell.getNumericCellValue( ...

  2. python中的多态

    # -*- coding: cp936 -*- #python 27 #xiaodeng #python中的多态 #多态:一个操作的意义取决于被操作对象的类型,相同的消息给予不同的对象会引发不同的动作 ...

  3. 在JQuery中获取URL中的参数值

    添加一个js文件,代码如下 // * jQuery url get parameters function [获取URL的GET参数值] // *character_set UTF-8 // * au ...

  4. A链接IE6、7下失效场景及解决方案

    1.当img元素包含在多个层级关系里时,只要触发了img元素的父元素的hasLayout,那么就会造成在IE6\7下A标签失效. <!DOCTYPE html PUBLIC "-//W ...

  5. vs2017预览版下载

    vs2017预览版,没有限制的不过不能生成生产版本,集成最新的功能! 下载地址: https://www.visualstudio.com/zh-hans/vs/preview/

  6. 在Eclipse中开发C/C++项目

    摘要:通过本文你将获得如何在Eclipse平台上开发C/C++项目的总体认识.虽然Eclipse主要被用来开发Java项目,但它的框架使得它很容易实现对其他开发语言的支持.在这篇文章里,你将学会如何使 ...

  7. UpdatePanel的用法详解

    摘自:http://www.cnblogs.com/shangxia/articles/2281782.html 一.UpdatePanel的结构 <asp:ScriptManager ID=& ...

  8. POJ 3096 Surprising Strings

    Surprising Strings Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5081   Accepted: 333 ...

  9. C#基础 - C# 的 常见概念简述

    在上篇文章中,你跟着我写了一个HelloWorld,本篇中,我们来谈谈一些C#程序中的小概念 1.C# 程序结构 一个 C# 程序主要包括以下部分: 命名空间声明(Namespace declarat ...

  10. python学习笔记013——内置函数dir()

    1 描述 dir() 函数 不带参数时,返回当前范围内的变量.方法和定义的类型列表: 带参数时,返回参数的属性.方法列表. 如果参数包含方法__dir__(),该方法将被调用. 如果参数不包含__di ...