2.认识O(NlogN)的排序---C++版左程云耗时100天打造算法与数据一周刷爆LeetCode

 1.递归法寻求数组arr(L,R)上的最大值

#include<iostream>
#include<vector>
#include <algorithm>
using namespace std;

int process(vector<int> arr,int L,int R) {
	if (L == R)
		return arr[L];
	int mid = L + ((R - L) >> 1);
	int leftMax = process(arr, L, mid);
	int rightMax = process(arr, mid+1, R);
	return max(leftMax, rightMax);

}

2.归并排序算法

#include<iostream>
#include<vector>
#include <algorithm>
using namespace std;


void merge(vector<int>& arr, int L, int R, int M);
void mergeSort(vector<int>&arr,int L,int R) {
	if (L == R)
		return ;
	int mid = L + ((R - L) >> 1);
	mergeSort(arr, L, mid);
	mergeSort(arr, mid+1, R);
	merge(arr, L, R,mid);
}
void merge(vector<int>& arr, int L, int R, int M) {
	int i = 0;
	int p1 = L;
	int p2 = M + 1;
	vector<int> arr1(R - L + 1); // 分配足够的内存空间
	while (p1 <= M && p2 <= R)
		arr1[i++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++];
	while (p1 <= M)
		arr1[i++] = arr[p1++];
	while (p2 <= R)
		arr1[i++] = arr[p2++];
	for (i = 0; i < arr1.size(); i++)
		arr[L + i] = arr1[i];

}

3.小和问题

采用归并排序算法代码如下:

#include<iostream>
#include<vector>
#include <algorithm>
using namespace std;


int merge(vector<int>& arr, int L, int R, int M);
int smallAdd(vector<int>& arr, int L, int R) {
	if (L == R)
		return 0;
	int mid = L + ((R - L) >> 1);
	
	return smallAdd(arr, L, mid)+ smallAdd(arr, mid + 1, R)+ merge(arr, L, R, mid);
}
int merge(vector<int>& arr, int L, int R, int M) {
	int i = 0;
	int p1 = L;
	int p2 = M + 1;
	int res=0;
	vector<int> arr1(R - L + 1); // 分配足够的内存空间
	while (p1 <= M && p2 <= R){
		res += arr[p1] <= arr[p2] ? (R - p2 + 1) * arr[p1] : 0;
		arr1[i++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++];
    }
	while (p1 <= M)
		arr1[i++] = arr[p1++];
	while (p2 <= R)
		arr1[i++] = arr[p2++];
	for (i = 0; i < arr1.size(); i++)
		arr[L + i] = arr1[i];
	return res;
}

3.逆序对问题

在一个数组中,左边的数如果比右边的数大,则折两个数构成一个逆序对,请打印所有逆序对,此案例没有给出解法,作者自己根据归并排序给出

#include<iostream>
#include<vector>
#include <algorithm>
using namespace std;


void merge_reverseOder(vector<int>& arr, int L, int R, int M);
void reverseOder(vector<int>& arr, int L, int R) {
	if (L == R)
		return ;
	int mid = L + ((R - L) >> 1);

	reverseOder(arr, L, mid);
	reverseOder(arr, mid + 1, R);
	merge_reverseOder(arr, L, R, mid);
}
void merge_reverseOder(vector<int>& arr, int L, int R, int M) {
	int i = 0;
	int p1 = L;
	int p2 = M + 1;
	int res = 0;
	vector<int> arr1(R - L + 1); // 分配足够的内存空间
	while (p1 <= M && p2 <= R) {
		if (arr[p1] > arr[p2] ? 1 : 0)
			for (int j = 0; j < (M - (p1)+1); j++)
				cout << "(" << arr[p1 + j] << "," << arr[p2] << ")" << endl;
		arr1[i++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++];
	}
	while (p1 <= M){
		arr1[i++] = arr[p1++];
		
	}
	while (p2 <= R)
		arr1[i++] = arr[p2++];
	for (i = 0; i < arr1.size(); i++)
		arr[L + i] = arr1[i];
	
}

对算法进行测试

#include"Swap_Print.h"
using namespace std;
#include"reverseOder.h"

int main() {


	vector<int> arr = { 3,2,4,5,0 };
	reverseOder(arr,  0, 4);
}

运行结果:

快速排序3.0

#include<iostream>
#include<vector>
using namespace std;
#include"Swap_Print.h"
vector<int> partition(vector<int>& arr, int L, int R);

void  quickSort(vector<int>&arr,int L,int R) {

	if (L < R)
	{
		/*
		srand(time(0));
		int random = rand();
		double randomDouble = double(random) / RAND_MAX;
		int randomPositon = L + ((int)randomDouble * (R - L + 1));
		cout << randomPositon;
		swap(arr[randomPositon],arr[R]);
		*/
		vector<int>arr1=partition(arr, L, R);
		
		quickSort(arr, L, arr1[0]);
		
		quickSort(arr, arr1[1],R);
		
	}

}

vector<int> partition(vector<int>& arr, int L, int R)
{
	int rightBoundary = R;
	int leftBoundary = L-1;
	int compare = arr[R];
	while (L < rightBoundary)
	{

		if (arr[L] < arr[R])
			swap(arr[L++], arr[++leftBoundary]);


		else if (arr[L] > arr[R]) 
			swap(arr[L], arr[--rightBoundary]);

		else if (arr[L] == arr[R]) 
			L++; 

	}
	swap(arr[R], arr[rightBoundary]);
	vector<int> arr1 = { leftBoundary ,rightBoundary+1 };
	return arr1;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值