排序——简单的快速排序流程(带图例演示)

快速排序是一种高效的排序算法,通过选择一个基准值将数据分为两部分,一部分的所有数据都比另一部分的所有数据小,然后递归地对这两部分数据进行排序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

快速排序(Quicksort),又称划分交换排序(partition-exchange sort),简称快排。它的原理和冒泡排序法一样都是用交换的方式,不过他会在数据中找到一个虚拟的中间值,把小于中间值的数据放在左边,把大于中间值的数据放在右边,再以同样的方式分别处理两边的数据,直到完成排序为止。

执行流程为:

  1. 先以第一个值为基准值,设置其索引为par,将这个值放入一个临时变量tmp中,防止在后面的步骤中被覆盖。再设置第一个值得索引为low,最后一个值的索引为high。先由high的位置开始,由后向前,若找到的数字大于基准值,继续向前找,直到找到小于基准值的值,将它放到索引为low的位置;
  2. 再由low位置从前往后查找查找,若找到的数字小于基准值,继续向后查找,直到找到大于基准值的值,将它放在此时的索引为high的位置;
  3. 步骤2-3都是在low<high的前提下进行,low在不断增大,high在不断减小,直到两者重合,即low=high时,将临时变量tmp中的值,即基准值放入这个位置,此时,这个位置前面的数字都必定比它小,后面的数字都必定比它大,这样,一次排序完成;
  4. 接下来对基准值左右两边的子序列进行同样的处理,直到某一次得到的基准值左右两边都只剩0个或一个数字,此时这组数字已经全部处于有序状态,快速排序完成;

以一组数据:28 6 40 2 60 9 58 16 47 20为例演示一下这个过程:

1)先将第一个数字的索引设置为per,将其复制一份到tmp临时变量中,再设置low为这个数的索引,high为最后一个数的索引;
第一步
2)由high位置开始从后往前查找,发现high对应的值20小于per对应的值28,故将其复制到low的位置
第二步
3)接着从low位置开始由前往后查找,20和6都小于per对应的值28,继续向前查找,直到找到大于28的数字40,将40放到high的位置;
第三步
4)再从high位置往前查找,找到小于per对应的值28的数字16,将其放到low的位置;
第四步
5)由low位置开始由前往后查找,找到大于per对应的值28的数字63,将其放到high的位置;
第五步
6)由high位置开始由后往前查找,找到小于per对应的值28的数字9,将其放到low的位置;
第六步
7)继续从low位置开始从前往后查找,走了一步之后就发现low与high的位置重合,此时将tmp中存储的值28放入该位置,2此时8的最终位置确定,它前面的数字都小于它,后面的数字都大于它,第一轮排序完成;
第一步
8)开始递归的处理28左右两侧的子序列,同上边的步骤一样,先将20放入tmp,从后往前比较后将9放到low位置;
第八步
9)从low位置往后查找,发现这个序列中的数字都小与per对应的值20,直到与high相遇,将tmp中的值放到相遇的位置,20的最终位置确定,再处理其左侧的子序列;
第9步
10)过程不再详述,20左侧子序列处理后的的结果为:
第10步
10)由于这次的基准值9右侧只有一个数字,所以不用再做处理,左侧有两个数字,再进行一次处理,结果为:
第10步
11)再对第一次的基准值28右侧的子序列进行排序,过程不再详述,剩余步骤每次的结果为:
在这里插入图片描述
在这里插入图片描述
至此,数组完全有序,快速排序完成。

实现几何计算,然后实现凸包、Delaunay三角和Voronoi多边形。使用node运行。 几何计算实现点,直线一般式方程、两点式方程、点截式方程、直线交点、点与直线关系,三角形、矩形外接三角形,矩形,圆、三角形外接圆、点与圆关系计算。 凸包算法 graham() { let vs = this.children.filter(e=>e.getClass() == "Vertex"); // find p0-y vectex let p0 = vs[0]; for (let v of vs) { if ( (v.y < p0.y) || (v.y==p0.y && v.x<p0.x)) p0 = v; } vs.sort(function(a,b) { let d1 = Math.atan2( a.y-p0.y , a.x-p0.x ) * (180 / Math.PI); if (d1 < 0) d1 += 180; let d2 = Math.atan2( b.y-p0.y , b.x-p0.x ) * (180 / Math.PI); if (d2 < 0) d2 += 180; if (d1 < d2) return -1; else if (d1 > d2) return 1; else { p0.getDistance(a) - p0.getDistance(b) > 0 ? 1 : -1; } }); let ps = [].concat(vs); let stack = new Array(ps.shift(), ps.shift()); for (let current of ps) { let d; do { let top = stack.peek(); let sec = stack[stack.length-2]; let line = Line.TwoPoint(sec,top); d = line.position(current); if (d>0) top = stack.pop(); } while (d > 0); stack.push(current); } } AI生成项目 javascript 运行 显示如下: 德洛内三角 DelaunayBowyer() { let indices = this.children .filter(e=>e.getClass() == "Vertex") .sort((a,b)=>{ return a.x == b.x ? 0 : (a.x < b.x ? -1 : 1); }); let maxx = 0, maxy = 0, minx = Number.MAX_SAFE_INTEGER, miny = Number.MAX_SAFE_INTEGER; indices.forEach(v=>{ if (v.x < minx) minx = v.x; if (v.x > maxx) maxx = v.x; if (v.y < miny) miny = v.y; if (v.y > maxy) maxy = v.y; }); let r = new Rectangle(new Point(minx, miny), new Point(maxx, maxy)); let supert = Triangle.ExternalTriangleFromRectangle(r); let vs = indices.concat([ supert.p0, supert.p1, supert.p2 ]); let ts =[ supert ]; for (let v of vs) { let edge = new CountArray(); let i = ts.length - 1; while (i>=0) { let t = ts[i--]; let c = Circle.Circumcircle(t); let position = c.test(v); if (position == "out") { continue ; } else { edge.push(new Pair(t.p0, t.p1)); edge.push(new Pair(t.p1, t.p2)); edge.push(new Pair(t.p2, t.p0)); ts.remove(t); } } let nedge = edge.getArray(); for (let i=0; i<nedge.length; i++) { if (v.equals(nedge[i].v1) || v.equals(nedge[i].v2) || nedge[i].v1.equals(nedge[i].v2)) { continue ; } let t = new Triangular(v, nedge[i].v1, nedge[i].v2); ts.push(t); } } for (let i=ts.length-1; i>=0; i--) { let t = ts[i]; if (t.p0.getClass() == "Point" || t.p1.getClass() == "Point" || t.p2.getClass() == "Point") { ts.remove(t); continue ; } this.children.push(t); } return ts; } AI生成项目 javascript 运行 显示如下,未上色和和上色的: 泰森多边形: Voronoi() { let vs = this.children.filter(e=>e.getClass() == "Vertex"); let ts = this.children.filter(e=>e.getClass() == "Triangular"); let gl = []; for (let v of vs) { let bounds = []; for (let t of ts) if (t.p0 == v || t.p1 == v || t.p2 == v) bounds.push(t); let sort = []; let e = bounds[0].exclude(v)[0]; let t; while (bounds.length > 0) { let bFound = false; for (t of bounds) { if (t.hasEdge(v, e)) { e = t.exclude(v, e)[0]; bFound = true; break; } } if (bFound) { bounds.remove(t); sort.push(t); } else { break ; } } if (bounds.length == 0) gl.push(sort); } for (let g of gl) { let cps = []; for (let s of g) { let c = Circle.Circumcircle(s); if (c.x <= 0 && c.y <= 0) return ; cps.push(c.p); } let p = new Path(cps); this.children.push(p); } } AI生成项目 javascript 运行 显示如下,背景和去掉背景的: ———————————————— 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 原文链接:https://blog.youkuaiyun.com/vcshcn/article/details/118533192 写成html 一个按钮和演示框 点击一下进入下一个流程生成泰森多边形
最新发布
07-14
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值