各种排序算法实现

来源:互联网 发布:算法帝国 英文封面 编辑:程序博客网 时间:2024/03/29 20:03

1 选择排序

最坏情况:时间复度为O(n^2);

均时间复杂度O(n^2);

最好情况:时间复杂度为O(n^2);

最差空间复杂度:需要辅助空间O(1);不是稳定排序

代码实现

void swap(int &a, int &b) {int tmp = a;a = b;b = tmp;}void selectionSort(int a[], int n) {//a为要排序数组,n为数组大小for(int i = 0; i < n-1; i++) {int k = i;for(int j = i+1; j < n; j++) {if(a[j] < a[k]) k = j;}if(k != i) swap(a[i], a[k]);}} 

2 冒泡排序

最坏情况:时间复杂度为O(n^2);

平均时间复杂度O(n^2); 

最好情况:数组已经排序,时间复杂度为O(n);

最差空间复杂度:需要辅助空间O(1);是稳定排序

代码实现

void swap(int &a, int &b) {int tmp = a;a = b;b = tmp;}void bubbleSort(int a[], int n) {//a为要排序数组,n为数组大小for(int i = 0; i < n-1; i++) {for(int j = 0; j < n-1-i; j++) if(a[j] > a[j+1])swap(a[j], a[j+1]);}}

3 直接插入排序

最坏情况数组反序,时间复杂度为O(n^2); 

平均时间复杂度O(n^2);

最好情况:数组已经排好序,时间复杂度为O(n);

最差空间复杂度:总共O(n),需要辅助空间O(1),是稳定排序

代码实现

void insertionSort(int a[], int n) {//a为要排序数组,n为数组长度 for(int i = 1; i < n; i++) {int key = a[i];int j = i-1;while(j >= 0 && a[j] > key) {a[j+1] = a[j];j--;}a[j+1] = key;}}


4 希尔排序

最坏情况:时间复杂度为O(n^2);

平均时间复杂度:O(n^1.25);

最好情况:时间复杂度为O(nlogn);

最差空间复杂度:总共O(n),需要辅助空间O(1);不是稳定排序 

代码实现

void shellSort(int a[], int n) {for(int gap = n/2; gap >= 1; gap /= 2) {for(int i = gap; i < n; i++) {int key = a[i];int j = i-gap;while(j >= 0 && a[j] > key) {a[j+gap] = a[j];j -= gap;}a[j+gap] = key;}}}

5 归并排序

典型的分治法,最坏情况:时间复杂度为O(nlogn);

平均时间复杂度O(nlogn);

最好情况:时间复杂度为O(nlgn);

最差空间复杂度:需要辅助空间O(n),是稳定排序

代码实现

void merge(int c[], int b[], int low, int mid, int high) {// 合并c[low:mid] 和 c[mid+1:right] 到 d[low:right] int i = low, j = mid+1, k = low;while((i <= mid) && (j <= high)) {if(c[i] <= c[j]) b[k++] = c[i++];else b[k++] = c[j++];}if(i > mid) for(int r = j; j <= high; j++)b[k++] = c[j];elsefor(int r = i; i <= mid; i++)b[k++] = c[i];}void copy(int a[], int b[], int left, int right) {//复制回数组a for(int i = left ; i <= right; i++) a[i] = b[i];}void mergeSort(int a[], int left, int right, int b[]) {// a为要排序数组,left, right表示数组下标,b为额外存储数组 if(left < right) {int i = (left+right)/2;mergeSort(a, left, i, b);mergeSort(a, i+1, right, b);merge(a, b, left, i, right);copy(a, b, left, right);}}

6 快速排序

典型的分治法,最坏情况:数组已经排序,每次分区都为0个元素与n-1个元素,时间复杂度为O(n^2);

平均时间复杂度O(nlogn);

最好情况:时间复杂度为O(nlogn);

最差空间复杂度:需要辅助空间O(logn);不是稳定排序

代码实现

void swap(int &a, int &b) {int tmp = a;a = b;b = tmp;} // 每次选择最右边元素作为基准将a[p:r]进行分区 int partion(int a[], int p, int r) {int i = p-1;int key = a[r];for(int j = p; j < r; j++) {if(a[j] <= key) {i++;swap(a[i], a[j]);}}swap(a[i+1], a[r]);return i+1;}void quickSort(int a[], int p, int r) {//a为要排序数组,p, r为数组下标 if(p < r) {int q = partion(a, p, r);quickSort(a, p, q-1);quickSort(a, q+1, r);}}

7 堆排序

最坏情况:时间复杂度为O(nlogn);

平均时间复杂度O(nlogn);

最好情况:时间复杂度为O(nlogn);

最差空间复杂度:需要辅助空间O(1);不是稳定排序

代码实现

void swap(int &a, int &b) {int tmp = a;a = b;b = tmp;}// 维持堆结构 void maxHeap_keep(int a[], int i, int heap_size) {//i为根节点下标, hipe_size为堆中元素个数 int left = 2*i +1;int right = 2*i +2;int largest = i;if(left < heap_size && a[left] > a[i])largest = left;if(right < heap_size && a[right] > a[largest])largest = right;if(largest != i) {swap(a[i], a[largest]);maxHeap_keep(a, largest, heap_size);}}// 建立初始堆, O(n) void build_maxHeap(int a[], int n) {//a为要排序数组,n为数组大小for(int i = n/2 ; i >= 0; i--)maxHeap_keep(a, i, n);}void heapSort(int a[], int n) {build_maxHeap(a, n);int heap_size = n;for(int i = n-1; i > 0; i--) {swap(a[0], a[i]);heap_size--;maxHeap_keep(a, 0, heap_size);} }

                                             
0 0