通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此也称为非线性时间比较类排序。
排序方法 | 时间复杂度(平均) | 时间复杂度(最坏) | 时间复杂度(最好) | 空间复杂度 | 稳定性 |
---|---|---|---|---|---|
冒泡排序 | O(n^2) | O(n^2) | O(n) | O(1) | 稳定 |
快速排序 | O(nlog2n) | O(n^2) | O(nlog2n) | O(n) | 不稳定 |
插入排序 | O(n^2) | O(n^2) | O(n) | O(1) | 稳定 |
希尔排序 | O(n^1.3) | O(n^2) | O(n) | O(1) | 不稳定 |
选择排序 | O(n^2) | O(n^2) | O(n^2) | O(1) | 不稳定 |
堆排序 | O(nlog2n) | O(nlog2n) | O(nlog2n) | O(1) | 不稳定 |
归并排序 | O(nlog2n) | O(nlog2n) | O(nlog2n) | O(n) | 稳定 |
介绍:
冒泡排序是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。
算法描述:
#include
using namespace std;
int bubbleSort(int arr[],int n)
{
for (int i = 0; i < n - 1; i++)
{
for (int j = 0; j < n - i - 1; j++)
{
if (arr[j] > arr[j + 1])
{
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
return 0;
}
int main()
{
int arr[1000];
int n;
cout << "请输入数组中元素的个数:";
cin >> n;
cout << "请输入元素: " << endl;
for (int i = 0; i < n; i++)
{
cin >> arr[i];
}
cout << "排序前:" << endl;
for (int i = 0; i < n; i++)
{
cout << arr[i] << " ";
}
cout << endl;
bubbleSort(arr, n);
cout << "排序后:" << endl;
for (int i = 0; i < n; i++)
{
cout << arr[i] << " ";
}
cout << endl;
return 0;
}
int bubbleSort(int arr[],int n)
{
for (int i = 0; i < n - 1; i++)
{
bool flag = true;
for (int j = 0; j < n - i - 1; j++)
{
if (arr[j] > arr[j + 1])
{
flag = false;
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
if (flag)
{
break;
}
}
return 0;
}
这样,当后面已经排序好了的情况下,我们就不需要再去遍历后面的元素了。
#include
using namespace std;
int swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
return 0;
}
int quicksort(int arr[], int left, int right)
{
if (left >= right)
{
return 0;
}
int i = left;
int j = right + 1;
int key =arr[left];//设置基准值
while (true)
{
//从左向右找比key大的值
while (arr[++i] < key && i != right);
//从右向左找比key小的值
while (arr[--j] > key && j != left);
if (i >= j)
{
break;
}
//交换ij对应的值
swap(&arr[i], &arr[j]);
}
//将基准值(中枢值)与j所对应的值交换,因为arr[J]是小于基准中下标最大的
swap(&arr[left], &arr[j]);
quicksort(arr, left, j - 1);
quicksort(arr, j + 1, right);
return 0;
}
int main()
{
int arr[1000];
int n;
cout << "请输入数组中元素的个数:";
cin >> n;
cout << "请输入元素: " << endl;
for (int i = 0; i < n; i++)
{
cin >> arr[i];
}
cout << "排序前:" << endl;
for (int i = 0; i < n; i++)
{
cout << arr[i] << " ";
}
cout << endl;
quicksort(arr, 0, n - 1);
cout << "排序后:" << endl;
for (int i = 0; i < n; i++)
{
cout << arr[i] << " ";
}
cout << endl;
return 0;
}
运行结果如下:
虽然我们实现了快速排序,但是却存在两个问题:
解决以上问题的方法:
代码演示:
#include
#include
using namespace std;
//交换
int swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
return 0;
}
//简单插入排序
int insertsort(int arr[], int n)
{
int temp, i, j;
for (i = 1; i < n; i++)
{
temp = arr[i];
for (j = i; j > 0 && arr[j - 1] > temp; j--)
{
arr[j] = arr[j - 1];
}
arr[j] = temp;
}
return 0;
}
//获得基准值
int median3(int arr[], int left, int right)
{
int center = (left + right) / 2;
if (arr[left] > arr[center])
{
swap(&arr[left], &arr[center]);
}
if (arr[left] > arr[right])
{
swap(&arr[left], &arr[right]);
}
if (arr[center] > arr[right])
{
swap(&arr[center], &arr[right]);
}
//此时arr[left]
swap(&arr[center], &arr[right - 1]);//已知arr[right]>arr[center]
return arr[right - 1];//只需考虑arr[left+1]到arr[right-2]的值,所以返回arr[right-1]
}
//快排
int quicksort(int arr[], int left, int right)
{
int key, i, j;
if (right - left > 3)//当元素较多时调用快速排序
{
key = median3(arr, left, right);//选择基准
i = left;
j = right - 1;
while (true)
{
while (arr[++i] < key);//从左向右找比key大的值
while (arr[--j] > key);//从右向左找比key小的值
if (i > j)
{
break;
}
swap(&arr[i], &arr[j]);
}
swap(&arr[i], &arr[right - 1]);//将基准值与按顺序第一个大于基准值的元素交换,保证前面小于后面大于基准
quicksort(arr, left, i - 1);//递归解决左边的
quicksort(arr, i + 1, right);//递归解决右边的
}
else//当元素较少时,直接用简单插入排序
{
insertsort(arr + left, right - left + 1);
}
return 0;
}
int main()
{
int arr[1000];
int n;
cout << "请输入数组中元素的个数:";
cin >> n;
cout << "请输入元素: " << endl;
for (int i = 0; i < n; i++)
{
cin >> arr[i];
}
cout << "排序前:" << endl;
for (int i = 0; i < n; i++)
{
cout << arr[i] << " ";
}
cout << endl;
quicksort(arr, 0, n - 1);
cout << "排序后:" << endl;
for (int i = 0; i < n; i++)
{
cout << arr[i] << " ";
}
cout << endl;
return 0;
}
#include
using namespace std;
int insertionSort(int arr[], int n)
{
int temp, i, j;
for (i = 1; i < n; i++)
{
temp = arr[i];
for (j = i; j > 0 && arr[j - 1] > temp; j--)
{
arr[j] = arr[j - 1];
}
arr[j] = temp;
}
return 0;
}
int main()
{
int arr[1000];
int n;
cout << "请输入数组中元素的个数:";
cin >> n;
cout << "请输入元素: " << endl;
for (int i = 0; i < n; i++)
{
cin >> arr[i];
}
cout << "排序前:" << endl;
for (int i = 0; i < n; i++)
{
cout << arr[i] << " ";
}
cout << endl;
insertionSort(arr, n);
cout << "排序后:" << endl;
for (int i = 0; i < n; i++)
{
cout << arr[i] << " ";
}
cout << endl;
return 0;
}
#include
using namespace std;
int shellSort(int arr[], int n)
{
for (int gap = n / 2; gap > 0; gap--)//确定增量
{
for (int i = gap; i < n; i += gap)//每次都间隔增量,将这些排序
{
int temp = arr[i];
int j;
for (j = i; j >= gap && arr[j - gap] > temp; j -= gap)
{
arr[j] = arr[j - gap];
}
arr[j] = temp;
}
}
return 0;
}
int main()
{
int arr[1000];
int n;
cout << "请输入数组中元素的个数:";
cin >> n;
cout << "请输入元素: " << endl;
for (int i = 0; i < n; i++)
{
cin >> arr[i];
}
cout << "排序前:" << endl;
for (int i = 0; i < n; i++)
{
cout << arr[i] << " ";
}
cout << endl;
shellSort(arr, n);
cout << "排序后:" << endl;
for (int i = 0; i < n; i++)
{
cout << arr[i] << " ";
}
cout << endl;
return 0;
}
#include
using namespace std;
int selectionSort(int arr[], int n)
{
for (int i = 0; i < n; i++)
{
int minIndex = i;
for (int j = i + 1; j < n; j++)
{
if (arr[minIndex] > arr[j])
{
minIndex = j;
}
}
int temp = arr[minIndex];
arr[minIndex] = arr[i];
arr[i] = temp;
}
return 0;
}
int main()
{
int arr[1000];
int n;
cout << "请输入数组中元素的个数:";
cin >> n;
cout << "请输入元素: " << endl;
for (int i = 0; i < n; i++)
{
cin >> arr[i];
}
cout << "排序前:" << endl;
for (int i = 0; i < n; i++)
{
cout << arr[i] << " ";
}
cout << endl;
selectionSort(arr, n);
cout << "排序后:" << endl;
for (int i = 0; i < n; i++)
{
cout << arr[i] << " ";
}
cout << endl;
return 0;
}
#include
#include
using namespace std;
int percDown(int arr[], int p, int n)//建立最大堆
{
int parent, child;//标记根结点和孩子结点
int x;
x = arr[p];
for (parent = p; (parent * 2 + 1) < n; parent = child)
{
child = parent * 2 + 1;//获得孩子结点的下标
if ((child != n - 1) && (arr[child] < arr[child + 1]))
{
child++;//指向左右子结点的较大者
}
if (x >= arr[child])//找到合适的位置,即根结点大于子结点
{
break;
}
else
{
arr[parent] = arr[child];//反之交换
}
}
arr[parent] = x;
return 0;
}
int swap(int *x, int *y)//交换
{
int temp = *x;
*x = *y;
*y = temp;
return 0;
}
int heapSort(int arr[], int n)//堆排序
{
for (int i = n / 2 - 1; i >= 0; i--)
{
percDown(arr, i, n);//建立最大堆
}
for (int i = n - 1; i > 0; i--)
{
swap(&arr[0], &arr[i]);//将最大堆中的最大值放在arr[i]
percDown(arr, 0, i);//然后用0-i创建最大堆获取最大值,即删除最大堆顶
}
return 0;
}
int main()
{
int arr[1000];
int n;
cout << "请输入数组中元素的个数:";
cin >> n;
cout << "请输入元素: " << endl;
for (int i = 0; i < n; i++)
{
cin >> arr[i];
}
cout << "排序前:" << endl;
for (int i = 0; i < n; i++)
{
cout << arr[i] << " ";
}
cout << endl;
heapSort(arr, n);
cout << "排序后:" << endl;
for (int i = 0; i < n; i++)
{
cout << arr[i] << " ";
}
cout << endl;
return 0;
}
#include
using namespace std;
//将arr[left]-arr[center-1]和arr[center]-arr[right]归并成一个序列
int merge(int arr[], int tmparr[], int left, int center, int right)
{
int l_end = center - 1;//左边终点的位置
int tmp = left;//有序序列的起始位置
int len = right - left + 1;//总长度
while (left <= l_end && center <= right)
{
if (arr[left] <= arr[center])//将小的元素先复制到tmparr中
{
tmparr[tmp++] = arr[left++];//将左边的元素复制到tmparr中
}
else
{
tmparr[tmp++] = arr[center++];//将右边的元素复制到tmparr中
}
}
while (left <= l_end)//直接将左边剩下的所有元素都复制到tmparr中
{
tmparr[tmp++] = arr[left++];
}
while (center <= right)//直接将右边剩下的所有元素都复制到tmparr中
{
tmparr[tmp++] = arr[center++];
}
//将有序的tmparr复制回arr中
for (int i = 0; i < len; i++,right--)
{
arr[right] = tmparr[right];
}
return 0;
}
int msort(int arr[], int tmparr[], int left, int right)
{
int center;
if (left < right)
{
center = (left + right) / 2;
msort(arr, tmparr, left, center);//递归解决左边
msort(arr, tmparr, center + 1, right);//递归解决右边
merge(arr, tmparr, left, center + 1, right);//合并两段有序序列并排序
}
return 0;
}
int mergeSort(int arr[], int n)
{
int *tmparr;
//创建一个数组,以便归并
tmparr = (int *)malloc(n * sizeof(int));
if (tmparr != NULL)
{
msort(arr, tmparr, 0, n - 1);
//释放空间
free(tmparr);
}
else
{
cout << "空间不足" << endl;
}
return 0;
}
int main()
{
int arr[1000];
int n;
cout << "请输入数组中元素的个数:";
cin >> n;
cout << "请输入元素: " << endl;
for (int i = 0; i < n; i++)
{
cin >> arr[i];
}
cout << "排序前:" << endl;
for (int i = 0; i < n; i++)
{
cout << arr[i] << " ";
}
cout << endl;
mergeSort(arr, n);
cout << "排序后:" << endl;
for (int i = 0; i < n; i++)
{
cout << arr[i] << " ";
}
cout << endl;
return 0;
}