#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <string>
#include <list>
using namespace std;
int binSearch(vector<int>arr,int start,int end,int key)
{
int ret = -1;
int mid = start + ((end-start)>>1);
for(int a : arr)
{
if(key>a)
{
start = mid+1;
}
else if(key<a)
{
end = mid-1;
}
else
ret = mid;
}
return ret;
}
void sift_down(int arr[], int start, int end) {
// 建立父结点指标和子结点指标
int dad = start;
int son = dad * 2 + 1;
while (son <= end) { // 子结点指标在范围内才做比较
if (son + 1 <= end && arr[son] < arr[son + 1]) // 先比较两个子结点大小,选择最大的
son++;
if (arr[dad] >= arr[son]) // 如果父结点比子结点大,代表调整完毕,直接跳出函数
return;
else { // 否则交换父子内容,子结点再和孙结点比较
swap(arr[dad], arr[son]);
dad = son;
son = dad * 2 + 1;
}
}
}
void heap_sort(int arr[], int len) {
// 从最后一个节点的父节点开始sift down以完成堆化(heapify)
for (int i = (len - 1 - 1) / 2; i >= 0; i--) sift_down(arr, i, len - 1);
// 先将第一个元素和已经排好的元素前一位做交换,再重新调整(刚调整的元素之前的元素),直到排序完毕
for (int i = len - 1; i > 0; i--) {
swap(arr[0], arr[i]);
sift_down(arr, 0, i - 1);
}
}
// 模板的T参数表示元素的类型,此类型需要定义小于(<)运算
template <typename T>
// arr为需要被排序的数组,len为数组长度
void quick_sort(T arr[], const int len) {
if (len <= 1) return;
// 随机选择基准(pivot)
const T pivot = arr[rand() % len];
// i:当前操作的元素
// j:第一个等于pivot的元素
// k:第一个大于pivot的元素
int i = 0, j = 0, k = len;
// 完成一趟三路快排,将序列分为:小于pivot的元素 | 等于pivot的元素 |
// 大于pivot的元素
while (i < k) {
if (arr[i] < pivot)
swap(arr[i++], arr[j++]);
else if (pivot < arr[i])
swap(arr[i], arr[--k]);
else
i++;
}
// 递归完成对于两个子序列的快速排序
quick_sort(arr, j);
quick_sort(arr + k, len - k);
}
// 假设数组的大小是n+1,冒泡排序从数组下标1开始
void bubble_sort(int a[], int n) {
bool flag = true;
while (flag) {
flag = false;
for (int i = 1; i < n; ++i) {
if (a[i] < a[i - 1]) {
flag = true;
int t = a[i];
a[i] = a[i - 1];
a[i - 1] = t;
}
}
}
}
void merge(int a[],int t[],int ll, int rr) {
// 用来把 a[ll.. rr - 1] 这一区间的数排序。 t 数组是临时存放有序的版本用的。
if (rr - ll <= 1) return;
int mid = ll + (rr - ll >> 1);
merge(a,t,ll, mid);
merge(a,t,mid, rr);
int p = ll, q = mid, s = ll;
while (s < rr) {
if (p >= mid || (q < rr && a[p] > a[q])) {
t[s++] = a[q++];
// ans += mid - p; 求逆序对个数
} else
t[s++] = a[p++];
}
for (int i = ll; i < rr; ++i) a[i] = t[i];
}
//关键点在于一次性创建数组,避免在每次递归调用时创建,以避免对象的无谓构造和析构。
int main()
{
int arr[10] = {123,523,53,151,4,134,1,2431,234,14};
int t[10] = {0};
merge(arr,t,0,10);
for(auto a : arr)
{
cout<<a<<" ";
}
//int arr[6] = {1,4,5,7,8,9};
//vector<int> arr1(arr,arr+6);
//if(binSearch(arr1,0,6,8))
//{
// cout<<"OK"<<endl;
//}
while(1);
return 0;
}
归并/堆排/快排/二分---C++实现
最新推荐文章于 2022-12-02 19:33:36 发布