选择排序(固定位置,找元素)
基本思想:对于长度为N的无序数列,第一次遍历,将第0个元素和后边所有元素相比较,找出最小的元素,然后和第0个元素交换,第二遍历,将第1个元素和后边所有的元素比较,找出剩下元素中最小的元素,然后和第1个元素交换,重复以上步骤直至最后一次遍历只剩下两个元素的时候,排序完成。
时间复杂度:O(n*n)
空间复杂度:O(1)
是否是稳定排序:不是稳定排序
代码示例:(根据上面的算法思想不难写出下面的代码)
#include <stdio.h>
#include <stdlib.h>
#defind ARRAY_LEN(x) (sizeof(x)/sizeof((x)[0]))
int exchange_times = 0;
int compare_times = 0;
int Swap(int *a, int *b)
{
int c;
int ret = -1;
ret = (a != NULL)&&(b != NULL);
if(ret)
{
c = *a;
*a = *b;
*b = c;
}
return ret;
}
int SelectSort1(int a[], int n)
{
int ret = -1;
int i = 0, j = 0;
ret = (a != NULL)&&(n > 0);
if(ret)
{
//外层循环最多进行n-1次
for(i = 0; i < n - 1; i++)
{
for(j = i + 1; j < n; j++)
{
if(a[j] < a[i])
{
Swap(&a[i],&a[j]);
exchange_times++;
}
compare_times++;
}
}
}
return ret;
}
int PlayFunc(int *a, int n)
{
int i = 0;
int ret = -1;
ret = (a != NULL)&&(n > 0);
if(ret)
{
printf("Array[]:");
for(i = 0; i < n; i++)
printf("%d, ", a[i]);
printf("\n");
}
return ret;
}
void main()
{
int array[] = {8,5,10,7,6,9,4,3,2,1};
PlayFunc(array, ARRAY_LEN(array));
SelectSort1(array, ARRAY_LEN(array));
PlayFunc(array, ARRAY_LEN(array));
printf("exchange_times: %d\n", exchange_times);
printf("compare_times: %d\n", compare_times);
}
运行效果截图:
上面的选择排序一样可以优化,每次只做比较,记录下无序序列中最小元素的下标,即每次遍历最多交换一次。下面贴上代码:
int SelectSort2(int a[], int n)
{
int ret = -1;
int i = 0, j = 0;
int MinIndex = 0;
ret = (a != NULL)&&(n > 0);
if(ret)
{
//外层循环最多进行n-1次
for(i = 0; i < n - 1; i++)
{
MinIndex = i;
for(j = i + 1; j < n; j++)
{
if(a[j] < a[MinIndex])
{
MinIndex = j;//找出并记录最小值下标
}
compare_times++;
}
if(i != MinIndex)
{
Swap(&a[i],&a[MinIndex]);
exchange_times++;
}
}
}
return ret;
}
运行效果截图:(和上面优化前相比,元素交换次数大大减少)
算法是不是很神奇!!!
插入排序(固定元素,找位置)
基本思想:对于长度为N的无序数列,需要进行N-1次插入排序。第一次,数列中第0个数认为是有序的数列,将数列中第1个元素插入仅有1个有序的数列中,第二次,数列的前两个元素已经成了有序数列,继续将第2个元素插入到前面两个元素的有序序列中,直到第N-1次,将数组中第N-1(最后一个)个元素插入前面的有序序列中,插入排序完成。
时间复杂度:O(n*n)
空间复杂度:O(1)
是否是稳定排序:稳定排序
代码示例:
#include <stdio.h>
#include <stdlib.h>
#define SIZE 10
int exchange_times = 0;
int compare_times = 0;
int Swap(int *a, int *b)
{
int c;
int ret = -1;
ret = (a != NULL)&&(b != NULL);
if(ret)
{
c = *a;
*a = *b;
*b = c;
}
return ret;
}
int InsertSort1(int a[], int n)
{
int ret = -1;
int i = 0, j = 0;
int Temp = 0;
ret = (a != NULL)&&(n > 0);
if(ret)
{
for(i = 1; i < n; i++)
{
if(a[i-1] > a[i])//从小到大排列 0到i-1是已经排好的有序序列
{
Temp = a[i];
for(j = i - 1; (j >= 0) && (Temp < a[j]) ; j--)//边比较边挪数据
{
a[j+1] = a[j];
exchange_times++;
//compare_times++;
}
a[j+1] = Temp;//将数据插入恰当的位置
compare_times++;
}
}
}
return ret;
}
int PlayFunc(int *a, int n)
{
int i = 0;
int ret = -1;
ret = (a != NULL)&&(n > 0);
if(ret)
{
printf("Array[]:");
for(i = 0; i < n; i++)
printf("%d, ", a[i]);
printf("\n");
}
return ret;
}
void main()
{
int array[SIZE] = {8,5,10,7,6,9,4,3,2,1};
PlayFunc(array, 10);
InsertSort1(array, 10);
PlayFunc(array, 10);
printf("exchange_times: %d\n", exchange_times);
printf("compare_times: %d\n", compare_times);
}
运行效果截图:
此处的交换次数和比较次数不能说明什么,这个算是简单的插入排序吧。同样算法还可以继续优化...未完待续!!!