思想
快速排序,是一种递归思想的排序算法。
设定一个分界值(此处选择序列第一个值),
把所有小于分界值的数放在左边,大于分界值的放右边,
得到的分块数据再次调用快速排序,
直到要排序的序列不可分割为止,此时序列为非递减排列
核心算法
分割,是快速排序的核心算法,步骤如下:
1.选择待排序列的第一项为分界值,
2.从序列末尾向前扫描,直到遇到比分界值小的值,把此值交换到序列开始的位置,更新序列末尾的位置;
3.然后从序列开始向后扫描,直到遇到比分界值大的值,把此值交换到序列末尾的位置,更新序列开始的位置;
4.重复2-3步,直到序列末尾与序列开始相遇;
5,把分界值赋值到序列相遇的位置;
6,输出序列相遇的位置,此位置把待排序列分割为两部分,在此在前的部分不大于该值,在此之后的部分不小于该值.
// 分割数组
// 输入:数组,要分割的开始位置和结束位置
// 输出:分割的位置
int quick_sort_cut(int array[], int start, int end)
{
int temp = array[start];
int i = start, j = end;
while (i < j)
{
while ((i < j) && (array[j] >= temp))
{
j--;
}
array[i] = array[j];
while ((i < j) && (array[i] <= temp))
{
i++;
}
array[j] = array[i];
}
array[i] = temp;
return i;
}
以递归的方式调用
递归方式十分简洁
// 快速排序
// 输入:数组,开始位置,结束位置
void quick_sort(int array[], int start, int end)
{
int cut_index;
if (start < end)
{
cut_index = quick_sort_cut(array, start, end);
quick_sort(array, start, cut_index - 1);
quick_sort(array, cut_index + 1,end);
}
}
以非递归的方式调用
通过手动管理一个栈来避免递归,栈的大小应大于可能的最大分割深度.
#include "stdlib.h"
// 快速排序,非递归版
void quick_sort_non(int array[], int start, int end)
{
typedef struct {
int start;
int end;
}limit_def;
int cut_index,i,j;
int limit_num = 0;
limit_def* limit_list = (limit_def* )calloc(end + 1 - start,sizeof(limit_def));
limit_list[limit_num].start = start;
limit_list[limit_num].end = end;
limit_num++;
while (limit_num > 0)
{
i = limit_list[limit_num-1].start;
j = limit_list[limit_num-1].end;
limit_num--;
if (i < j)
{
cut_index = quick_sort_cut(array, i, j);
limit_list[limit_num].start = i;
limit_list[limit_num].end = cut_index-1;
limit_num++;
limit_list[limit_num].start = cut_index + 1;
limit_list[limit_num].end = j;
limit_num++;
}
}
free(limit_list);
}