插入排序
一、简单释义
通过不断将当前元素 「插入」 到 「升序」(降序) 序列中,直到所有元素都执行过 「插入」 操作,则算法结束。(以升序为例)
二、核心思想
- 「迭代」:类似的事情,反复地做。
- 「比较」:关系运算符 小于等于( <=) 的运用。
- 「移动」:原地后移元素。
三、算法详解
- 在一个乱序数组中,首先需要将 「第二个元素」 和 「第一个元素」 进行 「比较」,如果 前者(「第二个元素」) 小于等于 后者(「第一个元素」),则将 后者 进行向后 「移动」,前者 则执行插入;
- 然后,进行第二轮「比较」,即 「第三个元素」 和 「第二个元素」、「第一个元素」 进行 「比较」, 直到 「前三个元素」 保持有序 。
- 最后,经过一定轮次的「比较」 和 「移动」之后,一定可以保证所有元素都是 「升序」 排列的。
核心代码
void InsertSort(int n, int *a) // (1)
{
int i, j;
for(i = 1; i < n; ++i)
{
int x = a[i]; // (2)
for(j = i-1; j >= 0; --j) // (3)
{
if(x <= a[j]) // (4)
{
a[j+1] = a[j]; // (5)
}else
break; // (6)
}
a[j+1] = x; // (7)
}
}
- (1) void InsertSort(int n, int *a)为 插入排序 的实现,代表对a[ ]数组进行升序排序。
- (2) 此时a[ i ]前面的 i - 1个数都认为是排好序的,令x = a[ i ];
- (3) 逆序的枚举所有的已经排好序的数;
- (4) 如果枚举到的数a[j]比需要插入的数x大,则当前数往后挪一个位置;
- (5) 执行挪位置的 操作;
- (6) 否则,跳出循环;
- (7) 将x插入到合适位置;
冒泡排序
一、简单释义
通过不断比较相邻的元素,如果「左边的元素」 大于 「右边的元素」,则进行「交换」,直到所有相邻元素都保持升序,则算法结束。
二、核心思想
- 「迭代」:类似的事情,反复地做。
- 「比较」:关系运算符 大于( > ) 的运用。
- 「交换」:变量或者对象的值的交换。
三、算法详解
- 首先需要将 「第一个元素」 和 「第二个元素」 进行 「比较」,如果 前者 大于 后者,则进行 「交换」,然后再比较 「第二个元素」 和 「第三个元素」 ,以此类推,直到 「最大的那个元素」 被移动到 「最后的位置」 。
- 然后,进行第二轮「比较」,直到 「次大的那个元素」 被移动到 「倒数第二的位置」 。
- 最后,经过一定轮次的「比较」 和 「交换」之后,一定可以保证所有元素都是 「升序」 排列的。
核心代码
void Swap(int *a, int *b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}
void BubbleSort(int n, int *a) // (1)
{
bool swapped;
int last = n;
do
{
swapped = false; // (2)
for(int i = 0; i < last - 1; ++i) // (3)
{
if(a[i] > a[i+1]) // (4)
{
Swap(&a[i], &a[i+1]); // (5)
swapped = true; // (6)
}
}
--last;
}while (swapped);
}
- (1) void BubbleSort(int n, int *a)为冒泡排序的实现,代表对a[ ]数组进行升序排序。
- (2) swapped标记本轮迭代下来,是否有元素产生了交换。
- (3) 每次冒泡的结果,会执行last的自减,所以待排序的元素会越来越少。
- (4) 如果发现两个相邻元素产生逆序,则将它们进行交换。保证右边的- 元素一定不比左边的小。
- (5) swap实现了元素的交换,这里需要用&转换成地址作为传参。
- (6) 标记更新。一旦标记更新,则代表进行了交换,所以下次迭代必须继续。
选择排序
一、简单释义
通过不断从未排序的元素中,「比较」 和 「交换」,从而 「选择」 出一个最小的, 直到最后变成一个「升序」 序列,则算法结束。
二、核心思想
- 「迭代」:类似的事情,不停地做。
- 「比较」:关系运算符 小于( < ) 的运用。
- 「交换」:变量或者对象的值的互换。
三、算法详解
- 首先从 「第一个元素」 到 「最后一个元素」 中选择出一个 「最小的元素」,和 「第一个元素」 进行 「交换」;
- 然后,从 「第二个元素」 到 「最后一个元素」 中选择出一个 「最小的元素」,和 「第二个元素」 进行 「交换」。
- 最后,一定可以保证所有元素都是 「升序」 排列的。
核心代码
void Swap(int *a, int *b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}
void SelectionSort(int n, int *a) // (1)
{
int i, j;
for(i = 0; i < n - 1; ++i) // (2)
{
int min = i; // (3)
for(j = i+1; j < n; ++j) // (4)
{
if(a[j] < a[min])
{
min = j; // (5)
}
}
Swap(&a[i], &a[min]); // (6)
}
}
- (1) void SelectionSort(int n, int *a)为选择排序的实现,代表对a[]数组进行升序排序。
- (2) 从首元素个元素开始进行 n − 1次跌迭代。
- (3) 首先,记录min代表当前第 i 轮迭代的最小元素的下标为 i 。
- (4) 然后,迭代枚举第 i + 1个元素到 最后的元素。
- (5) 选择一个最小的元素,并且存储下标到 min 中。
- (6) 将 第 i 个元素 和 最小的元素 进行交换。