分析一下这个算法的优缺点#include<cstdio> #include<cstring> #include<iostream> using namespace std; //1、逆序对:对于给定的一段正整数序列,逆序对就是序列中 ai > aj 且 i < j 的有序对。 //算出给定的一段正整数序列中逆序对的数目。注意序列中可能有重复数字。 int n;//正整数的个数 const int LENGTH = 5e5 + 100; int arr1[LENGTH];//输入的原始正整数序列 int temp[LENGTH];//暂存排序完毕的数 long long cnt = 0; void mergeSort(int a, int b) {//左区间下标一定大于右区间下标,排序不影响比较大小 if (a == b) return; int mid = (a + b) / 2; int i = a, k = a, j = mid + 1; mergeSort(a, mid);//将数组平分为左右两个区间,利用递归、分治的思想将数组分为同规模的更小的问题 mergeSort(j, b); while (i <= mid && j <= b) { //从各区间第一位开始,将左右区间的数进行比较,较小的数存入temp数组 if (arr1[i] <= arr1[j]) { temp[k++] = arr1[i++]; } else { temp[k++] = arr1[j++]; cnt += mid - i + 1;//此时第i位数至第mid位数有序,因此第i位之后的数也大于当前第j位数 } } while (i <= mid) {//当右区间的数都已被比较过,第i位数已经找不到能够进行比较的数,此时只需要把左区间剩下的数存入temp数组中即可 temp[k++] = arr1[i++]; } while (j <= b) {//此处与上面的while循环同理 temp[k++] = arr1[j++]; } for (int k = a; k <= b; ++k) {//最后将排列好的有序数组重新存入m数组中 arr1[k] = temp[k]; } } int main() { cout << "请输入一个正整数序列的个数:" << endl; cin >> n; cout << endl; cout << "请输入该正整数序列,每个整数之间以空格隔开:" << endl; for (int i = 1; i <= n; ++i) { cin >> arr1[i]; } cout << endl; mergeSort(1, n); cout << "该输入的正整数序列中,逆序对的数目为 " << cnt << " 个。" << endl; return 0; }
时间: 2023-12-06 14:41:19 浏览: 86
这个算法实现的是归并排序,同时利用归并排序的过程求解逆序对的个数。具体来说,归并排序是将一个未排序的数组不断地分成两半,然后对两半分别进行排序,最后将两个已排序的数组归并成一个有序数组。而在归并的过程中,统计逆序对的个数也可以同时完成。具体来说,当左半边的数arr1[i]大于右半边的数arr1[j]时,因为左半边的数都已经排好序,所以左半边的i到mid这些数都大于arr1[j],所以可以统计逆序对的个数为mid - i + 1。
优点:
1. 时间复杂度为O(nlogn),相对于冒泡排序、插入排序等O(n^2)的排序算法更加高效;
2. 空间复杂度为O(n),与快速排序相比,归并排序需要额外的空间存储临时数组,但是空间复杂度是可以接受的。
缺点:
1. 归并排序需要额外的空间存储临时数组,这会占用一定的内存空间;
2. 归并排序在实现上比较复杂,需要考虑分治递归、归并等操作,代码难度较高;
3. 归并排序不适合对小规模数据进行排序,因为归并排序需要不断地将数组分成两半,而对于小规模数据,这种操作会增加额外的开销。
相关问题
#include <iostream> #include <fstream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <climits> #include <string> #include <algorithm> #include <vector> #include <map> using namespace std; struct Value { char str[10000]; }; void structSort(Value *a, int n) { @你的代码 } int n; Value a[5000]; int main() { scanf("%d", &n); for (int i = 0; i<n; i++) { scanf("%s", a[i].str); } structSort(a, n); for (int i = 0; i<n; i++) { printf("%s\n", a[i].str); } return 0; }
这段代码给出了一个结构体数组 `a`,其中每个结构体包含一个字符串成员 `str`。接下来有一个函数 `structSort`,它需要你来实现。你需要使用任何一种排序算法对 `a` 数组进行排序,排序的依据是字符串的字典序(即按照字母顺序进行比较)。最后将排序后的字符串数组依次输出即可。
以下是可能的 `structSort` 实现方式之一,使用了标准库中的 `qsort` 函数:
```c++
int compare(const void *a, const void *b) {
return strcmp(((Value *)a)->str, ((Value *)b)->str);
}
void structSort(Value *a, int n) {
qsort(a, n, sizeof(Value), compare);
}
```
其中,`compare` 函数用于比较两个字符串的大小,将其作为参数传递给 `qsort` 函数进行排序。
求一个点到另外一个点的最小距离 #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<algorithm> #include<vector> #include<cstring> #include<cstdio> #include<cmath> #include<cstdlib> #include<sstream> #include<string> #include<map> using namespace std; typedef long long ll; int dx[4] = { 0, 0, 1, -1 }; int dy[4] = { 1, -1, 0, 0 }; #define fo(i,l,r) for (int i = l; i <= r; ++i) #define F 10005 int n, m, s, t,x,y,ww; ll D[F],w[F][F],vis[F]; int main() { cin >> n >> m >> s >> t; fo(i, 1, n) fo(j, 1, n) { if (i != j) w[i][j] = 0x3f3f3f3f3f; } fo(i, 0, n)//注意0的初始化 D[i] = 0x3f3f3f3f3f; D[s] = 0;//从源点到i的距离 fo(i, 1, m) { scanf("%d%d%d", &x, &y, &ww); w[x][y] = ww; w[y][x] = ww; } //dijkstra算法 int k = 0; fo(i, 1, n) { k = 0; fo(j, 1, n) if (!vis[j] && D[j] < D[k])//一开始找源点 k = j; vis[k] = 1; fo(j, 1, n) if (!vis[j]&&D[k] + w[k][j] < D[j]) { D[j] = D[k] + w[k][j]; } } cout << D[t] << endl; return 0; }不用任何容器来实现这个代码
以下是不使用任何容器实现求一个点到另外一个点的最小距离的代码:
```
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<sstream>
#include<string>
#include<map>
using namespace std;
typedef long long ll;
const int F = 10005;
int dx[4] = { 0, 0, 1, -1 };
int dy[4] = { 1, -1, 0, 0 };
int n, m, s, t, x, y, ww;
ll D[F], w[F][F], vis[F];
int main()
{
scanf("%d%d%d%d", &n, &m, &s, &t);
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= n; ++j)
{
if (i != j)
{
w[i][j] = 0x3f3f3f3f3f;
}
}
}
for (int i = 0; i <= n; ++i)
{
D[i] = 0x3f3f3f3f3f;
}
D[s] = 0;
for (int i = 1; i <= m; ++i)
{
scanf("%d%d%d", &x, &y, &ww);
w[x][y] = ww;
w[y][x] = ww;
}
// dijkstra算法
int k = 0;
for (int i = 1; i <= n; ++i)
{
k = 0;
for (int j = 1; j <= n; ++j)
{
if (!vis[j] && D[j] < D[k])
{
k = j;
}
}
vis[k] = 1;
for (int j = 1; j <= n; ++j)
{
if (!vis[j] && D[k] + w[k][j] < D[j])
{
D[j] = D[k] + w[k][j];
}
}
}
printf("%lld\n", D[t]);
return 0;
}
```
这个代码中没有使用任何STL容器,而是使用了基本数据类型和数组来存储和操作数据。
阅读全文