冒泡排序
时间复杂度:
O
(
n
2
)
O(n^2)
O(n2)
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
using namespace std;
void bubbleSort(int arr[], int len)
{
int i, j;
for (i = 0; i < len - 1; i++)
{
for (j = 0; j < len - 1 - i; j++)
{
if (arr[j] > arr[j + 1])
{
std::swap(arr[j], arr[j + 1]);
}
}
}
}
int main(void)
{
int arr[20];
for (int i = 0; i < 20; i++)
{
arr[i] = rand() % 100;
cout << arr[i] << " ";
}
cout << endl;
bubbleSort(arr, 20);
for (int i = 0; i < 20; i++)
{
cout << arr[i] << " ";
}
cout << endl;
return 0;
}
快速排序
时间复杂度:
O
(
n
l
o
g
n
)
O(nlogn)
O(nlogn)
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
using namespace std;
int partition(int arr[], int left, int right)
{
if (left >= right) // 退出
{
return -1;
}
int temp = arr[left]; // 以第一个元素值为比较基准
while (left < right)
{
while (left < right && arr[right] >= temp) // 先从右侧开始查找比基准小的位置
{
right--;
}
if (left < right)
arr[left++] = arr[right]; // 把找到的值赋值给左侧,然后left位置右移一位
while (left < right && arr[left] <= temp) // 从左侧查找比基准大的位置
{
left++;
}
if (left < right)
arr[right--] = arr[left]; // 把找到的值赋值给右侧,然后right位置左移一位
}
arr[left] = temp;
return left;
}
void quickSort(int arr[], int left, int right)
{
if (left >= right) // 退出条件
{
return;
}
int l = partition(arr, left, right); // 中间位置
quickSort(arr, left, l - 1); // 递归左侧排序
quickSort(arr, l + 1, right); // 递归右侧排序
}
int main(void)
{
int arr[20];
for (int i = 0; i < 20; i++)
{
arr[i] = rand() % 100;
cout << arr[i] << " ";
}
cout << endl;
quickSort(arr, 0, 19);
for (int i = 0; i < 20; i++)
{
cout << arr[i] << " ";
}
cout << endl;
return 0;
}
应用:一个整形数组,把数据连接成一个最小的数
bool compare(int a, int b)
{
string strA = to_string(a);
string strB = to_string(b);
string strAB = strA + strB;
string strBA = strB + strA;
std::string::size_type sz; // alias of size_t
int ab = std::stoi(strAB, &sz);
int ba = std::stoi(strBA, &sz);
if (ab < ba)
{
return true;
}
return false;
}
int main(void)
{
int arr[] = {123, 11, 12, 222,212, 2123,2121, 111};
for (int i = 0; i < 8; i++)
{
cout << arr[i] << " ";
}
cout << endl;
quickSort(arr, 0, 7);
sort(arr, arr + 8, compare);
for (int i = 0; i < 8; i++)
{
cout << arr[i] << " ";
}
cout << endl;
return 0;
}
数组索引排序
int main()
{
int arr[] = {10, 20,1,2,0};
vector<int> idx(5);
itoa(idx.begin(), idx.end(), 0);
sort(arr, arr + 5, [&](int &i, int &j){return arr[i] > arr[j]});
return 0;
}
堆排序
对于大顶堆:arr[i] >= arr[2i + 1] && arr[i] >= arr[2i + 2]
对于小顶堆:arr[i] <= arr[2i + 1] && arr[i] <= arr[2i + 2]
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <iostream>
#include <memory>
using namespace std;
void heapify(int *arr, int i, int len)
{
// 先根据堆性质,找出它左右节点的索引
int left = 2 * i + 1;
int right = 2 * i + 2;
// 默认当前节点(父节点)是最大值。
int largestIndex = i;
if (left < len && arr[left] > arr[largestIndex])
{
// 如果有左节点,并且左节点的值更大,更新最大值的索引
largestIndex = left;
}
if (right < len && arr[right] > arr[largestIndex])
{
// 如果有右节点,并且右节点的值更大,更新最大值的索引
largestIndex = right;
}
if (largestIndex != i)
{
// 如果最大值不是当前非叶子节点的值,那么就把当前节点和最大值的子节点值互换
std::swap(arr[i], arr[largestIndex]);
// 因为互换之后,子节点的值变了,如果该子节点也有自己的子节点,仍需要再次调整。
heapify(arr, largestIndex, len);
}
}
void buildMaxHeap(int *arr, int length)
{
for (int i = (int)floor(length / 2) - 1; i >= 0; i--)
{
heapify(arr, i, length);
}
}
/**
* @brief 大堆排序.
* @param arr 数组(完全二差数).
* @param length 数组长度.
*/
void heapsort(int *arr, int length)
{
if (arr == nullptr || length == 0)
{
return;
}
buildMaxHeap(arr, length);
int i = length;
while (i)
{
std::swap(arr[0], arr[i -1]); // 交换第一个和最后一个未交换的位置
buildMaxHeap(arr, --i); // 后面交换后的位置,不参与大堆重建
}
}
int main()
{
int arr[8] = {9, 5, 1, 2, 3, 4, 7, 8};
heapsort(arr, 8);
return 0;
}