- 将一个记录插入到已排好序的序列中,从而得到一个新的有序序列。
重点:使用哨兵,用于临时存储和判断数组边界。
具体过程:
将序列的第一个数据看成是一个有序的子序列,然后从第二个记录逐个向该有序的子序列进行有序的插入,从后往前比较,直到相等或者大于该数。
void InsertSort(int arr[], int len)
{
int i, j,temp;
for (i = 1; i < len; ++i)
{
if (arr[i - 1] > arr[i])
{
temp = arr[i];
for (j = i-1 ; j >= 0 && arr[j] > temp; --j)
{
arr[j + 1] = arr[j];
}
arr[j + 1] = temp;
}
}
return;
}
- 希尔排序算法是直接插入排序算法的一种改进,减少了其复制的次数,速度要快很多。不需要大量的辅助空间,不是一种稳定排序。
具体方法:取缩小的增量进行分组,每个组进行直接插入排序。
- 进行N趟比较,每次找出最小的元素,放在第i趟选择的位置
void my_select_sort(vector<int>& v)
{
int i, j, temp,length=v.size();
for (i = 0; i < length; ++i)
{
temp = i;
for (j = i + 1; j < length ; ++j)
{
if (v[temp] > v[j])
{
temp = j;
}
}
j = v[temp];
v[temp]=v[i];
v[i] = j;
}
return;
}
- 堆:顺序储存的完全二叉树
大根堆:父节点大于等于子节点
小根堆:父节点小于等于子节点
排序过程:以小根堆为例:
1. 堆初始化,将最大的节点初始化到根节点,
具体:从n/2-1(最后一个父亲节点)开始与最大的子节点比较互换
2. 将初始化后的最大根节点与数组最后一个元素交换,数组
长度-1,继续进行初始化,将最大节点交换到根节点
3. 重复n次步骤2,就可以得到一个小根堆
- 进行N趟的比较,每趟从i=0位置向后比较,相邻的较小的放在前面,一趟过后最大元素在上一趟最大元素前面。
- 选择一个基准,比它大的放在右边,比它小的放在左边,再进行递归调用。
具体实现:
一般选择第一个数作为基准,使用哨兵记录该数,先从右往左扫描,直到找到比哨兵大的数,将其与基准数位置交换;
再从左往右扫描,出现比哨兵大的数,则将其交换到上一次交换后右侧的空缺位置;
如此反复,直到左右扫描接触,接触点放置哨兵,在左右分治,递归调用;
void QuickSort(int arr[], int left, int right)
{
if (left < right)
{
int i, j, temp;
i = left;
j = right;
temp = arr[i];
while (i < j)
{
while (i<j && arr[j] > temp)
--j;
if (i < j)
{
arr[i] = arr[j];
++i;
}
while (i < j && arr[i] < temp)
++i;
if (i < j)
{
arr[j] = arr[i];
--j;
}
}
arr[i] = temp;
QuickSort(arr, left, i - 1);
QuickSort(arr, i + 1, right);
}
return;
}
- 归并排序,是创建在归并操作上的一种有效的排序算法。算法是采用分治法。