目录
1.选择排序
1.1选择排序的实现
1.11实现原理:
选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。 选择排序是不稳定的排序方法。
这只不过是思路大致图,具体看一下动图
1.12代码实现与讲解
//选择排序 void SelectSort(int* a, int n) { assert(a); int begin = 0; int end = n - 1; while (begin < end) { int mini = begin; int maxi = begin; for (int i = begin + 1; i <= end; i++) { if (a[i] > a[maxi]) { maxi = i; } if (a[i] < a[mini]) { mini = i; } } Swap(&a[begin], &a[mini]); //begin和maxi重叠,需要修正 if (begin == maxi) { maxi = mini; } Swap(&a[end], &a[maxi]); begin++; end--; } }
这里首先有begin记录起始位置下标,end记录这n个数最后位置的下标。
我们要找最小值和最大值,那找到后要记录他们,所以引入mini记录最小值下标,maxi记录最大值下标,一定注意是下标,不是数值。
1.2选择排序复杂度
对于内层循环来说,最好的情况就是顺序排列,比较1次就可以了,最差的情况是逆序排列比较n-1次,而外层循环i从第二个数到最后走了n-1次,所以0(N)是0(n^2)。可见选择排序的性能并不比直接插入排序要好。
2.冒泡排序
2.1冒泡排序概念及图解
冒泡排序就是重复地走访过要排序的元素列,依次比较两个相邻的元素,如果他们的顺序(如从大到小)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素已经排序完成。
就是比较相邻的数,谁小排前面,再比较第二三个数,再重新排序,依次重复完全。
上图:
动态图更形象一点!
2.2代码
2.21代码讲解
//冒泡排序
void BubbleSort(int* a, int n)
{
int i = 0;
for (i = 0; i < n - 1; i++)
{
int j = 0;
int flag = 0;
for (j = 0; j < n - 1 - i; j++)
{
//if ( a[j] < a[j + 1] )//降序
if (a[j] > a[j + 1])//升序
{
Swap(&a[j], &a[j + 1]);
flag = 1;
}
}
if (flag == 0)//当上面有一趟flag不是1,
//即没有位置交换就说明已经有序了,可以结束了。
{
break;
}
}
}
2.22注意:
外循环中循环了n-1次n个数,比较n-1次,没毛病。内循环中比较n-1-i次,在外循环进行i次后那就会有i个小数(大数)被固定好,所以就比较剩余的就行了。
2.23时间复杂度
就说最差情况下是多少。我们要顺序排,给的是逆序的,外层循环进行n-1次,内层循环最差也是n-1次。所以复杂度0(N)=0(n^2)。
2.3冒泡排序的优化
就比如下面的情况
这种还不到循环结束的边界但是后面已经有序了咋计算,如果再来俩循环或者使用上面的那个flag=1那个相对于优化的代码就有点多此一举了。上代码
void BubbleSort1(int*a, int n)
{
int k, flag;
flag = n - 1;
bool sortBorder = true;
while (flag)
{
k = flag;//初始化为size-1,以后每一次取出flag
flag = 0;//每一次flag重置为0
for (int i = 0; i < k; i++)
{
if (a[i] > a[i + 1])
{
Swap(&a[i], &a[i + 1]);
flag = i;//i最终的值为最后被排序的下标
sortBorder = false;
}
}
if (sortBorder)
{
break;
}
}
}