上一篇文章总结了插入排序中的直接插入排序和希尔排序,本篇文章总结一下 排序算法中的交换排序,其中包括冒泡排序和快速排序。
3、冒泡排序
冒泡排序是快速排序算法中最简单的一种,主要是借助“交换”的排序方法。
基本思想:对每一对相邻的两个元素进行比较,然后排序,使较大值靠后,较小值靠前,最后会将此序列中的最大值排列到最后,然后从头开始重复上述步骤,筛选出第二大值为于最大值的前边。再次重复上述步骤直至整个序列有序。
总体来说其时间复杂度为O(n^2)。
其空间复杂度为O(1)。
# include<stdio.h>
# include<assert.h>
# include<time.h>
# include<stdlib.h>
void BuleSort(int *arr, int len)//冒泡排序
{
assert(NULL != arr);
int tmp=0;
for (int i = 0; i<len; ++i)
{
for (int j = 0; j<len - 1; ++j)
{
if (arr[j]>arr[j + 1])
{
tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
}
int main()
{
int arr[10]={0};
srand(time(0));
for(int i=0;i<10;i++)
{
arr[i]= rand()%100+1;
}
BuleSort(arr,10);
for(int i=0;i<10;i++)
{
printf("%d ",arr[i]);
}
printf("\n");
return 0;
}
4、快速排序
快速排序是对冒泡排序的一次重大改进。该排序方法运用的典型思想是“分治法”。
基本思想:通过一次排序后,使得待排序列成为两个部分,前一个部分的元素都比关键值小,后一部分的元素都比关键值大。然后再次使用这个方法对两个部分的元素分别进行排序,最终使得待排序列成为一个有序序列。
总体来说其时间复杂度为O()。理想的情况是,每次划分所选择的中间数恰好将当前序列几乎等分,经过趟划分,便可得到长度为1的子表。这样,整个算法的时间复杂度为O()。 最坏的情况是,每次所选的中间数是当前序列中的最大或最小元素,这使得每次划分所得的子表中一个为空表,另一子表的长度为原表的长度-1。这样,长度为n的数据表的快速排序需要经过n趟划分,使得整个排序算法的时间复杂度为O(n^2)。
其空间复杂度为度O()。从空间性能上看,尽管快速排序只需要一个元素的辅助空间,但快速排序需要一个栈空间来实现递归。最好的情况下,即快速排序的每一趟排序都将元素序列均匀地分割成长度相近的两个子表,所需栈的最大深度为O();但最坏的情况下,栈的最大深度为n。这样,快速排序的空间复杂度为O()。
该排序方法被认为是目前最好的一种内部排序方法。当待排序列有序时,快速排序就退化成了冒泡排序了;当待排序列无序时,快速排序就会显示出优势。对于快速排序而言,越是无序的待排序列,排序速度就越快,越有序就越慢。
快速排序的非递归程序代码:
# include<stdio.h>
# include<assert.h>
# include<time.h>
# include<stack>
# include<stdlib.h>
int Quick(int *arr,int low,int hight)
{
assert(NULL!=arr);
int tmp=arr[low];
while(low<hight)
{
while(low<hight&&arr[hight]>=tmp)
{
hight--;
}
if(low<hight)
{
arr[low++]=arr[hight];
}
else
{
break;
}
while(low<hight && arr[low]<=tmp)
{
low++;
}
if(low<hight)
{
arr[hight--]=arr[low];
}
else
{
break;
}
}
arr[low]=tmp;
return low;
}
void Quickly(int *arr,int low,int hight)
{
assert(NULL!=arr);
int sit=Quick(arr,low,hight);
if(low == hight)
{
return;
}
if(sit+1<hight)
{
Quick(arr,sit+1,hight);
}
if(sit-1>low)
{
Quick(arr,low,sit-1);
}
}
void Quickstack(int *arr,int low,int hight)
{
assert(NULL!=arr);
stack<int> sta;
sta.push(low);
sta.push(hight);
while(!sta.empty())
{
hight=sta.top();
sta.pop();
low=sta.top();
sta.pop();
int sit=Quick(arr,low,hight);
if(sit<hight-1)
{
sta.push(sit+1);
sta.push(hight);
}
if(sit>low+1)
{
sta.push(low);
sta.push(sit-1);
}
}
}
int QuickSort(int *arr,int len)
{
Quickstack(arr,0,len-1);
return 0;
}
int main()
{
int arr[10]={0};
srand(time(0));
for(int i=0;i<10;i++)
{
arr[i]= rand()%100+1;
}
QuickSort(arr,10);
for(int i=0;i<10;i++)
{
printf("%d ",arr[i]);
}
printf("\n");
return 0;
}
快速排序的递归程序代码:
void QuickSort(int *arr, int p, int q) //快速排序(递归)
{
if (p >= q)
{
return;
}
int i = p;
int j = q;
int key = arr[p];
while (i < j)
{
while (i < j&&key <= arr[j])
{
j--;
}
arr[i] = arr[j];
while (i < j&&key >= arr[i])
{
i++;
}
arr[j] = arr[i];
}
arr[i] = key;
QuickSort(arr, p, i - 1);
QuickSort(arr, i + 1, q);
}