void qsort(int s[], int l, int r)
{
int i, j, x;
if (l < r)
{
i = l;
j = r;
x = s[i];
while (i < j)
{
while(i < j && s[j] > x) j--; /* 从右向左找第一个小于x的数 */
if(i < j) s[i++] = s[j];
while(i < j && s[i] < x) i++; /* 从左向右找第一个大于x的数 */
if(i < j) s[j--] = s[i];
}
s[i] = x;
qsort(s, l, i-1); /* 递归调用 */
qsort(s, i+1, r);
}
}
算法步骤:
在序列中选择一个关键元素做为轴;
对序列进行重新排序,将比轴小的元素移到轴的前边,比轴大的元素移动到轴的后面。在进行划分之后,轴便在它最终的位置上;
递归地对两个子序列进行重新排序:含有较小元素的子序列和含有较大元素的子序列。
算法复杂度:
快速排序(QuickSort)的最坏时间复杂度应为0(n2),最好时间复杂度为O(nlgn),平均时间复杂度为O(nlgn)。快速排序(QuickSort)在系统内部需要一个栈来实现递归。若每次划分较为均匀,则其递归树的高度为O(lgn),故递归后需栈空间为O(lgn)。最坏情况下,递归树的高度为O(n),所需的栈空间为O(n)。
----------------------------------------------------------------
/********************************************************************************************
平方阶(O(n2))排序
一般称为简单排序,例如直接插入、直接选择和冒泡排序
********************************************************************************************/
/*插入排序*/
extern int InsertSort(int source[], int array_size)
{
int index = 1; //插入排序
int i, j;
for (i = 1; i < array_size; i++)
{
index = source[i];
j = i;
while ((j > 0) && (source[j - 1] > index))
{
source[j] = source[j - 1];
j--;
}
source[j] = index;
}
return 1;
}
/*冒泡排序*/
extern int BubbleSort(int source[], int array_size)
{
int i, j;
int temp;
for (i = 0; i < array_size; i++)
{
for (j = 0; j < array_size - i - 1; j++)
if (source[j] > source[j + 1])
{
temp = source[j];
source[j] = source[j + 1];
source[j + 1] = temp;
}
}
return 1;
}
/*选择排序*/
extern int SelectSort(int source[], int array_size)
{
int temp, min;
int i, j;
for (i = 0; i < array_size; i++)
{
min = i;//先假设最小下标为i
for (j = i + 1; j < array_size; j++)
if (source[j] < source[min])
min = j;//把i之后的最小值附给min
if (min != i)
{
temp = source[i];
source[i] = source[min];
source[min] = temp;
}//判断min与i是否相等,若相等则说明原假设正确,反之:交换数值
}
return 1;
}
/*********************************************************************************************
线性对数阶(O(nlgn))排序
如快速、堆和归并排序
********************************************************************************************/
/*快速排序接口*/
static int Partition(int source[], int left, int right)
{
int x = source[left];
while (left < right)
{
while (left < right && x <= source[right])
right--;
source[left] = source[right];
while (left < right && x >= source[left])
left++;
source[right] = source[left];
}
source[left] = x;
return left;
}
extern int QuickSort(int source[], int left, int right)
{
int iPos;
if (left >= right)
return 1;
iPos = Partition(source, left, right);
QuickSort(source, left, iPos - 1); // 左边划分
QuickSort(source, iPos + 1, right); // 右边划分
return 1;
}
/*堆排序*/
static void HeapAdjust(int source[], int root, int node)/*root根节点, node节点总数*/
{
//已知source[root..node]中除source[root]之外均满足堆的定义,本函数调整source[root]
//使source[root..node]成为一个大顶堆
int j, rc;
rc = source[root];
for (j = 2 * root; j <= node; j *= 2) //沿关键字叫大的结点向下筛选
{
if (j < node && source[j] < source[j + 1])
++j; //j为关键字较大的记录的下标
if (rc >= source[j])
break; //rc应插入在位置root上
source[root] = source[j];
root = j;
}
source[root] = rc; //插入
}
extern int HeapSort(int source[], int array_size)
{
int i, t;
for (i = array_size / 2; i > 0; --i)
//把a[1..L.length]建成大顶堆
HeapAdjust(source, i, array_size);
for (i = array_size; i > 1; --i)
{
t = source[1]; //将堆顶记录和当前未经排序子序列a[1..i]
source[1] = source[i]; //中的最后一个记录相互交换
source[i] = t;
HeapAdjust(source, 1, i - 1); //将r[1..i-1]重新调整为大顶堆
}
return 1;
}
/**********************************************************************************************
O(n1+£)阶排序
£是介于0和1之间的常数,即0<£<1,如希尔排序
********************************************************************************************/
/*希儿排序*/
extern int ShellSort(int source[], int array_size)
{
int increament;
int e, i, j;
/*初始步长设为n/2*/
for (increament = array_size / 2; increament > 0; increament = increament / 2)
for (j = increament; j < array_size; j++)
{
if (source[j] < source[j - increament])
{
e = source[j];
for (i = j - increament; i >= 0 && source[i] > e; i = i - increament)
source[i + increament] = source[i];
source[i + increament] = e;
}
}
return 1;
}