C语言几种常用排序
2017-08-04 09:12
363 查看
C语言几种常用排序
[pái xù]
编辑
排序是计算机内经常进行的一种操作,其目的是将一组“无序”的记录序列调整为“有序”的记录序列。分内部排序和外部排序。若整个排序过程不需要访问外存便能完成,则称此类排序问题为内部排序。反之,若参加排序的记录数量很大,整个序列的排序过程不可能在内存中完成,则称此类排序问题为外部排序。内部排序的过程是一个逐步扩大记录的有序序列长度的过程。
编辑
将杂乱无章的数据元素,通过一定的方法按关键字顺序排列的过程叫做排序。假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,ri=rj,且ri在rj之前,而在排序后的序列中,ri仍在rj之前,则称这种排序算法是稳定的;否则称为不稳定的。
快速排序、希尔排序、堆排序、直接选择排序不是稳定的排序算法,而基数排序、冒泡排序、直接插入排序、折半插入排序、归并排序是稳定的排序算法
排序算法大体可分为两种:
一种是比较排序,时间复杂度O(nlogn) ~ O(n^2),主要有:冒泡排序,选择排序,插入排序,归并排序,堆排序,快速排序等。
另一种是非比较排序,时间复杂度可以达到O(n),主要有:计数排序,基数排序,桶排序等。
这里我们来探讨一下常用的比较排序算法,非比较排序算法将在后续文章中介绍。下表给出了常见比较排序算法的性能:
有一点我们很容易忽略的是排序算法的稳定性(腾讯校招2016笔试题曾考过)。
排序算法稳定性的简单形式化定义为:如果Ai = Aj,排序前Ai在Aj之前,排序后Ai还在Aj之前,则称这种排序算法是稳定的。通俗地讲就是保证排序前后两个相等的数的相对顺序不变。
对于不稳定的排序算法,只要举出一个实例,即可说明它的不稳定性;而对于稳定的排序算法,必须对算法进行分析从而得到稳定的特性。需要注意的是,排序算法是否为稳定的是由具体算法决定的,不稳定的算法在某种条件下可以变为稳定的算法,而稳定的算法在某种条件下也可以变为不稳定的算法。
例如,对于冒泡排序,原本是稳定的排序算法,如果将记录交换的条件改成A[i] >= A[i + 1],则两个相等的记录就会交换位置,从而变成不稳定的排序算法。
其次,说一下排序算法稳定性的好处。排序算法如果是稳定的,那么从一个键上排序,然后再从另一个键上排序,第一个键排序的结果可以为第二个键排序所用。基数排序就是这样,先按低位排序,逐次按高位排序,低位排序后元素的顺序在高位也相同时是不会改变的。
冒泡排序
#include <stdio.h>
// 交换函数
void swap (int a[], int i, int j)
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
// 打印数组
void printA (int *a, int len)
{
int i;
for (i = 0; i < len; i++)
{
printf ("%4d", a[i]);
}
printf ("\n");
}
// 冒泡排序
int main1()
{
int a[10] = {9,6,8,0,3,5,2,4,7,1};
int len = sizeof(a) / sizeof(a[0]);
int i,j;
// 外层循环控制轮数,每一轮找出一个最大的树沉底
for (i = 0; i < len -1; i++)
{
// 内层循环控制每一轮比较的次数
for (j = 0; j < len-1-i; j++)
{
if (a[j] > a[j+1])
{
swap (a, j, j+1);
}
}
}
printA (a, len);
return 0;
}
// 鸡尾酒排序
int main()
{
int a[10] = {9,6,8,0,3,5,2,4,7,1};
int len = sizeof(a) / sizeof(a[0]);
int i;
int left = 0;
int right = len - 1;
while (left < right)
{
// 从左往右找到一个最大的数放到right的位置
for (i = left; i < right; i++)
{
if (a[i] > a[i+1])
{
swap (a, i, i+1);
}
}
right--;
// 从右往左找到一个最小的数放到left的位置
for (i = right; i > left; i--)
{
if (a[i-1] > a[i])
{
swap (a, i, i-1);
}
}
left++;
}
printA (a, len);
return 0;
}
选择排序
#include <stdio.h>
// 交换函数
void swap (int a[], int i, int j)
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
// 打印数组
void printA (int *a, int len)
{
int i;
for (i = 0; i < len; i++)
{
printf ("%4d", a[i]);
}
printf ("\n");
}
// 冒泡排序
int main()
{
int a[10] = {9,6,8,0,3,5,2,4,7,1};
int len = sizeof(a) / sizeof(a[0]);
int i,j;
int min;
// 外层循环控制轮数,每一轮找到一个最小的数
for (i = 0; i < len-1; i++)
{
min = i;
// 内层循环找每一轮最小数的下标
for (j = i+1; j < len; j++)
{
if (a[min] > a[j])
{
min = j; // 保存当前最小元素的下标
}
}
// 如果当前顶端元素不是最小的值,将最小的值和顶端元素进行交换
if (min != i)
{
swap (a, i, min);
}
}
printA (a, len);
return 0;
}
插入排序
#include <stdio.h>
// 交换函数
void swap (int a[], int i, int j)
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
// 打印数组
void printA (int *a, int len)
{
int i;
for (i = 0; i < len; i++)
{
printf ("%4d", a[i]);
}
printf ("\n");
}
// 冒泡排序
int main()
{
int a[10] = {9,6,8,0,3,5,2,4,7,1};
int len = sizeof(a) / sizeof(a[0]);
int get; // 抓牌
int i,j;
for (i = 1; i < len; i++)
{
get = a[i]; // 抓牌
j = i - 1;
// 找到第一个比抓到的牌小的元素,并且进行移位
while (j >= 0 && a[j] > get)
{
a[j+1] = a[j]; // 如果元素比新抓到的元素大,往后移一个位置
j--;
}
a[j+1] = get; // 将新元素插入第一个比它小的元素的后面
}
printA (a, len);
return 0;
}
插入排序改进二分排序
#include <stdio.h>
// 交换函数
void swap (int a[], int i, int j)
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
// 打印数组
void printA (int *a, int len)
{
int i;
for (i = 0; i < len; i++)
{
printf ("%4d", a[i]);
}
printf ("\n");
}
// 二分插入排序
int main()
{
int a[10] = {9,6,8,0,3,5,2,4,7,1};
int len = sizeof(a) / sizeof(a[0]);
int left, right,mid,i,j,get;
for (i = 1; i < len; i++)
{
get = a[i]; // 抓牌
left = 0; // 确定左边界
right = i - 1; // 确定右边界
// 找插入位置:查找完后要插入的位置在下标为left的位置
while (left <= right)
{
mid = (left + right)/2;
if (a[mid] > get) // 要插入的位置在mid的左边
{
right = mid - 1; // 重新设定右边界
}
else // 要插入的位置在mid的右边
{
left = mid + 1; // 重新设定左边界
}
}
// 移位操作:将left开始右边的所有元素都右移一位
for (j = i-1; j >= left; j--)
{
a[j+1] = a[j];
}
a[left] = get; // 插入新元素
}
printA (a, len);
return 0;
}
希尔排序
#include <stdio.h>
// 交换函数
void swap (int a[], int i, int j)
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
// 打印数组
void printA (int *a, int len)
{
int i;
for (i = 0; i < len; i++)
{
printf ("%4d", a[i]);
}
printf ("\n");
}
// 希尔排序
int main1()
{
int a[10] = {9,6,8,0,3,5,2,4,7,1};
int len = sizeof(a) / sizeof(a[0]);
int i,j,get;
int d = len; // d代表每一次的步长
do
{
d = d / 3 + 1;
for (i = d; i < len; i++)
{
get = a[i];
j = i - d;
while (j >= 0 && a[j] > get)
{
a[j+d] = a[j];
j -= d;
}
a[j+d] = get;
}
}while (d > 1);
printA (a, len);
return 0;
}
int main()
{
int a[10] = {9,6,8,0,3,5,2,4,7,1};
int len = sizeof(a) / sizeof(a[0]);
int i,j,get;
int d = 0; // d代表每一次的步长
while (d < len)
{
d = d * 3 + 1; // 0 1 4 13
}
while (d >= 1)
{
for (i = d; i < len; i++)
{
get = a[i];
j = i - d;
while (j >= 0 && a[j] > get)
{
a[j+d] = a[j];
j -= d;
}
a[j+d] = get;
}
d = (d-1) / 3; // 4 1 0
}
printA (a, len);
return 0;
}
#include <stdio.h>
// 交换函数
void swap (int a[], int i, int j)
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
// 打印数组
void printA (int *a, int len)
{
int i;
for (i = 0; i < len; i++)
{
printf ("%4d", a[i]);
}
printf ("\n");
}
// a 代表一个数组
// i 代表要调整的结点的下标
// len 数组的长度
void heapify(int *a, int i, int len)
{
int left = 2 * i + 1; // 左孩子结点下标
int right = 2 * i + 2; // 右孩子结点下标
int max = i; // 三个节点中最大元素的下标
if (left < len && a[left] > a[max])
max = left;
if (right < len && a[right] > a[max])
max = right;
if (max != i) // 当前父节点不是所有结点中最大的元素,需要做调整
{
swap (a, i, max);
heapify (a, max, len); // 调整被交换的结点
}
}
void heapSort (int *a, int len)
{
// 建堆
int i;
for (i = len/2 - 1; i >= 0; i--)
{
heapify (a, i, len);
}
// 排序
for (i = len-1; i > 0; i--)
{
swap (a, 0, i); // 拿堆顶元素与队尾元素进行交换
len--; // 找到一个最大元素以后堆大小减1
heapify (a, 0, len); // 调整堆顶元素
}
}
int main()
{
int a[10] = {9,6,8,0,3,5,2,4,7,1};
int len = sizeof(a) / sizeof(a[0]);
heapSort(a, len);
printA (a, len);
return 0;
}
归并排序
#include <stdio.h>
// 交换函数
void swap (int a[], int i, int j)
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
// 打印数组
void printA (int *a, int len)
{
int i;
for (i = 0; i < len; i++)
{
printf ("%4d", a[i]);
}
printf ("\n");
}
// a 是数组 tmp 是缓冲区
void merge(int *a, int left, int mid, int right, int *tmp)
{
int i = left;
int j = mid + 1;
int k = 0;
while (i <= mid && j <= right)
{
if (a[i] > a[j])
tmp[k++] = a[j++];
else
tmp[k++] = a[i++];
}
while (i <= mid)
tmp[k++] = a[i++];
while (j <= right)
tmp[k++] = a[j++];
k = 0;
for (i = left; i <= right; i++)
{
a[i] = tmp[k++];
}
}
void mergeSort(int *a, int left, int right, int *tmp)
{
if (left >= right)
return;
int mid = (left + right)/2;
mergeSort (a, left, mid, tmp); // 对左边部分进行归并排序
mergeSort (a, mid+1, right, tmp); // 对右边部分进行归并排序
merge (a, left, mid, right, tmp); // 将将部分数据进行归并
}
int main()
{
int a[10] = {9,6,8,0,3,1,2,4,7,5};
int len = sizeof(a) / sizeof(a[0]);
int tmp[10];
mergeSort (a, 0, len-1, tmp);
printA (a, len);
return 0;
}
快速排序
#include <stdio.h>
// 交换函数
void swap (int a[], int i, int j)
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
// 打印数组
void printA (int *a, int len)
{
int i;
for (i = 0; i < len; i++)
{
printf ("%4d", a[i]);
}
printf ("\n");
}
// 分区操作,返回基准值的下标
int partition(int *a, int left, int right)
{
int pivot = a[right];
int index = left; // 如果找到一个比基准值小的元素,与下标为index的元素交换
int i;
for (i = left; i < right; i++)
{
if (a[i] < pivot)
{
swap (a, i, index);
index++;
}
}
swap (a, index, right);
return index; // 基准值所在位置下标
}
void qSort(int *a, int left, int right)
{
if (left < right)
{
int pivot = partition(a, left, right); // 进行分区操作,找基准值下标
qSort (a, left, pivot-1); // 对左边部分进行快速排序
qSort (a, pivot+1, right); // 对右边部分进行快速排序
}
}
int main()
{
int a[10] = {9,6,8,0,3,1,2,4,7,5};
int len = sizeof(a) / sizeof(a[0]);
qSort (a, 0, len-1);
printA (a, len);
return 0;
}
http://sorting.at/# 动画演示
常用排序:
http://www.cnblogs.com/eniac12/p/5329396.html#s12
常见面试排序:
http://blog.csdn.net/pi9nc/article/details/12220851
[pái xù]
排序
编辑排序是计算机内经常进行的一种操作,其目的是将一组“无序”的记录序列调整为“有序”的记录序列。分内部排序和外部排序。若整个排序过程不需要访问外存便能完成,则称此类排序问题为内部排序。反之,若参加排序的记录数量很大,整个序列的排序过程不可能在内存中完成,则称此类排序问题为外部排序。内部排序的过程是一个逐步扩大记录的有序序列长度的过程。
概念描述
编辑将杂乱无章的数据元素,通过一定的方法按关键字顺序排列的过程叫做排序。假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,ri=rj,且ri在rj之前,而在排序后的序列中,ri仍在rj之前,则称这种排序算法是稳定的;否则称为不稳定的。
常见排序算法
快速排序、希尔排序、堆排序、直接选择排序不是稳定的排序算法,而基数排序、冒泡排序、直接插入排序、折半插入排序、归并排序是稳定的排序算法排序算法大体可分为两种:
一种是比较排序,时间复杂度O(nlogn) ~ O(n^2),主要有:冒泡排序,选择排序,插入排序,归并排序,堆排序,快速排序等。
另一种是非比较排序,时间复杂度可以达到O(n),主要有:计数排序,基数排序,桶排序等。
这里我们来探讨一下常用的比较排序算法,非比较排序算法将在后续文章中介绍。下表给出了常见比较排序算法的性能:
有一点我们很容易忽略的是排序算法的稳定性(腾讯校招2016笔试题曾考过)。
排序算法稳定性的简单形式化定义为:如果Ai = Aj,排序前Ai在Aj之前,排序后Ai还在Aj之前,则称这种排序算法是稳定的。通俗地讲就是保证排序前后两个相等的数的相对顺序不变。
对于不稳定的排序算法,只要举出一个实例,即可说明它的不稳定性;而对于稳定的排序算法,必须对算法进行分析从而得到稳定的特性。需要注意的是,排序算法是否为稳定的是由具体算法决定的,不稳定的算法在某种条件下可以变为稳定的算法,而稳定的算法在某种条件下也可以变为不稳定的算法。
例如,对于冒泡排序,原本是稳定的排序算法,如果将记录交换的条件改成A[i] >= A[i + 1],则两个相等的记录就会交换位置,从而变成不稳定的排序算法。
其次,说一下排序算法稳定性的好处。排序算法如果是稳定的,那么从一个键上排序,然后再从另一个键上排序,第一个键排序的结果可以为第二个键排序所用。基数排序就是这样,先按低位排序,逐次按高位排序,低位排序后元素的顺序在高位也相同时是不会改变的。
冒泡排序
#include <stdio.h>
// 交换函数
void swap (int a[], int i, int j)
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
// 打印数组
void printA (int *a, int len)
{
int i;
for (i = 0; i < len; i++)
{
printf ("%4d", a[i]);
}
printf ("\n");
}
// 冒泡排序
int main1()
{
int a[10] = {9,6,8,0,3,5,2,4,7,1};
int len = sizeof(a) / sizeof(a[0]);
int i,j;
// 外层循环控制轮数,每一轮找出一个最大的树沉底
for (i = 0; i < len -1; i++)
{
// 内层循环控制每一轮比较的次数
for (j = 0; j < len-1-i; j++)
{
if (a[j] > a[j+1])
{
swap (a, j, j+1);
}
}
}
printA (a, len);
return 0;
}
// 鸡尾酒排序
int main()
{
int a[10] = {9,6,8,0,3,5,2,4,7,1};
int len = sizeof(a) / sizeof(a[0]);
int i;
int left = 0;
int right = len - 1;
while (left < right)
{
// 从左往右找到一个最大的数放到right的位置
for (i = left; i < right; i++)
{
if (a[i] > a[i+1])
{
swap (a, i, i+1);
}
}
right--;
// 从右往左找到一个最小的数放到left的位置
for (i = right; i > left; i--)
{
if (a[i-1] > a[i])
{
swap (a, i, i-1);
}
}
left++;
}
printA (a, len);
return 0;
}
选择排序
#include <stdio.h>
// 交换函数
void swap (int a[], int i, int j)
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
// 打印数组
void printA (int *a, int len)
{
int i;
for (i = 0; i < len; i++)
{
printf ("%4d", a[i]);
}
printf ("\n");
}
// 冒泡排序
int main()
{
int a[10] = {9,6,8,0,3,5,2,4,7,1};
int len = sizeof(a) / sizeof(a[0]);
int i,j;
int min;
// 外层循环控制轮数,每一轮找到一个最小的数
for (i = 0; i < len-1; i++)
{
min = i;
// 内层循环找每一轮最小数的下标
for (j = i+1; j < len; j++)
{
if (a[min] > a[j])
{
min = j; // 保存当前最小元素的下标
}
}
// 如果当前顶端元素不是最小的值,将最小的值和顶端元素进行交换
if (min != i)
{
swap (a, i, min);
}
}
printA (a, len);
return 0;
}
插入排序
#include <stdio.h>
// 交换函数
void swap (int a[], int i, int j)
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
// 打印数组
void printA (int *a, int len)
{
int i;
for (i = 0; i < len; i++)
{
printf ("%4d", a[i]);
}
printf ("\n");
}
// 冒泡排序
int main()
{
int a[10] = {9,6,8,0,3,5,2,4,7,1};
int len = sizeof(a) / sizeof(a[0]);
int get; // 抓牌
int i,j;
for (i = 1; i < len; i++)
{
get = a[i]; // 抓牌
j = i - 1;
// 找到第一个比抓到的牌小的元素,并且进行移位
while (j >= 0 && a[j] > get)
{
a[j+1] = a[j]; // 如果元素比新抓到的元素大,往后移一个位置
j--;
}
a[j+1] = get; // 将新元素插入第一个比它小的元素的后面
}
printA (a, len);
return 0;
}
插入排序改进二分排序
#include <stdio.h>
// 交换函数
void swap (int a[], int i, int j)
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
// 打印数组
void printA (int *a, int len)
{
int i;
for (i = 0; i < len; i++)
{
printf ("%4d", a[i]);
}
printf ("\n");
}
// 二分插入排序
int main()
{
int a[10] = {9,6,8,0,3,5,2,4,7,1};
int len = sizeof(a) / sizeof(a[0]);
int left, right,mid,i,j,get;
for (i = 1; i < len; i++)
{
get = a[i]; // 抓牌
left = 0; // 确定左边界
right = i - 1; // 确定右边界
// 找插入位置:查找完后要插入的位置在下标为left的位置
while (left <= right)
{
mid = (left + right)/2;
if (a[mid] > get) // 要插入的位置在mid的左边
{
right = mid - 1; // 重新设定右边界
}
else // 要插入的位置在mid的右边
{
left = mid + 1; // 重新设定左边界
}
}
// 移位操作:将left开始右边的所有元素都右移一位
for (j = i-1; j >= left; j--)
{
a[j+1] = a[j];
}
a[left] = get; // 插入新元素
}
printA (a, len);
return 0;
}
希尔排序
#include <stdio.h>
// 交换函数
void swap (int a[], int i, int j)
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
// 打印数组
void printA (int *a, int len)
{
int i;
for (i = 0; i < len; i++)
{
printf ("%4d", a[i]);
}
printf ("\n");
}
// 希尔排序
int main1()
{
int a[10] = {9,6,8,0,3,5,2,4,7,1};
int len = sizeof(a) / sizeof(a[0]);
int i,j,get;
int d = len; // d代表每一次的步长
do
{
d = d / 3 + 1;
for (i = d; i < len; i++)
{
get = a[i];
j = i - d;
while (j >= 0 && a[j] > get)
{
a[j+d] = a[j];
j -= d;
}
a[j+d] = get;
}
}while (d > 1);
printA (a, len);
return 0;
}
int main()
{
int a[10] = {9,6,8,0,3,5,2,4,7,1};
int len = sizeof(a) / sizeof(a[0]);
int i,j,get;
int d = 0; // d代表每一次的步长
while (d < len)
{
d = d * 3 + 1; // 0 1 4 13
}
while (d >= 1)
{
for (i = d; i < len; i++)
{
get = a[i];
j = i - d;
while (j >= 0 && a[j] > get)
{
a[j+d] = a[j];
j -= d;
}
a[j+d] = get;
}
d = (d-1) / 3; // 4 1 0
}
printA (a, len);
return 0;
}
#include <stdio.h>
// 交换函数
void swap (int a[], int i, int j)
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
// 打印数组
void printA (int *a, int len)
{
int i;
for (i = 0; i < len; i++)
{
printf ("%4d", a[i]);
}
printf ("\n");
}
// a 代表一个数组
// i 代表要调整的结点的下标
// len 数组的长度
void heapify(int *a, int i, int len)
{
int left = 2 * i + 1; // 左孩子结点下标
int right = 2 * i + 2; // 右孩子结点下标
int max = i; // 三个节点中最大元素的下标
if (left < len && a[left] > a[max])
max = left;
if (right < len && a[right] > a[max])
max = right;
if (max != i) // 当前父节点不是所有结点中最大的元素,需要做调整
{
swap (a, i, max);
heapify (a, max, len); // 调整被交换的结点
}
}
void heapSort (int *a, int len)
{
// 建堆
int i;
for (i = len/2 - 1; i >= 0; i--)
{
heapify (a, i, len);
}
// 排序
for (i = len-1; i > 0; i--)
{
swap (a, 0, i); // 拿堆顶元素与队尾元素进行交换
len--; // 找到一个最大元素以后堆大小减1
heapify (a, 0, len); // 调整堆顶元素
}
}
int main()
{
int a[10] = {9,6,8,0,3,5,2,4,7,1};
int len = sizeof(a) / sizeof(a[0]);
heapSort(a, len);
printA (a, len);
return 0;
}
归并排序
#include <stdio.h>
// 交换函数
void swap (int a[], int i, int j)
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
// 打印数组
void printA (int *a, int len)
{
int i;
for (i = 0; i < len; i++)
{
printf ("%4d", a[i]);
}
printf ("\n");
}
// a 是数组 tmp 是缓冲区
void merge(int *a, int left, int mid, int right, int *tmp)
{
int i = left;
int j = mid + 1;
int k = 0;
while (i <= mid && j <= right)
{
if (a[i] > a[j])
tmp[k++] = a[j++];
else
tmp[k++] = a[i++];
}
while (i <= mid)
tmp[k++] = a[i++];
while (j <= right)
tmp[k++] = a[j++];
k = 0;
for (i = left; i <= right; i++)
{
a[i] = tmp[k++];
}
}
void mergeSort(int *a, int left, int right, int *tmp)
{
if (left >= right)
return;
int mid = (left + right)/2;
mergeSort (a, left, mid, tmp); // 对左边部分进行归并排序
mergeSort (a, mid+1, right, tmp); // 对右边部分进行归并排序
merge (a, left, mid, right, tmp); // 将将部分数据进行归并
}
int main()
{
int a[10] = {9,6,8,0,3,1,2,4,7,5};
int len = sizeof(a) / sizeof(a[0]);
int tmp[10];
mergeSort (a, 0, len-1, tmp);
printA (a, len);
return 0;
}
快速排序
#include <stdio.h>
// 交换函数
void swap (int a[], int i, int j)
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
// 打印数组
void printA (int *a, int len)
{
int i;
for (i = 0; i < len; i++)
{
printf ("%4d", a[i]);
}
printf ("\n");
}
// 分区操作,返回基准值的下标
int partition(int *a, int left, int right)
{
int pivot = a[right];
int index = left; // 如果找到一个比基准值小的元素,与下标为index的元素交换
int i;
for (i = left; i < right; i++)
{
if (a[i] < pivot)
{
swap (a, i, index);
index++;
}
}
swap (a, index, right);
return index; // 基准值所在位置下标
}
void qSort(int *a, int left, int right)
{
if (left < right)
{
int pivot = partition(a, left, right); // 进行分区操作,找基准值下标
qSort (a, left, pivot-1); // 对左边部分进行快速排序
qSort (a, pivot+1, right); // 对右边部分进行快速排序
}
}
int main()
{
int a[10] = {9,6,8,0,3,1,2,4,7,5};
int len = sizeof(a) / sizeof(a[0]);
qSort (a, 0, len-1);
printA (a, len);
return 0;
}
http://sorting.at/# 动画演示
常用排序:
http://www.cnblogs.com/eniac12/p/5329396.html#s12
常见面试排序:
http://blog.csdn.net/pi9nc/article/details/12220851
相关文章推荐
- C语言常用的几种排序算法代码(选择排序,冒泡排序,插入排序,快速排序)
- c语言的几种常用排序的实现
- 用C语言实现常用的几种排序
- 几种常用的高效排序(二)--堆排
- C语言实现4种常用排序
- 几种常用排序法
- 二级c语言之常用的几种排序方法
- C语言常用排序全解
- 几种常用的排序方法
- 几种常用的排序方法7--希尔排序
- 几种常用排序
- C语言常用排序全解
- C语言四种常用排序
- C语言实现4种常用排序
- C语言——常见的几种排序的实现
- 常用的6种排序C语言实现
- 几种常用排序的实现
- 几种常用的排序算法的分析及java实现(希尔排序,堆排序,归并排序,快速排序,选择排序,插入排序,冒泡排序)
- 几种常用的排序方法
- 几种常用的排序方法。