这里对排序算法做一个总结,还未完结,后序还将加入希尔排序等排序方法。
将每一个数依次与其后面的数做对比,如果前后两个数逆序,则交换,然后进行下一步对比,经过每一个交换,最大的数都会被换到数组尾部,然后使数组总长度减一,这里为了节省时间,可以设置一个标志位,在每一次循环的开始都设为 true,如果在遍历过程中发生交换,则同时置为 false,经过一次完整循环以后没有发生过一次交换,则标志位一直为 true 视为数组已经有序,直接结束。
void bubbleSort(vector &A)
{
int n = A.size();
bool sorted = false; // flag to save time
while (!sorted)
{
sorted = true;
for (int i = 0; i < n-1; i++)
{
if (A[i]>A[i+1])
{
swap(A[i], A[i + 1]);
sorted=false;
}
}
n--;
}
}
每一次迭代都找到从出发位置开始后面数组中的最小数字,然后让其与当前位置的值互换,需要借助两个中间遍历来记录最小值的位置与数值。
void selectionSort(vector &A)
{
int k=0; int temp=0;
for (int i = 0; i < A.size(); i++)
{
k = i;
temp = A[i];
for (int j = i; j < A.size(); j++)
{
if (temp > A[j])
{
k = j;
temp = A[j];
}
}
A[k] = A[i];
A[i] = temp;
}
}
当数组中只有一个数时数组肯定有序,这里假设数组前半部分是有序的,则只要从数组的后半部分每次取一个数,查找到这个待插入的数在前半部分的位置,让后将其加入,直到后半部分数组长度为0,整个数组即有序。
void insertSort(vector& A) {
for (int i = 1; i < A.size(); i++)
{
for (int j = 0; j < i; j++) {
if (A[j] > A[i])
{
swap(A[j],A[i])
}
}
}
}
这里首先找到一个中心旋转点,一般是数组 A 的第一个A[0]/最后一个元素A[A.size()-1],这里以 A[0] 为旋转点为例,设置两个哨兵i,j 分辨去找大于 A[0] 和 大于 A[0] 的点,哨兵 i 从左向右遍历,当满足 i <= j,并且A[i] > A[0]时,i停下,同理 j 从右向左找小于A[0] 的值,当满足 i<=j,且 A[j] < A[0]时,j 停下,交换 A[i] 和 A[j],然后继续向前寻找,直到 i> j 时,以 A[0] 为中间点的,然后对 A[0] 的左、右分辨重复上面的过程。
int partition(vector& a, int left, int right) {
int i = left;
int j = right;
int temp = a[right];
while (i =temp)
{
j--;
}
if (i < j)
swap(a[i], a[j]);
}
swap(a[j], a[right]);
return j;
}
void quickSort(vector a, int left, int right) {
if (left >= right)
{
return;
}
int j = partition(a, left, right);
quickSort(a, left, j - 1);
quickSort(a, j + 1, right);
}
void merge(vector&s1, vector& s2, vector & result)
{
int i = 0, j = 0;
for (; i < s1.size()&&j= s2[j])
{
result.push_back(s2[j]);
j++;
}
else {
result.push_back(s1[i]);
i++;
}
}
if (i < s1.size())
{
for(int k=i;k&nums)
{
if (nums.size() <= 1)
return;
int i = 0, j = nums.size();
int mid = (i + j) / 2;
vector s1;
vector s2;
for (int k = 0; k < mid; k++)
s1.push_back(nums[k]);
for (int k = mid; k < j; k++)
s2.push_back(nums[k]);
mergeSort(s1);
mergeSort(s2);
nums.clear();
merge(s1, s2, nums);
}
数组实现
void merge(vector& A, int lo, int mi, int hi) {
int ll = mi - lo + 1; int lr = hi - mi;
vector L(ll+1, 0);
vector R(lr+1, 0);
for (int i = 0; i < ll; i++) {
L[i] = A[lo + i];
}
for (int j = 0; j < lr; j++) {
R[j] = A[mi + j+ 1];
}
L[ll] = INT_MAX;
R[lr] = INT_MAX;
for (int i = 0, j = 0, k = lo; k <= hi; k++)
{
if (L[i] <= R[j])
A[k] = L[i++];
else
A[k] = R[j++];
}
}
void mergeSort(vector& A, int lo, int hi)
{
// 若两数组默认有序,则直接 hi-lo<2 ,就可以 return,这里还需要换一下
if (hi - lo == 1)
{
if (A[lo] > A[hi]) {
swap(A[lo], A[hi]);
return;
}
}
if (hi - lo<1)
{
return;
}
int mi = (hi + lo) >> 1;
mergeSort(A, lo, mi);
mergeSort(A, mi + 1, hi);
merge(A, lo, mi, hi);
}
void adjust(vector &arr, int len, int index)
{
int left = 2 * index + 1; // index的左子节点
int right = 2 * index + 2;// index的右子节点
int maxIdx = index;
if (left arr[maxIdx]) maxIdx = left;
if (right arr[maxIdx]) maxIdx = right;
if (maxIdx != index)
{
swap(arr[maxIdx], arr[index]);
adjust(arr, len, maxIdx);
}
}
// 堆排序
void heapSort(vector &arr, int size)
{
// 构建大根堆(从最后一个非叶子节点向上)
for (int i = size / 2 - 1; i >= 0; i--)
{
adjust(arr, size, i);
}
// 调整大根堆
for (int i = size - 1; i >= 1; i--)
{
swap(arr[0], arr[i]); // 将当前最大的放置到数组末尾
adjust(arr, i, 0); // 将未完成排序的部分继续进行堆排序
}
}