常见排序算法及对应的时间复杂度和空间复杂度:
常见排序算法:
1.冒泡排序,2.选择排序,3.插入排序,4.希尔排序,5.堆排序,6.归并排序,7.快速排序;
表格版 |
排序方法 | 时间复杂度(平均) | 时间复杂度(最坏) | 时间复杂度(最好) | 空间复杂度 | 稳定性 | 复杂性 |
冒泡排序 | O(n2) | O(n2) | O(n) | O(1) | 稳定 | 简单 |
选择排序 | O(n2) | O(n2) | O(n2) | O(1) | 不稳定 | 简单 |
插入排序 | O(n2) | O(n2) | O(n) | O(1) | 稳定 | 简单 |
希尔排序 | O(nlog2n) | O(n2) | O(n) | O(1) | 不稳定 | 较复杂 |
堆排序 | O(nlog2n) | O(nlog2n) | O(nlog2n) | O(1) | 不稳定 | 较复杂 |
归并排序 | O(nlog2n) | O(nlog2n) | O(nlog2n) | O(n) | 稳定 | 较复杂 |
快速排序 | O(nlog2n) | O(n2) | O(nlog2n) | O(nlog2n) | 不稳定 | 较复杂 |
常见排序算法的相关程序
#include <stdio.h>
#define MAX 10
typedef int ElementType;
typedef ElementType ARR[MAX];
int len = sizeof(ARR)/sizeof(ElementType);
void swap(ARR arr,int i,int j) //交换函数
{
ElementType temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
void print(ARR arr) //输出函数
{
int i;
for(i = 0;i < len;i++)
{
printf("%3d",arr[i]);
}
printf("\n");
}
void bubble1(ARR arr);//冒泡排序
void bubble2(ARR arr);//冒泡排序改进
void select (ARR arr);//选择排序
void insert (ARR arr);//插入排序
void shell (ARR arr);//希尔函数
void heapadjust(ARR arr,int n,int m);//
void heap(ARR arr);//堆排序
void merge(ARR arr,int left,int mid,int right);//归并排序
void mergesort(ARR arr,int left,int right);//
void mergesort1(ARR arr);//
int pivotkey1(ARR arr,int low,int high);//快速排序
int pivotkey2(ARR arr,int low,int high);//
void quicksort(ARR arr,int low,int high);//
int main()
{
ARR arr1 = {10,9,8,7,6,5,4,3,2,1};
ARR arr2 = {10,9,4,3,2,1,8,7,6,5};
ARR arr3 = {10,9,8,7,6,5,4,3,2,1};
ARR arr4 = {10,9,8,7,6,5,4,3,2,1};
ARR arr5 = {10,9,8,7,6,5,4,3,2,1};
ARR arr6 = {6,4,2,5,10,7,1,8,3,9};
ARR arr7 = {6,4,2,5,10,7,1,8,3,9};
ARR arr8 = {6,4,2,5,10,7,1,8,3,9};
ARR arr9 = {6,4,2,5,10,7,1,8,3,9};
printf("bubble1 : \n");
bubble1(arr1);
printf("bubble2 : \n");
bubble2(arr2);
printf("select : \n");
select(arr3);
printf("insert : \n");
insert(arr4);
printf("shell : \n");
shell(arr5);
printf("heap : \n");
heap(arr6);
printf("mergesort : \n");
mergesort(arr7,0,len-1);
printf("mergesort1 : \n");
mergesort1(arr8);
printf("quicksort : \n");
quicksort(arr9,0,len-1);
return 0;
}
//冒泡排序
void bubble1(ARR arr)
{
int i,j;
for(i = 0;i < len-1;i++)
{
for(j = 0;j < len-1-i;j++)
{
if(arr[j] > arr[j+1])
swap(arr,j,j+1);
}
print(arr);
}
}
//冒泡排序改进
void bubble2(ARR arr)
{
int i,j;
int flag = 1;
for(i = 0;i<len-1 && flag;i++)
{
flag = 0;
for(j = 0;j < len-1-i;j++)
{
if(arr[j] > arr[j+1])
{
flag = 1;
swap(arr,j,j+1);
}
}
print(arr);
}
}
//选择排序
void select (ARR arr)
{
int i,j;
int min;
for(i = 0;i < len-1;i++)
{
min = i;
for(j = i+1;j < len;j++)
{
if(arr[j] < arr[min])
min = j;
}
if(min != i)
swap(arr,i,min);
print(arr);
}
}
//插入排序
void insert (ARR arr)
{
int i,j;
ElementType temp;
for(i = 1;i < len;i++)
{
if(arr[i-1] > arr[i])
{
temp = arr[i];
for(j = i-1;j >= 0;j--)
if(temp < arr[j])
arr[j+1] = arr[j];
else
break;
arr[j+1] = temp;
print(arr);
}
}
}
//希尔排序
void shell (ARR arr)
{
int i,j;
int temp; //增量数组step=2^n +- 1(n=1,2..)
int a[] = {1,3,5};
int k = 2;
int step = a[k];
while(k >= 0)
{
for(i = step;i < len;i++)
{
if(arr[i-step] > arr[i])
{
temp = arr[i];
for(j=i-step;j>=0;j-=step)
if(temp < arr[j])
arr[j+step]=arr[j];
else
break;
arr[j+step] = temp;
}
}
step = a[--k];
print(arr);
}
}
//将arr[n...m]调整为大顶堆
void heapadjust(ARR arr,int n,int m)
{
int i;
ElementType temp = arr[n];
for(i=2*n+1;i<=m;i=2*i+1)
{
if(i<m && arr[i]<arr[i+1])
i++;
if(arr[i]<temp)
break;
//swap(arr,n,i);
arr[n] = arr[i];
n = i;
}
arr[n] = temp;
}
//堆排序
void heap(ARR arr)
{
int i;//初始化堆
for(i=((len-1)-1)/2;i>=0;i--)
heapadjust(arr,i,len-1);
for(i=len-1;i>0;i--)
{
swap(arr,0,i);
heapadjust(arr,0,i-1);
print(arr);
}
}
//归并排序
//将a[l..m]和a[m+1..r]归并
void merge(ARR arr,int left,int mid,int right)
{
int i = left;
int j = mid+1;
int len = right-left+1;
ElementType temp[len];
int k = 0;
while(i<=mid && j<=right)
{
if(arr[i] > arr[j])
temp[k++] = arr[j++];
else
temp[k++] = arr[i++];
}
while(i<=mid)
temp[k++] = arr[i++];
while(j<=right)
temp[k++] = arr[j++];
for(i=0;i<len;i++)
arr[left+i] = temp[i];
}
//归并排序递归算法
void mergesort(ARR arr,int left,int right)
{
if(left == right)
return;
int mid = (left+right)/2;
mergesort(arr,left,mid);
mergesort(arr,mid+1,right);
merge(arr,left,mid,right);
print(arr);
}
//归并排序的非递归算法
void mergesort1(ARR arr)
{
int left,mid,right;
int i;
for(i = 1;i < len;i*=2)
{
left = 0;
//当右侧数组存在时才需要进行归并
while(left+i < len)
{
mid = left+i-1;
right = mid+i<len?mid+i:len-1;
merge(arr,left,mid,right);
left = right+1;
print(arr);
}
}
}
//快速排序
//方法一、获得枢轴位置
int pivotkey1(ARR arr,int low,int high)
{//用子表的第一个记录作枢轴
ElementType pivot = arr[low];
//ElementType pivot=getpivot(arr,low,high);
while(low < high)
{
while(low<high && arr[high]>=pivot)
high--;
arr[low] = arr[high];
//swap(arr,low,high);
while(low<high && arr[low]<=pivot)
low++;
arr[high] = arr[low];
//swap(arr,low,high);
}
arr[low] = pivot;
print(arr);
return low;
}
//方法二、获得枢轴位置
int pivotkey2(ARR arr,int low,int high)
{
ElementType pivot = arr[low];
//ElementType pivot=getpivot(arr,low,high);
//保持枢轴不动,从枢轴下一个位置开始
int tail = low+1;
int i;
for(i = low+1;i <= high;i++)
{
if(arr[i] <= pivot)
swap(arr,i,tail++);
}
swap(arr,low,--tail);
print(arr);
return tail;
}
void quicksort(ARR arr,int low,int high)
{
if(low<high)
{//pivotkey为枢轴值的位置
int pivotkey=pivotkey1(arr,low,high);
//将低子表进行快速排序
quicksort(arr,low,pivotkey-1);
//将高子表进行快速排序
quicksort(arr,pivotkey+1,high);
}
}
//改进快速排序
ElementType getpivot(ARR arr,int low,int high)
{
//三数取中法获得枢轴
ElementType pivot;
int mid = (low+high)/2;
if(arr[low] > arr[high])
swap(arr,low,high);
if(arr[mid] > arr[high])
swap(arr,mid,high);
if(arr[mid] > arr[low])
swap(arr,low,mid);
return arr[low];
}
//减少递归调用占用的栈空间
void Qsort(ARR arr,int low,int high)
{
while(low<high)
{
int pivotkey=pivotkey1(arr,low,high);
quicksort(arr,low,pivotkey-1);
low = pivotkey+1;//尾递归
}
}