稳定 时间复杂度 平均时间复杂度 空间复杂度
冒泡排序 √ 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