﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-lzdhlsc</title><link>http://www.cppblog.com/lzdhlsc/</link><description /><language>zh-cn</language><lastBuildDate>Tue, 09 Jun 2026 20:23:34 GMT</lastBuildDate><pubDate>Tue, 09 Jun 2026 20:23:34 GMT</pubDate><ttl>60</ttl><item><title>几种常见的排序方法（1）</title><link>http://www.cppblog.com/lzdhlsc/archive/2010/01/13/105539.html</link><dc:creator>LSC</dc:creator><author>LSC</author><pubDate>Tue, 12 Jan 2010 18:49:00 GMT</pubDate><guid>http://www.cppblog.com/lzdhlsc/archive/2010/01/13/105539.html</guid><wfw:comment>http://www.cppblog.com/lzdhlsc/comments/105539.html</wfw:comment><comments>http://www.cppblog.com/lzdhlsc/archive/2010/01/13/105539.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lzdhlsc/comments/commentRss/105539.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lzdhlsc/services/trackbacks/105539.html</trackback:ping><description><![CDATA[1.Quicksort<br>快排的基本思想是分组和组合。<br>分组：将待排序的数组（假设数据以数组形式存储的）分成两部分<br>然后这里有个东西叫Pivot,中文名叫中枢纽元，多么衰的名字&#8230;&#8230;我们就叫它x吧。<br>知道了这两个东西以后，介绍一下快排的思路：<br><br>刚才说过，快排把待排数组分成两部分，怎么分呢，根据x，分成 &lt;x,x,&gt;x ，也就是说分成小于x， 大于x 的两组<br>也许你会问，这样的分组是怎么实现的呢？这个待会说，姑且我们认为这个是可实现的。（-_-|||）<br>这样的分组后，x就到了正确的位置， 比如说，x 应该排老十五，那他前面14个比它小的找出来放到&lt;x的那部分里了，这样它自然就在第15的位置上了，剩下在它后面的自然就是比它大的了。<br>实际上，所说的分组不是真的分组，这个待排的数组还是一个整体，只是把小于x的数据挪到大于x的数据之前，然后把x挪到小于x的数据之后，这样在x身后的数据就都大于x了。<br>有图有真相(假设我们选数组的第一个数据为<strong>X</strong>)：<br>
<div id="z-by" style="text-align: left;"><img  src="http://docs.google.com/File?id=ddhvfjzt_3dd5zc73k_b" style="width: 550px; height: 400px;"><br>这样以后，对于&lt;x和&gt;x的两组，注意，他们两组还没有排序呢，对这两组继续用同样的方法，直到排完序为止。<br><br></div>
接下来，我们要关心的是怎么分组。怎么x就跑到&lt;X,&gt;X中间了呢？<br>我们用一个例子来说明。<br>看图：
<div id="gjmc" style="text-align: left;">
<div id="nh2l" style="text-align: left;"><img  src="http://docs.google.com/File?id=ddhvfjzt_8hkdrcz9x_b" style="width: 550px; height: 300px;"></div>
<br></div>
开始的时候，i=0,j=1，因为<br>（1）.除了x所有的数据都是未分组部分，所以j=1。<br>（2）.小于x的部分还没有产生。所以i=0.<br>接下来，我们让未分组部分的第一个元素和x比较。如果未分组部分的的首元素小于x，我们自然要把这个首元素归到&lt;x的组里，<br>怎么做呢？两步：<br>（1）.扩大&lt;x组的边界。<br>（2）.将未分组的首元素放到&lt;x组里面去。<br>
<div id="jxrq" style="text-align: left;"><img  src="http://docs.google.com/File?id=ddhvfjzt_9fc7fbqf6_b" style="width: 550px; height: 100px;"></div>
<br>所以我们让i=i+1,然后调换a[i],a[j]。也就是把未知组的首元素调换到&lt;x里面，既最后一个&lt;x的位置上，至于被调换走的a[i],想想，1.i=i+1以后，i=j。<br>这样相当于没调换，仅仅增加了i,也就是&lt;x组的边界，这正是我们想要的。有&gt;x组的时候，在未调换之前实际上a[i]里的元素实际上是&gt;x组的（因为i已经被增加1了），<br>因为&lt;x组后面紧接着是&gt;x组，将i=i+1,实际将&gt;x组里面的首元素纳入了&lt;x组里面去了，这不是错误的么，是啊，所以我们有了调换a[i],a[j],这<br>样把这个属于&gt;x的元素放到了未知组的第一个元素的位置上了。这个不是还是不对的么？是的，但是我们还有第三招：将j=j+1,没错，减少未知<br>组的边界。我想问问大家，&lt;x组的尾边界是i,那么&gt;x的尾边界是什么？是j-1。将j增加了以后，相当于增加了&gt;x组，又重新把a[j]的这个元素纳入&gt;x组了。<br>看图从左到右，从上到下阅读：<br>
<div id="su66" style="text-align: left;">
<div id="ndsw" style="text-align: left;"><img  src="http://docs.google.com/File?id=ddhvfjzt_72nssh8dm_b" style="width: 550px; height: 300px;"></div>
<br>
<div id="uf:3" style="text-align: left;"><img  src="http://docs.google.com/File?id=ddhvfjzt_6f5m5f2hj_b" style="width: 550px; height: 300px;"><br>接下来对1 3 2与 8 9 的排序就不细说了。步骤是一致的。<br>下面写一下伪代码：<br>quicksort(A,p,q){<br>&nbsp;&nbsp;&nbsp; if p&lt;q<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; then {<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;r=partition(A,p,q);<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; quicksort(A,p,r-1);<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; quicksort(A,r+1,q);<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; }<br>partition(A,p,q){<br>&nbsp;&nbsp;&nbsp; x=A[p];<br>&nbsp;&nbsp; &nbsp;i=p;<br>&nbsp;&nbsp;&nbsp; For(j=p+1 to q){<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; if (A[j]&lt;=x)<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; then {<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; i=i+1;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; Swap（A[i]，A[j]);<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp; &nbsp; Swap(A[p],A[i]);<br>&nbsp;&nbsp;&nbsp; return i;<br>}<br></div>
<br></div>
这种算法的时间复杂度是O(nlogn)，是一个比较高效的方法，关于时间复杂度的证明第二章介绍。<br><br>此文档基于MIT 网络课程。<img src ="http://www.cppblog.com/lzdhlsc/aggbug/105539.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lzdhlsc/" target="_blank">LSC</a> 2010-01-13 02:49 <a href="http://www.cppblog.com/lzdhlsc/archive/2010/01/13/105539.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>