一、快速排序

  一般而言,学习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  }

具体就这些。