复习数据结构时,仿照王道数据结构考研复习指导,复现九大排序算法,包括插入排序(直接插入排序,折半插入排序,希尔排序),交换排序(冒泡排序,快速排序),选择排序(简单选择排序,堆排序),归并排序和基数排序。
以下算法均采用C++实现。
插入排序
直接插入排序
直接插入排序是每次将一个待排序的记录插入已经排好序的子序列,直到全部记录插入完成。 即:1.从前面的有序子表中查找出待插入元素应该被插入的位置;2.给插入位置腾出空间,将待插入元素复制到表中的插入位置
void InsertSort1(int A[], int n)
{
int i, j;
for (i = 2; i <= n; i++)
{
if (A[i] < A[i - 1])
{
A[0] = A[i];
j = i - 1;
do
{
A[j + 1] = A[j];
j--;
} while (j >= 1 && A[j] > A[0]);
A[j + 1] = A[0];
}
}
}
其中,A[0]为哨兵元素。 直接插入排序:时间复杂度O(n2),空间复杂度O(1),稳定的排序算法。
折半插入排序
折半插入排序减少比较元素的次数。
void InsertSort2(int A[], int n)
{
int i, j;
for (i = 2; i <= n; i++)
{
A[0] = A[i];
int l = 1, r = i - 1;
while (l <= r)
{
int mid = l + (r - l) / 2;
if (A[0] < A[mid])
r = mid - 1;
else
l = mid + 1;
}
for (j = i - 1; j >= r + 1; j--)
{
A[j + 1] = A[j];
}
A[r + 1] = A[0];
}
}
折半插入排序时间复杂度仍为O(n2),是一种稳定的排序算法。
希尔排序
希尔排序又称为缩小增量排序,即把相隔某个增量的记录组成一个子表,对各个子表分别进行直接插入排序,当整个表中的元素已经“基本有序”时,再对全体记录进行一次直接插入排序。
void ShellSort(int A[], int n)
{
int i, j, dk;
for (dk = n / 2; dk >= 1; dk = dk / 2)
{
for (i = dk + 1; i <= n; i++)
if (A[i] < A[i - dk])
{
A[0] = A[i];
for (j = i - dk; j > 0 && A[j] > A[0]; j -= dk)
{
A[j + dk] = A[j];
}
A[j + dk] = A[0];
}
}
}
希尔排序,时间复杂度约为O(n1.3),最坏情况O(n2),空间复杂度O(1),不稳定的排序。
交换排序
冒泡排序
冒泡排序,从后往前(或从前往后)两两比较相邻元素的值,若为逆序,则交换,重复n-1趟。
void BubbleSort(int A[], int n)
{
for (int i = 0; i < n - 1; i++)
{
bool flag = false;
for (int j = n - 1; j > i; j--)
{
if (A[j] < A[j - 1])
{
swap(A[j], A[j - 1]);
flag = true;
}
}
if (!flag)
return;
}
}
冒泡排序,空间复杂度O(1),时间复杂度O(n2),稳定的排序方法
快速排序
快速排序的基本思想是基于分治法的,任取一个元素pivot作为枢轴,划分为两部分。左半部分<pivot,右半部分>pivot。快速排序的partition有很多种实现方法,这里采用王道408中描述的方法进行实现。
int Partition(int A[], int low, int high)
{
int pivot = A[low];
while (low < high)
{
while (low < high && A[high] >= pivot)
high--;
A[low] = A[high];
while (low < high && A[low] <= pivot)
low++;
A[high] = A[low];
}
A[low] = pivot;
return low;
}
void QuickSort(int A[], int low, int high)
{
if (low < high)
{
int pivotpos = Partition(A, low, high);
QuickSort(A, low, pivotpos - 1);
QuickSort(A, pivotpos + 1, high);
}
}
快速排序:空间复杂度O(logn),时间复杂度O(nlogn),不稳定的排序方法,快速排序是所有内部排序算法中平均性能最优的排序算法
选择排序
简单选择排序
简单选择排序,每一趟选择关键字最小的元素,作为有序子序列的第i个元素。
void SelectSort(int A[], int n)
{
for (int i = 0; i < n - 1; i++)
{
int min = i;
for (int j = i + 1; j < n; j++)
{
if (A[min] > A[j])
{
min = j;
}
}
if (min != i)
swap(A[min], A[i]);
}
}
选择排序,时间复杂度O(n2),空间复杂度O(1),不稳定的排序算法
堆排序
咕咕咕
归并排序
归并排序,将两个或两个以上的有序表组合成一个新的有序表,将前后相邻的两个有序表归并为一个有序表,两两进行归并。
void Merge(int A[], int left, int mid, int right)
{
int B[1001];
for (int i = left; i <= right; i++)
{
B[i] = A[i];
}
int s1 = left, s2 = mid + 1, s = left;
while (s1 <= mid && s2 <= right)
{
if (B[s1] <= B[s2]) A[s++] = B[s1++];
else if (B[s1] > B[s2]) A[s++] = B[s2++];
}
while (s1 <= mid)
{
A[s++] = B[s1++];
}
while (s2 <= right)
{
A[s++] = B[s2++];
}
}
void MergeSort(int A[], int left, int right)
{
if (left < right)
{
int mid = (left + right) / 2;
MergeSort(A, left, mid);
MergeSort(A, mid + 1, right);
Merge(A, left, mid, right);
}
}
归并排序,空间复杂度O(n),时间复杂度O(nlogn),稳定的排序算法
基数排序
咕咕咕
|