好久不看数据结构,天天调用别人封好的结构,感觉基本功都快忘光了,现在将压在箱底的数据结构翻出来看看,加深下印象。
闲话少说,水平所限,仅仅回顾几个最常用的排序算法,包括冒泡排序,直接插入排序,简单选择排序,快速排序,堆排序,归并排序,我个人将算法分为两大块,时间复杂度为O(N2)为一大类,其余为另外一大类。
先从最简单的排序说起吧,
冒泡排序原理:
冒泡排序(BubbleSort)的基本概念是:依次比较相邻的两个数,将小数放在前面,
* 大数放在后面。即首先比较第1个和第2个数,将小数放前,大数放后。
* 然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,
* 将小数放前,大数放后。重复以上过程,仍从第一对数开始比较(因为可能由于第2个数和第3个数的交换,
* 使得第1个数不再小于第2个数),将小数放前,大数放后,一直比较到最大数前的一对相邻数,
* 将小数放前,大数放后,第二趟结束,在倒数第二个数中得到一个新的最大数。
* 如此下去,直至最终完成排序。
* 由于在排序过程中总是小数往前放,大数往后放,相当于气泡往上升,所以称作冒泡排序。
* 冒泡排序属于稳定的排序,时间复杂性为o(n^2),空间复杂度为O(1)。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
{
int temp;
for (int i = 0; i < seq.Length; ++i)
{
for (int j = 1; j < seq.Length - i;++j )
{
if (seq[j - 1] > seq[j])
{
temp = seq[j];
seq[j] = seq[j - 1];
seq[j - 1] = temp;
}
}
}
}
直接插入排序原理:
/*每次从无序表中取出第一个元素,把它插入到有序表的合适位置,使有序表仍然有序。
* 第一趟比较前两个数,然后把第二个数按大小插入到有序表中;
* 第二趟把第三个数据与前两个数从后向前扫描,
* 把第三个数按大小插入到有序表中;依次进行下去,进行了(n-1)趟扫描以后就完成了整个排序过程。
* 直接插入排序属于稳定的排序,时间复杂性为o(n^2),空间复杂度为O(1)。
* 直接插入排序是由两层嵌套循环组成的。外层循环标识并决定待比较的数值。
* 内层循环为待比较数值确定其最终位置。直接插入排序是将待比较的数值与它的前一个数值进行比较,
* 所以外层循环是从第二个数值开始的。当前一数值比待比较数值大的情况下继续循环比较,
* 直到找到比待比较数值小的并将待比较数值置入其后一位置,结束该次循环。
* 值得注意的是,我们必需用一个存储空间来保存当前待比较的数值,
* 因为当一趟比较完成时,我们要将待比较数值置入比它小的数值的后一位
* 插入排序类似玩牌时整理手中纸牌的过程。插入排序的基本方法是:
* 每步将一个待排序的记录按其关字的大小插到前面已经排序的序列中的适当位置,直到全部记录插入完毕为止。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
{
int temp;
for (int i = 1; i < seq.Length; ++i)
{
temp = seq[i];
for (int j = i-1; j >=0;--j )
{
if (seq[j] > temp)
{
seq[j+1] = seq[j];
seq[j] = temp;
}
else
{
break;
}
}
}
}
简单选择排序原理:
/* 简单选择排序从待排序的序列中选择最小(或最大)的记录与第一个记录交换位置,然后下一次从不包括第一个记录的余下记录中
* 选择最小的与第二个记录交换,如此循环,直到只剩最后一个记录。
* 简单选择排序属于稳定的排序,时间复杂性为o(n^2),空间复杂度为O(1)。*/
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
{
int temp ;
for (int i = 0; i < seq.Length; ++i)
{
temp = seq[i];
for (int j = i + 1; j < seq.Length; ++j)
{
if (temp < seq[j])
{
temp = seq[j];
seq[j] = seq[i];
seq[i] = temp;
}
}
}
}