这里都是按照升序排序的;
交换函数如下:
void Swap(int *a ,int *b){
int tmp = *a;
*a = *b;
*b = tmp;
return;
}
1.冒泡排序
方法一:首先,常规冒泡算法,外循环定义count 为排序的趟数,内循环为每趟进行比较并且交换,实现代码如下:
void BubbleSort(int array[],size_t size){
if(size <= 1){
return;
}
size_t count = 0;
for(;count < size - 1;count++){
size_t i = 0;
for(i = 0;i < size - count -1;i++){
if(array[i] > array[i+1]){
Swap(&array[i],&array[i+1]);
}
}
}//for(;count < size - 1;count++)
return;
}
方法二:定义一个边界bound,并且[0,bound)为有序区间,[bound,size)为待排序区间,代码实现如下:
void BubbleSort2(int array[],size_t size){
if(size <= 1){
return;
}
//[0,bound)为一个有序区间
//[bound,size)为待排序区间
size_t bound = 0;
for(;bound < size;bound++){
size_t cur = size - 1;
for(;cur > bound;cur--){
if(array[cur] < array[cur - 1]){
Swap(&array[cur],&array[cur - 1]);
}
}
}
return;
}
冒泡排序的时间复杂度:O(N^2)
空间复杂度:O(1)
稳定性:稳定排序算法
2.选择排序
思路:整体思路为打擂台,定义第一个元素为擂主即bound,然后让bound之后每一个元素与bound进行比较,如果bound大于后面的元素就进行交换(升序排序);
代码实现如下:
void SelectSort(int array[],size_t size){
if(size <= 1){
return;
}
size_t bound = 0;
for(;bound < size;bound++){
size_t cur = bound + 1;
for(;cur < size;cur++){
if(array[cur] < array[bound]){
Swap(&array[cur],&array[bound]);
}
}
}
return;
}
选择排序时间复杂度:O(N^2)
空间复杂度:O(1)
稳定性:不稳定
3.插入排序
思路:定义一个边界bound,[0,bound)为有序区间,将这个有序区间看成线性表,
[bound,size)为待排序区间,在定义一个cur从后往前开始一边进行比较一边进行搬运,将bound_value的值插入到线性表的合适位置,这里需要注意的是,在搬运之前,先将bound的值保存起来,避免搬运之后将其覆盖;
代码实现如下:
void InsertSort(int array[],size_t size){
if(size <= 1){
return;
}
size_t bound = 1;
for(;bound < size;bound++){
int bound_value = array[bound];
size_t cur = bound;
for(;cur > 0;cur--){
if(bound_value < array[cur - 1]){
array[cur] = array[cur -1];
}else{
//说明已经找到一个合适的位置
break;
}
}//for(;cur > 0;cur--)
array[cur] = bound_value;
}
return;
}
插入排序的时间复杂度:O(N^2)
空间复杂度:O(1)
稳定性:稳定的排序算法
特点:
1.数组元素个数比较小的时候,执行效率比较快
2.如果数组基本有序,执行效率也很快
4.堆排序
思路:整体思路为两步
(1).根据数组建立堆(如果是升序排序,建立大堆);
有两种建立堆的方法:下沉式调整和上浮式调整;
这里两种方法都有实现,具体看代码
(2).循环的删除堆顶元素,删除完之后,排序也就完成了;
先将堆顶元素与最后一个元素进行交换,然后调用下沉式调整进行调整,使仍然符合堆的要求;
代码实现:
代码解释:从HeapSort函数开始;
void AdjustUp(int array[],size_t size,size_t index){
(void)size;
size_t child = index;
size_t parent = (child - 1)/2;
while(child > 0){
if(array[parent] < array[child]){
Swap(&array[parent],&array[child]);
}else{
break;
}
child = parent;
parent = (child - 1)/2;
}
return;
}
void AdjustDown(int array[],size_t size,size_t index){
size_t parent = index;
size_t child = 2 * parent + 1;
while(child < size){
if(child + 1 < size && array[child] < array[child + 1]){
child = child + 1;
}
if(array[parent] < array[child]){
Swap(&array[parent],&array[child]);
}
parent = child;
child = 2 * parent + 1;
}
return;
}
void HeapCreate(int array[],size_t size){
if(size <= 1){
return;
}
#if 1
//下沉式调整
size_t i = (size - 1 -1)/2;
for(;i > 0;i--){
AdjustDown(array,size,i);
}
AdjustDown(array,size,0);
#else
//上浮式调整
size_t bound = 0;
for(;bound < size;bound++){
AdjustUp(array,bound,bound);
}
#endif
return;
}
void HeapPop(int array[],size_t heap_size){
if(heap_size <= 1){
return;
}
Swap(&array[0],&array[heap_size - 1]);
AdjustDown(array,heap_size - 1,0);
return;
}
void HeapSort(int array[],size_t size){
if(size <= 1){
return;
}
//1.基于数组建立一个堆(如果是升序排序,建立大堆)
HeapCreate(array,size);
//2.循环的删除堆顶元素,将所有的堆顶元素都删除完了,排序完成
size_t i = 0;
for(;i < size - 1;i++){
//第二个参数表示数组中那部分区间是符合堆的规则
HeapPop(array,size - i);
}
return;
}
堆排序时间复杂度:O(N*logN)
空间复杂度:O(1)
稳定性:不稳定排序