一,直接插入排序:
每趟将一个待排序的关键字按照其值的大小插入到已经排好的部分有序序列的适当位置上,直到所有待排关键字都被插入到有序序列中为止,复杂度最坏n^2,最好为n
void InsertSort(int R[], int n) //代拍关键字存储在R[]中,默认为整形,个数为n
{
int i = 0, j = 0;
int temp = 0;
for (i = 1; i < n; ++i)
{
temp = R[i]; //将待插入关键字暂存于temp中
j = i - 1;
//下面这个循环完成待排关键字之前的关键字开始扫描,如果大于待排关键字,则后移一位
while (j >= 0 && temp < R[j])
{
R[j + 1] = R[j];
--j;
}
R[j + 1] = temp; //找到插入位置,将temp中暂存的待排关键字插入
}
}
//直接插入算法的时间复杂度为O(n*n)
二,希尔排序:
希尔排序又称之为缩小增量排序,其本质还是插入排序,只不过是将待排序列按照某种规则分成几个子序列,分别对这几个子序列进行直接插入排序。这个规则的体现就是增量的选取.希尔排序复杂度最坏n^2,最好为n
void Shellsort(int Array[], int n)
{
int d = n / 2; //设置起始增量
while (d >= 1) //增量为1时排序结束
{
for (int k = 0; k < d; ++k) //遍历所有的子序
{
for (int i = k + d; i < n; i += d) //对每个子序进行插入排序
{
int temp = Array[i];
int j = i - d;
while (j >= k && Array[j] > temp)
{
Array[j + d] = Array[j];
j -= d;
}
Array[j + d] = temp;
}
}
d = d / 2; //缩小增量
}
}
三,冒泡排序:
比较相邻的元素。如果第一个比第二个大,就交换他们两个。对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。针对所有的元素重复以上的步骤,除了最后一个。 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。复杂度最坏n^2,最好为n
//冒泡排序:时间复杂度为O(n*n)
void BubbleSort(int R[], int n) //默认待排序关键字为整型
{
int i = 0, j = 0, flag = 0;
int temp;
for (int i = n - 1; i >= 1; --i)
{
flag = 0; //变量flag用来标记本堂排序是否发生了交换
for (j = 1; j <= i; ++j)
if (R[j - 1] > R[j])
{
temp = R[j];
R[j] = R[j - 1];
R[j - 1] = temp;
flag = 1; //如果没有发生交换,则flag的值为0,;如果发生了交换,flag的值改为1
}
if (0 == flag) //一趟排序过程中如果没有发生关键字交换,则证明序列有序,排序结束
return;
}
}
四,快速排序:
交换类的排序,它通过多次划分操作实现排序。以升序为例,其执行流程可以概括为:每一趟选择当前所有子序列中的一个关键字(通常是第一个)作为枢轴,将子序列中比枢轴小的移到枢轴的前边,比枢轴大的移动到枢轴的后边;当本趟所有的子序列都被枢轴以上述规则划分完毕后会的到新的一组更短的子序列,它们成为下一趟划分的初始序列集。快速排序的算法思想基于分治思想的,最好复杂度为O(n*logn),最坏时间复杂度为O(n*n)
void QuickSort(int R[], int low, int high) //对从R[Low]到R[High]的关键字进行排序
{
int temp = 0;
int i = low, j = high;
if (low < high)
{
temp = R[low];
//下面这个循环完成了一趟排序,即数组中小于temp的关键字放在左边,大于temp的关键字放在右边。左边和右边的分界点就是temp的最终位置
while (i < j)
{
while (i < j && R[j] >= temp) //先从右往左扫描,找到第一个小于temp的关键字
--j;
if (i < j) //这个判断保证退出上面的while循环是因为R[j] < temp,而不是因为 i>= j退出循环的,此步非常重要切忌将其忽略
{
R[i] = R[j]; //放在temp左边
++i; //i右移一位
}
while (i < j && R[i] <= temp) //从右往左扫描,找到一个大于temp的关键字
++i;
if (i < j)
{
R[j] = R[i]; //放在tem的左边
--j; //j右移一位
}
}
R[j] = temp; //将temp放在最终的位置上
QuickSort(R, low, i - 1); //递归的对temp左边的关键字进行排序
QuickSort(R, i + 1, high); //递归的对temp右边的关键字进行排序
}
}
五,选择排序:
选择类排序的主要动作是“选择”。简单选择采用最简单的选择方式,从头至尾扫描序列,选出
最小的一个关键字,和第一个关键字交换,接着从剩下的关键字中继续这种选择和交换,最终使序列有序。平均时间复杂度为n^2
void SelectSort(int R[], int n)
{
int i = 0, j = 0, k = 0;
int temp = 0;
for (i = 0; i < n; ++i)
{
k = i;
//下面这个循环是算法的关键,它从序列中挑选出最小的一个关键字
for (j = i + 1; j < n; ++j)
{
if (R[k] > R[j])
k = j;
}
//下面三句完成最小关键字与无序序列的第一个关键字的交换
temp = R[i];
R[i] = R[k];
R[k] = temp;
}
}