稳定 时间复杂度 平均时间复杂度 空间复杂度
冒泡排序 √ O(n2) O(n2) O(1)
选择排序 × O(n2) O(n2) O(1)
插入排序 √ O(n2) O(n2) O(1)
二叉排序 √/× O(n2) O(n*log2n) O(n)
快速排序 × O(n2) O(n*log2n) O( log2n )~O(n)
基数排序 √ O(n*logrm) O(n*logrm) O(2r) 【注】r为基数,m为堆数
希尔排序 × O O O(1)
堆排序 × O(n*log2n) O(n*log2n) O(1)
归并排序 √
锦标赛排序,类似于二叉树排序。
for (int i = 0; i < size - 1; i++) {
for (int j = 0; j < size - i - 1; j++) {
if (array[j+1] < array[j]) {
int tmp = array[j+1]; array[j+1] = array[j]; array[j] = tmp;
}
}
}//每次选择最小的一个元素,进行位置交换。
void select_sort(int array[], int size)
{
int i, j, tmp;
for (i =0; i < size-1; i++ ) {
index = i;
for (j = i+1; j < size; j++) {
//选择剩余元素中最小的一个元素,记录在index中
if (array[index] > array[j])
index = j;
}
if (i != index) {
//进行元素的交换
tmp = array[index];
array[index] = array[i];
array[i] = tmp;
}
}
}//在一个已经有序的小序列基础上,一次插入一个元素。
void insert_sort(int array[], int size)
{
int i, j, tmp;
for (i = 1; i <= size; i++) {
tmp = array[i]; //待插入的元素
j = i-1;
//与已排序的数逐一比较大小,大于tmp时,该数移后
while ((j > 0) && (array[j] > tmp)) {
array[j+1] = array[j];
j--;
}
array[j+1] = tmp;
}
}
【注】:进行函数调用时,传入的参数为:quick_sort(data,0, size-1);
void swap(int *array, int x, int y)
{
int tmp = array[x];
array[x] = array[y];
array[y] = tmp;
}
int partition1(int *array, int start, int end) {
int pos = (start + end) / 2;
swap(array,pos,end);
int key = array[end];
int i = start-1;
for(int j=start;j<=end;++j){
if(array[j]<key){
swap(array,++i,j);
}
}
swap(array,++i,end);
return i;
}
int partition(int *array, int start, int end) {
int pos = (start+end)/2;
int low = start+1;
int high = end;
int key = array[pos];
swap(array, pos, start);
while (low < high) {
while (low < high && array[low] <= key)
low++;
while (low < high && array[high] > key)
high--;
if (low >= high)
break;
swap(array, low, high);
}
if (array[low] > key) {
swap(array, start, low-1);
return low-1;
} else {
swap(array, start, low);
return low;
}
}
void quick_sort(int *array, int start, int end){
if (start >= end) {
return;
}
int pos = partition(array, start, end);
quick_sort(array, start, pos-1);
quick_sort(array, pos+1, end);
}
//生成二叉排序树,然后将二叉树采用中序遍历重新对array赋值
struct node{
int value;
struct node *left;
struct node *right;
};
struct node *new_node(int value)
{
struct node *new_node = (struct node*)malloc(sizeof(struct node));
if (node) {
node->value = value;
node->left = NULL;
node->right = NULL;
}
return node;
}
void insert_to_tree(struct node *root, struct node *node)
{
struct node *tmp = root, *prev = tmp;
while (tmp) {
prev = tmp;
if (tmp->value < node->value) {
tmp = tmp->right;
} else {
tmp = tmp->left;
}
}
if (prev->value < node->value) {
prev->right = node;
} else {
prev->left = node;
}
}
int binary_tree_sort(int array[], int size)
{
int i = 0;
struct node *root = new_node(array[i]);
struct node *node = NULL;
struct stack *s = NULL;
for (i = 1; i < size; i++) {
node = new_node(array[i]);
if (!node) {
return 0;
}
insert_to_tree(root, node);
}
//中序遍历二叉树,重新填充数组
s = create_stack();
if (s == NULL) {
printf("Create stack failed!\n");
return 0;
}
node = root;
i = 0;
while (node || !is_empty(s)){
while (node) {
push(&s, node);
node = node->left;
}
node = pop(&s);
array[i] = node->value;
node = node->right;
i++;
if (i >= size) {
break;
}
}
destroy_stack(&s);
return (i <= size);
}
int find_max_num(int array[], int size)
{
int i = 0, max = 0;
for (; i < size; i ++) {
if (array[i] > max) {
max = array[i];
}
}
return max;
}
int get_loop_times(int num)
{
int loop = 0, tmp = 0;
do {
tmp = num / 10;
loop++;
} while (tmp != 0);
return loop;
}
//将数字分配到各自的桶中,然后按照桶的顺序输出排序结果
void __radix_sort(int array[], int size, int loop)
{
//建立一组桶
int buckets[10][size] = {0};
/*
求桶的index的除数
如798
个位桶index = (798 / 1) % 10 = 8;
十位桶index = (798 / 10) % 10 = 9;
百位桶index = (798 / 100) % 10 = 7
*/
int tmp_num = (int) pow(10, loop-1);
int i, j, index, k;
for (i = 0; i < size; i++) {
index = (array[i] / tmp_num) % 10;
for (j = 0; j < size; j++) {
if (buckets[index][j] == 0) {
buckets[index][j] = array[i];
break;
}
}
}
//将桶中的数,倒回到原有数组中
k = 0;
for (i = 0; i < 10; i++) {
for (j = 0; i < size; j++) {
if (buckets[i][j] != 0) {
array[k] = buckets[i][j];
buckets[i][j] = 0;
k++;
}
}
}
}
//从个位开始,向高位依次放入桶中,进行排序
void radix_sort(int array[], int size)
{
//获取数组中的最大数
int max_num = find_max_num(array, size);
//获取最大数的位数,次数也是再分配的次数
int loop_times = get_loop_times(max_num);
int i = 0;
//对每一位进行桶分配
for (i = 1; i <= loop_times; i++) {
__radix_sort(array, size, i);
}
}void shellPass(int *R,int n, int d)
{//希尔排序中的一趟排序,d为当前增量
int tmp;
for(i=d+1; i<=n;i++) //将R[d+1..n]分别插入各组当前的有序区
if(R[i]<R[i-d]){
tmp=R[i];
j=i-d; //R[0]只是暂存单元,不是哨兵
do {//查找R[i]的插入位置
R[j+d] = R[j]; //后移记录
j=j-d; //查找前一记录
}while(j>0 && tmp < R[j]);
R[j+d]=tmp; //插入R[i]到正确的位置上
}
}
}
void shellSort(int *R, int n)
{
int increment = n; //增量初值,不妨设n>0
do {
increment=increment/3 +1; //求下一增量
shellPass(R,increment); //一趟增量为increment的Shell插入排序
}while(increment>1)
}
inline void swap(int *a, int num1, int num2)
{
int tmp = a[num1];
a[num1] = a[num2];
a[num2] = tmp;
}
/* 对该数进行下滤操作,直到该数比左右节点都小就停止下滤。
即对某个根节点的值进行位置下降调整,使该值比其左右子节点都小;
若该节点是叶子节点,则无法while循环 */
void PercolateDown(int num[] , int index,int size) {
int min;//最小指向下标
while (index * 2 + 1<size) {
//若该节点有左子结点,则假设该节点为最小
min = index * 2 + 1;
if (index * 2 + 2<size) {//若有右子节点,比较获得左右子节点的最小值
if (num[min] > num[index * 2 + 2]) {
min = index * 2 + 2;
}
}
if (num[index] < num[min]) {//当前的节点小于左右子节点,则循环结束
break;
} else {
Swap(num, index, min);//将当前节点与最小子节点进行交换
index = min;// 重设下标,继续对该节点进行下虑
}
}// while
}
/* 建堆方法,只需线性时间建好;
建堆的结果:数组的第一个元素(即树根)是所有元素中的最小值,索引小于等于size/2-1的其它元素(即其它非叶子节点)的值都是其所在子树的最小值 */
void BuildHeap(int num[] ,int size) {
int i;
//从最后一个非叶子节点开始,对每个非叶子节点进行最小根调整,保证每个根节点都是其子树中的最小值
for (i = size / 2 - 1; i >= 0; i--) {
PercolateDown(num, i,size);
}
}
void HeapSort(int num[] ,int size)
{
int i;
int iLength=size;
//建立小顶堆
BuildHeap(num,size);
/*
堆排序-建立大顶堆,数组按由大到小排序
基本思路:
从数组的最后一个元素开始,将其与第一个元素交换,然后对该元素进行下虑操作
此时第一个元素总是当前堆的最小值。
*/
for (i = iLength - 1; i >= 1; i--) {
Swap(num, 0, i);
size--; //每交换一次,将堆的规模减小一次
PercolateDown(num, 0, size);//将新的首元素下虑操作
}
}void merge_sort(int array[], unsigned int first, unsigned int last)
{
int mid = 0;
if(first<last)
{
/*mid = (first+last)/2;*/ /*注意防止溢出*/
/*mid = first/2 + last/2;*/
/*mid = ((first & last) + (first ^ last) >> 1);*/
mid = ((first & last) + ((first ^ last) >> 1)); /*修正上一句优先级错误*/
merge_sort(array, first, mid);
merge_sort(array, mid+1,last);
merge(array,first,mid,last);
}
}
void merge(int array[], int low,int mid,int high)
{
int j = mid+1, k = 0;
while(j <= high) {
if(array[j-1] < array[j])
break;
tmp = array[j];
k = j-1;
while ( k >= 0 && tmp < array[k]){
array[k + 1] = array[k];
k--;
}
array[k] = tmp;
j++;
}
}void merge(int array[], int low,int mid,int high)
{
int tmp_arr[high-low+1] = {0};
int i = low, j = mid+1, k = 0;
while(i <= mid && j <= high){
if(array[i] < array[j]) {
tmp_arr[k++] = array[i++];
} else {
tmp_arr[k++] = array[j++];
}
}
while(i <= mid)
tmp_arr[k++] = array[i++];
while(j <= high)
tmp_arr[k++] = array[j++];
i = low, k = 0;
while(i <= high)
array[i++] = tmp_arr[k++];
}
原文地址:http://blog.csdn.net/shutingchen/article/details/38173361