排序算法复杂度比较
排序名称 | 最好的时间复杂度 | 平均时间复杂度 | 最坏时间复杂度 | 空间复杂度 | 是否稳定 |
---|---|---|---|---|---|
冒泡排序 | O( n n n) (已经有序的情况) | O( n 2 n^2 n2) | O( n 2 n^2 n2) (倒序) | O( 1 1 1) | 是 |
选择排序 | O( n 2 n^2 n2) | O( n 2 n^2 n2) | O( n 2 n^2 n2) | O( 1 1 1) | 否 |
插入排序 | O( n n n) (已经有序的情况) | O( n 2 n^2 n2) | O( n 2 n^2 n2)(倒序) | O( 1 1 1) | 是 |
快速排序 | O( n l o g 2 n nlog_2n nlog2n) (标准值左右等长) | O( n l o g 2 n nlog_2n nlog2n) | O( n 2 n^2 n2)(已经有序的情况) | O( l o g 2 n log_2n log2n) | 否 |
希尔排序 | - | - | - | O( 1 1 1) | 否 |
归并排序 | O( n l o g 2 n nlog_2n nlog2n) | O( n l o g 2 n nlog_2n nlog2n) | O( n l o g 2 n nlog_2n nlog2n) | O( r d + n rd+n rd+n) | 是 |
基数排序 (r表示关键字基数,d代表长度,n代表关键字个数) | O( d ( n + r d ) d(n+rd) d(n+rd)) | O( d ( r + n ) d(r+n) d(r+n)) | O( d ( r + n ) d(r+n) d(r+n)) | O( 1 1 1) | 是 |
堆排序 | O( n l o g 2 n nlog_2n nlog2n) | O( n l o g 2 n nlog_2n nlog2n) | O( n l o g 2 n nlog_2n nlog2n) | O( 1 1 1) | 否 |
注:
空间复杂度:是解决问题额外申请的空间,如果不随待处理数据量的增大额外处理空间增大,空间复杂度记为O(1)。
稳定:数值相同的两个元素,在排序前后相对位置未发生改变。
排序算法实现
冒泡排序
void BubbleSort(int arr[], int length)
{
int flag = 0;
for(int i=0; i<length&&flag==0; i++)
{
flag = 1;
for(int j=length-1; j>=i; j--)
{
if(arr[j] > arr[j+1])
{
flag = 0;
swap(arr[j], arr[j+1]);
}
}
}
}
选择排序
void SelectSort(int arr[], int length)
{
int min = 0;
for(int i=0; i<length; i++)
{
min = i;
for(int j=i+1; j<length; j++)
{
if(arr[min] > arr[j])
min = j;
}
if(min != i)
{
swap(arr[min], arr[i]);
}
}
}
插入排序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//插入排序:将无序序列插入到有序序列
//在什么情况下效率高:如果序列基本有序情况下;插入排序时数据序列比较少
void InsertSort(int arr[], int length)
{
int i,j;
int temp;
for(i=1;i<length;i++)
{
if(arr[i] < arr[i-1])
{
temp = arr[i];
for(j=i-1;j>=0&&temp<arr[j];j--)
{
arr[j+1] = arr[j];
}
arr[j+1] = temp;
}
}
}
void Print(int arr[], int length)
{
int i;
for(i=0;i<length;i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
int main()
{
int arr[] = {3,1,2,4,5,6,9};
Print(arr, sizeof(arr)/sizeof(arr[0]));
InsertSort(arr, sizeof(arr)/sizeof(arr[0]));
Print(arr, sizeof(arr)/sizeof(arr[0]));
return 0;
}
希尔排序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//希尔排序:分组插入排序
//先分组,然后分别对每一组插入排序
void ShellSort(int arr[], int length)
{
int increasment = length;
int i,j,k;
int temp;
do
{
//确定分组增量
increasment = increasment/3 + 1;
for(i=0;i<increasment;i++)
{
for(j=i+increasment;j<length;j+=increasment)
{
if(arr[j] < arr[j-increasment])
{
temp = arr[j];
for(k=j-increasment;k>=0&&temp<arr[k];k-=increasment)
{
arr[k+increasment] = arr[k];
}
arr[k+increasment] = temp;
}
}
}
}
while(increasment > 1);
}
void Print(int arr[], int length)
{
int i;
for(i=0;i<length;i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
int main()
{
int arr[] = {3,1,2,4,5,6,9};
Print(arr, sizeof(arr)/sizeof(arr[0]));
ShellSort(arr, sizeof(arr)/sizeof(arr[0]));
Print(arr, sizeof(arr)/sizeof(arr[0]));
return 0;
}
快速排序
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
* 将给定数组排序
* @param arr int整型vector 待排序的数组
* @return int整型vector
*/
int partition(vector<int>& arr, int l, int r) {
int i = l, j = r;
int temp = arr[i];
while(i<j)
{
while (arr[j]>=temp && i<j) j--;
swap(arr[i], arr[j]);
while (arr[i]<=temp && i<j) i++;
swap(arr[i], arr[j]);
}
return i;
}
void quick(vector<int>& arr, int l, int r)
{
if(l<r)
{
int p = partition(arr, l, r);
quick(arr, l, p-1);
quick(arr, p+1, r);
}
}
vector<int> MySort(vector<int>& arr) {
// write code here
quick(arr, 0, arr.size()-1);
return arr;
}
};
归并排序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//归并排序:将两个有序序列合并成一个有序序列
//创建数组
int MAX_LEN = 10;
int* CreateArray()
{
int *arr = (int*)malloc(sizeof(int)*MAX_LEN);
memset(arr, 0, sizeof(int)*MAX_LEN);
return arr;
}
//合并
void Merge(int arr[], int start, int end ,int mid, int *temp)
{
int i_start = start;
int i_end = mid;
int j_start = mid + 1;
int j_end = end;
int length = 0;
while(i_start<=i_end && j_start<=j_end)
{
if(arr[i_start]<arr[j_start])
{
temp[length] = arr[i_start];
i_start++;
length++;
}
else
{
temp[length] = arr[j_start];
j_start++;
length++;
}
}
while(i_start<=i_end)
{
temp[length] = arr[i_start];
i_start++;
length++;
}
while(j_start<=j_end)
{
temp[length] = arr[j_start];
j_start++;
length++;
}
//辅助空间覆盖原空间
int i;
for(i=0;i<length;i++)
{
arr[start+i] = temp[i];
}
}
void MergeSort(int arr[], int start, int end, int *temp)
{
if(start >= end) return;
int mid = (start + end)/2;
MergeSort(arr, start, mid, temp);
MergeSort(arr, mid+1, end, temp);
Merge(arr, start, end, mid, temp);
}
void Print(int arr[], int length)
{
int i;
for(i=0;i<length;i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
int main()
{
int arr[] = {3,1,2,4,5,6,9};
Print(arr, sizeof(arr)/sizeof(arr[0]));
int *temp = CreateArray();
MergeSort(arr, 0, sizeof(arr)/sizeof(arr[0])-1, temp);
Print(arr, sizeof(arr)/sizeof(arr[0]));
return 0;
}
堆排序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//堆排序:通过调整堆,初始化从下往上,
//大顶堆:父节点要比孩子节点大,按从下到大排序
void HeapAdjust(int arr[], int index, int length)
{
//先保存当前节点下标
int max = index;
//保存节点左右孩子下标
int lchild = index * 2 + 1;
int rchild = index * 2 + 2;
int temp;
if(lchild<length && arr[lchild]>arr[max])
{
max = lchild;
}
if(rchild<length && arr[rchild]>arr[max])
{
max = rchild;
}
if(max != index)
{
temp = arr[max];
arr[max] = arr[index];
arr[index] = temp;
HeapAdjust(arr, max, length);
}
}
void HeapSort(int arr[], int length)
{
int i;
//初始化堆
for(i=length/2-1;i>=0;i--)
{
HeapAdjust(arr, i, length);
}
//从上向下调整
int temp;
for(i=length-1;i>=0;i--)
{
temp = arr[i];
arr[i] = arr[0];
arr[0] = temp;
HeapAdjust(arr, 0, i);
}
}
void Print(int arr[], int length)
{
int i;
for(i=0;i<length;i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
int main()
{
int arr[] = {3,1,2,4,5,6,9};
Print(arr, sizeof(arr)/sizeof(arr[0]));
HeapSort(arr, sizeof(arr)/sizeof(arr[0]));
Print(arr, sizeof(arr)/sizeof(arr[0]));
return 0;
}
桶排序
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct node
{
int nValue;
int nIndex;
struct node *pNext;
}Hash;
//组内冒泡排序
void GroupSort(Hash *pHead)
{
if(pHead==NULL || pHead->pNext==NULL) return;
Hash *pSort = NULL;
Hash *pTemp = pHead;
while(pTemp->pNext != NULL)
{
pSort = pHead;
while(pSort->pNext != NULL)
{
if(pSort->nValue > pSort->pNext->nValue)
{
pSort->nValue = pSort->nValue ^ pSort->pNext->nValue;
pSort->pNext->nValue = pSort->nValue ^ pSort->pNext->nValue;
pSort->nValue = pSort->nValue ^ pSort->pNext->nValue;
}
pSort = pSort->pNext;
}
pTemp = pTemp->pNext;
}
}
//桶排序
void BucketSort(int arr[], int length)
{
if(arr==NULL||length<0) return;
//找到最大和最小值的最高位
int i;
int min=arr[0], max=arr[length-1];
for(i=0;i<length;i++)
{
if(min>arr[i])
{
min = arr[i];
}
if(max<arr[i])
{
max = arr[i];
}
}
//拆位
int nNum = max;
int ncount = 1;
while(nNum)
{
nNum/=10;
ncount*=10;
}
ncount/=10;
int nMaxIndex = max/ncount;
int nMinIndex = min/ncount;
//分组申请数组
Hash **pHash = (Hash **)malloc(sizeof(Hash*)*(nMaxIndex-nMinIndex+1));
memset(pHash, 0, sizeof(Hash*)*(nMaxIndex-nMinIndex+1));
//元素入桶
int nIndex;
Hash *pTemp = NULL;
for(i=0;i<length;i++)
{
nIndex = arr[i]/ncount - nMinIndex;
pTemp = (Hash*)malloc(sizeof(Hash));
pTemp->nValue = arr[i];
pTemp->pNext = pHash[nIndex];
pHash[nIndex] = pTemp;
}
//排序
for(i=0;i<nMaxIndex-nMinIndex+1;i++)
{
GroupSort(pHash[i]);
}
//放回原数组
nNum = 0;
for(i=0;i<nMaxIndex-nMinIndex+1;i++)
{
pTemp = pHash[i];
while(pTemp)
{
arr[nNum] = pTemp->nValue;
nNum++;
pTemp = pTemp->pNext;
}
}
//释放空间
Hash *pDel = NULL;
for(i=0;i<nMaxIndex-nMinIndex+1;i++)
{
pTemp = pHash[i];
while(pTemp)
{
pDel = pTemp;
pTemp = pTemp->pNext;
free(pDel);
pDel = NULL;
}
}
free(pHash);
pHash = NULL;
}
void Print(int arr[], int length)
{
if(arr==NULL||length<0) return;
int i;
for(i=0;i<length;i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
int main()
{
int arr[] = {102, 209, 101, 333, 509, 399, 666};
Print(arr, sizeof(arr)/sizeof(arr[0]));
BucketSort(arr, sizeof(arr)/sizeof(arr[0]));
Print(arr, sizeof(arr)/sizeof(arr[0]));
return 0;
}
单链表快排:
pNode* partition(pNode* start,pNode* end){
int num = start->val;
pNode* p = start;
pNode* q = start->next;
while(q != end){
if(q->val < num){
p = p->next;
swap(p->val,q->val);
}
q = q->next;
}
swap(p->val,start->val);
return p;
}
void quick_sort(pNode* start,pNode* end){
if(start != end){
pNode* index = partition(start,end);
quick_sort(start,index);
quick_sort(index->next,end);
}
}