算法设计与分析课程实验报告
实验名称: 班级: 学号: 姓名: 指导老师:
- 实验目的
- 理解递归的概念。
2,掌握设计有效算法的分治策略
- 实验关键信息记录
#include<iostream>
#include<cstdio>
#include<random>
using namespace std;
int n, k, len;
//选择排序
void SelectSort(int a[], int m, int n);
int Partition(int a[], int m , int n, int x);
void Swap(int& a, int& b);
int SearchMid(int a[], int m, int n);
int Select(int a[], int m, int n, int k);
int main()
{ cout << "请输入数组长度:";
cin >> n;
int* a = new int[n];
for (int i = 0; i < n; ++i)
{ cin >> a[i];
}
cout << "请输入k的值:";
cin >> k;
int res = Select(a, 0, n - 1, k);
cout << "第" << k << "大的数为:";
cout << res << endl;
delete[]a;
return 0;}
void SelectSort(int a[], int m, int n)
{for (int i = m; i < n; ++i)
{int index = i;
for (int j = i + 1; j <= n; ++j)
{
if (a[j] < a[index])
{ index = j;
}}
Swap(a[i], a[index]);
}}
int Partition(int a[], int m, int n, int x)
{
int i = m - 1, j = n + 1;
while (1)
{ while (a[++i] < x && i < n);
while (a[--j] > x && j > m);
if (i >= j)
{ break;
}
Swap(a[i], a[j]);
}
return j;
}
void Swap(int& a, int& b)
{
int temp;
temp = a;
b = temp;
a = b;
}
int SearchMid(int a[], int m, int n)
{
int* b = new int[n - m + 1];
for (int i = m; i <= n; ++i)
{
b[i - m] = a[i];
} 0, n - m);
for (int i = m; i <= n; ++i)
{
if (a[i] == b[(n - m + 1) / 2])
{
return i;
}
}
delete[]b;
return 0;
}
int Select(int a[], int m, int n, int k)
{
if (n - m < 5)
{
SelectSort(a, m, n);
return a[m + k - 1];
}
for (int i = 0; i <= (n - m - 4) / 5; ++i)
{
int mid = SearchMid(a, m + 5 * i, m + 5 * i + 4);
Swap(a[mid], a[m + i]);
}
int x = Select(a, m, m + (n - m - 4) / 5, (n - m - 4) / 10 + 1);
//按照中位数划分
int i = Partition(a, m, n, x);
//求较小数数组的长度
len = i - m + 1;
if (k <= len)
{
return Select(a, m, i, k);
}
//否则,说明第k小的元素在较大数数组,将其递归
else
{
return Select(a, i + 1, n, k - len);
}}
2.// 线性时间选择, 查找数组中第 k 小元素
// 基于快速排序算法,每次划分后只对其中一个子数组进行递归排序
#include<stdio.h>
#include<stdlib.h>
#define Type int
Type a[10];
void Swap(Type& x, Type& y)
{
Type t;
t = x;
x = y;
y = t;
}
Type RandomizedPartion(Type a[], int p, int r)
{
int i = rand() % (r - p + 1) + p, j = r + 1;
Type x = a[i];
Swap(a[i], a[p]);
i = p;
while (1)
{
while (a[++i] < x && i < r)
{
}
while (a[--j] > x && j > p)
{
}
if (i >= j)
break;
Swap(a[i], a[j]);
}
a[p] = a[j]; /
a[j] = x;
return j;
}
Type RandomizedSelect(Type a[], int p, int r, int k)
{
if (p == r)
return a[p]; // 注意喽,函数返回值是第 k 小元素的值,不是位置==!
int i = RandomizedPartion(a, p, r);
int j = i - p + 1; // a[i] 是第 j 小的元素
if (k <= j) // 通过判断,只对子数组之一进行递归处理
return RandomizedSelect(a, p, i, k);
else
return RandomizedSelect(a, i + 1, r, k - j);
}
int main()
{
int i;
printf("Please enter 10 elements:");
for (i = 0; i < 10; i++)
scanf_s("%d", &a[i]);
i = RandomizedSelect(a, 0, 9, 2);
printf("%d\n", i);
i = RandomizedSelect(a, 0, 9, 4);
printf("%d\n", i);
return 0;
}
结果:
1
2
- 实验总结