直接插入
基本思想:将整个队列分为有序区和无序区,然后依次从无序区中选择一个数,按大小顺序插入到有序区中去。图解示意如下,
代码实现
//从小到大排序
void InsertSort(int arr[], int len)
{
int temp = 0; //作为对比的临时数据
//无序区遍历
for (int i = 1; i < len; i++)
{
temp = arr[i];
//有序区遍历
for (int j = i - 1; j >= 0 && arr[j] > temp; j--)
{
//当发现临时数据比有序区的元素小时,将有序区的元素往前移动一步,
//而不需要将临时数据插入到空出来的位置,节省移动时间
arr[j + 1] = arr[j];
}
//将临时数据插入到最后满足条件的位置
arr[j + 1] = temp;
}
}
冒泡
基本思想:将第一个元素与第二个元素比较,如果第一个元素比第二个元素大,那么就将两者交换,并继续用第二个元素和第三个元素比较,在一个循环结束后,最大的元素会沉到数组的最右边,因此,下次循环就直接到倒数第二个元素为止,最后的一次循环就只剩第一个元素,至此,所有元素都排列完成。图解示意如下,
代码实现
//两个数据交换
void swap(int& a, int& b)
{
int temp = a;
b = a;
a = temp;
}
//基本实现
void BubbleSort(int arr[], int len)
{
//循环len次
for (int i = 0; i < len - 1; i++)
{
//从头遍历交换相邻两个元素
for (int j = 0; j < len - i - 1; j++)
{
if (arr[j] > arr[j + 1])
{
swap(arr[j], arr[j + 1]);
}
}
}
}
/**
*优化实现:对于已经遍历出的有序部分,不需要再遍历
*/
void BubbleSort(int arr[], int len)
{
//current记录当前所在的位置
//last记录最后发生交换的位置
int current = len, last = len - 1;
while (last < 0)
{
for (int i = current = 0; i < last; i++)
{
if (arr[i] > arr[i + 1])
{
swap(arr[i], arr[i + 1);
current = i; //记录当前所在的位置
}
}
//若current = 0即表示没有可以交换的元素了,即已经有序了
last = current;
}
}
快速排序
基本思想:首先以某一个位置的数为基准数,然后保证基准数的左边的元素都比基准数小,右边的元素都比基准数大;这样就分成两部分,再对这两部分也做同样的操作,通过这样一次次递归,从而达到排序的目的。图解示意如下,
/**
* @brief 得到基准值
* @param[in] first,是从0开始的z轴顺序
* @param[in] end,是从0开始的z轴顺序
*/
int getPivot(int arr[], int first, int end)
{
int key = arr[end]; //最后一个元素作为主元
int i = first; //插入队列中已有元素的下标
//从first遍历到倒数第二个元素
for (int j = first; j < end; j++)
{
if (arr[j] <= key)
{
swap(arr[j], arr[i]);
i++;
}
}
//交换i处和end处的元素
swap(arr[i], arr[end]);
return i;
}
void QuickSort(int arr[], int first, int end)
{
if (first < end)
{
int pivot = getPivot(arr, first, end);
QuickSort(arr, first, pivot - 1); //对基准左边的元素递归排序
QuickSort(arr, pivot + 1, end); //对基准右边的元素递归排序
}
}