• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C#教程 > C#递归算法之快速排序

C#递归算法之快速排序

作者:Robin 字体:[增加 减小] 来源:互联网 时间:2017-05-28

Robin 通过本文主要向大家介绍了c#排序算法,c#冒泡排序算法代码,c#快速排序算法,c#冒泡排序算法,c#选择排序算法等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

上两片第归算法学习:

1)递归算法之分而治之策略
2)递归算法之归并排序

  上一篇学习中介绍了了递归算法在排序中的一个应用:归并排序,在排序算法中还有一种算法用到了递归,那就是快速排序,快速排序也是一种利用了分而治之策略的算法,它由C.A.R发明,它依据中心元素的值,利用一系列递归调用将数据表划分成越来越小的子表。在每一步调用中,经过多次的交换,最终为中心元素找到最终的位置。与归并算法不同,快速排序是就地排序,而归并排序需要把元素在临时向量中拷贝,下面通过对以下向量进行排序来理解和加深快速排序算法的步骤:

v={800,150,300,650,550,500,400,350,450,400,900};

  利用快速排序算法对此数据表进行排序的第0级划分过程如下: 向量v的索引范围为:[first,last) = [0,10),则中心点的索引为mid = (0+10)/2=5,中心点的值为v[5] = 500

  快速排序算法的第一次划分的目的就是将向量v依据v[5]的值划分成两个子表subList1和subList2,其中subList1中的值都小于v[5],而subList2中的值都大于v[5],我们将subList1称为左子表,subList2称为右子表,并且确定v[5]的最终位置

下面就是实现这一目的需要我们作出的工作步骤:

1)首先将中心元素与起始位置的元素进行交换。

2)分别扫描左子表和右子表,左子表扫描起始位置为 first+1, 右子表从last-1开始。左子表从左向右扫描扫描,右子表从右向左扫描。直到左子表扫描位置大于或者等于右子表扫描位置时候结束。

在第一个步骤中,得到如下的数据表

500  150  300 650 550 800 400 350 450 400 

/UpFiles/2017/5/28/201606160900294.png

  而此时的左子表扫描位置处于索引1处,右子表扫描位置处于索引9处,先从左子表扫描,直到找到数据值大于中间值500的位置停止扫描,然后扫描右子表,直到找到数据值小于中间值500并且右子表的扫描位置(scanDown)要小于左子表开始位置,防止数据溢出。找到之后,交换左子表与右子表中中扫描位置的元素,图示如下:

/UpFiles/2017/5/28/201606160900295.png

在交换v[3](650>500)与v[8](450<500)后,继续扫描左子表和右子表,如图

/UpFiles/2017/5/28/201606160900296.png

  直到满足条件scanUp>=scanDown,然后scanDown所在位置就是中心元素500的最终位置,交换v[0]与v[scanDown)=v[5],第一次划分级别的最终结果数据集为:400,150,300,450,350,500,800,550,650,900,此时得到的左子表为:400,150,300,450,350,右子表为:800,550,650,900

  下一个划分级别是处理上一级别产生的子表,按照相同的处理方法分别处理左子表和右子表,左子表索引位置[0,5),右子表索引位置[6,10),按照上面的处理步骤处理左子表(400,150,300,450,350)得到的最终结果为:150,300,400,450,350 右子表最终处理结果为:550,650,800,900 在处理结果中300与650分别是中心值,他们现在的位置就是最终位置

  在接下来的处理中,总是处理上一步骤中留下的子表,当子表数目<=1的时候就不用处理子表了,而子表有两个元素的时候,比较大小,然后交换两元素位置即可。

大于2个元素的子表都和上面的处理步骤一样,我们将上面的处理过程编写出一个函数

private int PivotIndex(int[] v, int first, int last),那么快速排序算法就是对此函数的递归调用

/// <summary>
/// 交换位置
/// </summary>
/// <param name="v"></param>
/// <param name="index1"></param>
/// <param name="index2"></param>
private void Swrap(int[] v, int index1, int index2)
{
 int temp = v[index1];
 v[index1] = v[index2];
 v[index2] = temp;
}
/// <summary>
/// 将向量V中索引{first,last)划分成两个左子表和右子表
/// </summary>
/// <param name="v">向量V</param>
/// <param name="first">开始位置</param>
/// <param name="last">结束位置</param>
private int PivotIndex(int[] v, int first, int last)
{
 if (last == first)
 {
  return last;
 }
 if (last - first == 1)
 {
  return first;
 }
 int mid = (first + last) / 2;
 int midVal = v[mid];
 //交换v[first]和v[mid]
 Swrap(v, first, mid);
 int scanA = first + 1;
 int scanB = last - 1;
 for (; ; )
 { 

  while (scanA <= scanB && v[scanA] < midVal)
  {
   scanA++;
  }
  while (scanB > first && midVal <= v[scanB])
  {
   scanB--;
  }
  if (scanA >= scanB)
  {
   break;
  }
  Swrap(v, scanA, scanB);
  scanA++;
  scanB--;
 }
 Swrap(v, first, scanB);
 return scanB; 

}
public void Sort(int[] v, int first, int last)
{
 if (last - first <= 1)
 {
  return;
 }
 if (last - first == 2)
 {
  //有两个元素的子表
  if (v[first] > v[last - 1])
  {
   Swrap(v, first, last - 1);
  }
  return;
 }
 else
 {
  int pivotIndex = PivotIndex(v, first, last);
  Sort(v, first, pivotIndex);
  Sort(v, pivotIndex + 1, last);
 }
} 

</div>

  快速排序因为每次划分都能将中心值元素找到最终的位置,并且左边值都小于中心值,右边都大于中心值,它的时间复杂度平均和归并算法一致为O(nlog2n);

  任何一种基于比较的排序算法的时间复杂度不可能小于这个数,除非不使用比较的方法进行排序。

算法程序:http://xiazai.weikejianghu.com/201606/yuanma/QuickSort(weikejianghu.com).rar

</div>
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • C#递归算法之打靶算法分析
  • C#算法函数:获取一个字符串中的最大长度的数字
  • C#递归算法之快速排序
  • C#递归算法寻找数组中第K大的数
  • C#用递归算法解决经典背包问题
  • C#算法设计之关于1000瓶水的问题
  • C#排序算法的比较分析
  • C#实现的优酷真实视频地址解析功能(2014新算法)
  • C#常见算法面试题小结
  • c# 快速排序算法

相关文章

  • 2017-05-28c#读取excel内容内容示例分享
  • 2017-05-28C#中while循环语句用法实例详解
  • 2017-05-28C# 重写ComboBox实现下拉任意组件的方法
  • 2017-05-28C# 拓展方法的简单实例
  • 2017-05-28C#从windows剪贴板获取并显示文本内容的方法
  • 2017-05-28WinForm遍历窗体所有子控件的方法
  • 2017-05-28c#图片缩放图片剪切功能实现(等比缩放)
  • 2017-05-28简介C#读取XML的两种方式
  • 2017-05-28提权函数之RtlAdjustPrivilege()使用说明
  • 2017-05-28C#学习笔记——基本语法

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • C#实现XSL转换的方法
    • C#实现跨线程操作控件方法
    • C#实现将32位MD5摘要串转换为128位二进制字符串的方法
    • C#基础:Dispose()、Close()、Finalize()的区别详解
    • C#编程实现查看剪切板内容的方法
    • C#实现窗口之间的传值
    • C# cmd中修改显示(显示进度变化效果)的方法
    • C#微信开发之微信公众号标签管理功能
    • 使用Npoi操作excel的解决办法
    • C#程序中session的基本设置示例及清除session的方法

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有