C语言的快速排序及分析

一、快速排序

  一般而言,学习C语言较为简单的排序,则是直接插入排序和冒泡排序。而这两者在数据较大的时候则速度就很慢了。

快速排序的速度大于前者并且较为简单,所以写下学习快速排序的过程,供以后复习。

  快速排序的原理:

    1、快速排序是分治思想,将数列分解排序。

    2、具体过程是:先任取一个值作为基准,然后将小于该基准值的数放在该数的左侧,大于该数的数放在右侧。

    3、然后就是重复地将左侧与右侧持续进行该过程,直到将其分成两个数为一组,然后比较交换。这样,就实现了排序。

  具体实现:

  先定义一个交换函数,方便后续的交换

1 void swap(int a[],int i,int j)
2 {
3         a[i]=a[i]^a[j];
4         a[j]=a[i]^a[j];
5         a[i]=a[i]^a[j];
6 }

  接下来是快速排序的具体算法

 1 void quicksort(int a[],int low,int high)
 2 {
 3     if(low<high)//保证分开的组的成员在两个以上才需要排序
 4     {
 5         int last=low;//last为基准,并设置为组的第一个数
 6         for(int i=last+1;i<=high;i++)//从基准后开始循环
 7         {
 8            if(a[i]<a[last])//如果小于基准,则放在基准的左侧
 9             {
10                 swap(a,last,last+1);//将基准与后一位交换
11                 last++;                //交换后的新基准
12                 if(i!=last)            //
13                     swap(a,last-1,i);
14             }
15         }
16        quicksort(a,low,last);
17        quicksort(a,last+1,high);    //对两部分的数继续上述过程
18     }
19 }

  上述代码是我在看到快速排序的原理后自己写的,显然满足其原理,而且较为简单理解,毕竟从一端开始比较。

但是实际的快速排序并不是这样来的,而是更进一步的优化,采用了从两端比较的方式。

  下面贴出具体代码

 1 void quicksort2(int *a,int low,int high)
 2 {
 3     int i = low;    //i,j分别从首端和尾端开始变化
 4     int j = high;
 5     int temp = a[i]; //temp作为比较的基准
 6
 7     if( low < high)//保证有数可排
 8     {
 9         while(i < j)
10         {
11             while((a[j] >= temp) && (i < j))//基准第一位,所以先从后开始
12             {     //直到循环到比其小的时候开始将后赋值给前一位
13                 j--;
14             }
15             a[i] = a[j];//这里采用赋值而不是交换,在循环外会把丢失的temp补上
16             while((a[i] <= temp) && (i < j))
17             {
18                 i++;
19             }
20             a[j]= a[i];//同上
21         }
22         a[i] = temp;
23         quicksort2(a,low,i-1);
24         quicksort2(a,j+1,high);
25     }
26 }

  以上就是快速排序的过程了。

  若是仔细观察的话会发现一个小细节,那就是快排的每一次循环完成后都完成了一个的数的排序——那就是基准值

快排的原理是将大于基准值的数放在后面,小于的放在前面。这样,每次的排序后基准值的位置确定。那么久可以演化为

另一种问题:求解一组数中的第n大的数。这样可以不完全排序就能解出答案。

  具体代码如下:

 1  int getresult(int *a,int low,int high,int k)
 2  {
 3      int i=low;
 4      int j=high;
 5      int temp=a[i];
 6      if(low<high)
 7      {
 8          while (i<j)
 9          {
10             while ((a[j]>=temp)&&(i<j))
11              {
12                  j--;
13             }
14              a[i]=a[j];
15              while ((a[i]<=temp)&&(i<j))
16              {
17                 i++;
18              }
19              a[j]=a[i];
20          }
21          a[i]=temp;//前面代码与快排一模一样,不做赘述
22          if(i==k-1)//如果基准刚好为所求,则返回
23              return a[i];
24          else if(i>high-k+1)//下面根据大小来选择对哪边进行重复
25             getresult(a,low,i-1,k);
26          else
27              getresult(a,j+1,high,k);
28      }
29  }

  恩,具体就这些。

时间: 2024-08-03 18:01:20

C语言的快速排序及分析的相关文章

C 语言中的内存分析

C 语言中的内存分析 一.进制 我们需要了解的4中进制:二进制.八进制.十进制.十六进制 #include <stdio.h> int main() { //默认情况下是十进制 intnumber = 12; //二进制 intnumber2=0b1100; //八进制 intnumber3 = 014; //十六进制 intnumber = 0xc; return0; } Printf以不同进制形式输出的类型: %d 通常以十进制输出一个整数 %o通常以八进制输出一个整数 %x通常以十六进制

C语言面试及答案分析

第一部分:基本概念及其它问答题 1.关键字static的作用是什么? 这个简单的问题很少有人能回答完全.在C语言中,关键字static有三个明显的作用: 1). 在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变. 2). 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问.它是一个本地的全局变量. 3). 在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用.那就是,这个函数被限制在声明它的模块的本地范围内使用. 大多

C语言终极面试及答案分析

http://www.cnblogs.com/Purple_Xiapei/archive/2012/05/10/2495003.html 第一部分:基本概念及其它问答题1.关键字static的作用是什么?这个简单的问题很少有人能回答完全.在C语言中,关键字static有三个明显的作用:1). 在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变.2). 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问.它是一个本地的全局变量.3)

C语言实现快速排序法(分治法)

title: 快速排序法(quick sort) tags: 分治法(divide and conquer method) grammar_cjkRuby: true --- 算法原理 分治法的基本思想:将原问题分解为若干个更小的与原问题相似的问题,然后递归解决各个子问题,最后再将各个子问题的解组合成原问题的解. 利用分治法可以将解决办法分为 "三步走" 战略: (1) 在数据集中选定一个元素作为"基准"(pivot) (2) 将所有数据集小于基准的元素放在基准左边

C语言:内存地址分析 &amp; sizeof和strlen用法总结

还是在大学时代接触的C语言,当时学习数组.指针等概念时,怎一个"晕"字了得.最近在学习之余,疯狂地恶补了相关知识,故总结之,如有错误,请大家多多指点. 一. 内存地址分析 1) 先来看一个最基础的例子: int a[4]; 提问:&a[0],  a,  &a,  a+1,  &(a+1),  &a+1 分别表示什么? 咋一看,真的不知所措: 我们可以图解来分析它(假设下面的操作均在32为系统上面). 先来对上图进行简单的说明工作: 1. 紫色区域就是数组

C#版 选择法、冒泡法、插入法和快速排序法分析与对比(一)

前言 之前老师就讲过了选择法和冒泡法,之后又提到了插入法和排序法,今天做了一个小DEMO,对比了一下四种方法的效率,当然看了很多大牛也博客,其实算法还设计了时间复杂度和空间复杂度,对于这两个概念,我只能从表面上进行理解,其中涉及到了很多数学的问题,所以就不展开写了. 选择排序 冒泡法 插入法 快速排序法 这部分知识比较新,而且内容比较多,所以打算单独另外总结一遍博客,来详细的总结一下这个方法~ DEMO(比较三个算法所用时间) 先说一下设计的思路,生成要求个数的不重复的随机数,将随机数循环赋给l

R语言:社会网络关系分析-进阶

本文内容参考李明<R语言与网站分析>一书 下面使用R语言实现社会网络分析的各个基础概念 # (1) 点集合(Vertexs)和点的属性数据 # 使用V(g)可返回关系网络g中所有点的集合V,并通过length函数直接返回点数目n.代码如下: V(g.undir) ## Vertex sequence: ## [1] 1 2 3 4 5 6 7 length(V(g.undir)) ## [1] 7 # 在g.undir中记录了点名称属性数据V(g.undir)$label,这里也可以直接展示.

Android平台语言Locale设置流程分析

Android系统Setting程序中对于语言设置这块的内容.具体位置有以下两处: 1).设置显示语言:Settings -> Language & keyboard -> Select language 2).设置输入语言:Settings -> Language & keyboard -> Android keyboard [settings] -> Input languages Settings工程中,Settings -> Language &

C语言链表的来源分析

C语言中的链表是重点,也是难点,而且意义非凡.对链表的的抽象和恐惧是源于对它的来龙去脉的不明白.所以很有必要对它的发展渊源做透彻分析. 链表的单位是节点,而节点源于复合数据类型:结构体: 节点和结构体的区别就是看是否有指针域,目的就是想找到下一个节点: 结构体形如: struct Ghost { char name[30]; int age; int height; char addr[30]; }; 节点形如: struct Ghost { char name[30]; int age; in