7、12
1、二分查找:
Position BinarySearch( List L, ElementType X )
{
Position start=1;
Position end=L->Last;
Position mid;
do{
if(start>end){
return NotFound;
}
mid=(start+end)/2;
if(X==L->Data[mid]){
return mid;
}
else if(X>L->Data[mid]){
start=mid+1;
}
else {
end=mid-1;
}
}while(X!=L->Data[mid]);
}
2、快速求最大值和最小值(分治法)
1、跳出的条件,i>=j 返回a[i]
2、当i+1=j时,二者比大小,返回较大的那个3、
else{
num1=max(a,i,mid);
num2=max(a,mid,j);
return num1>num2?num1:num2;
代码:
int max(int a[],int i,int j) // 从主函数传来头和尾的地址 i, j
{
int mid,num1,num2; // mid 为这组数的中点下标.num1,num2分别来接受再两组数找到的最大值.将较大值的返回给上一层
mid=(i+j)/2; //这里(i+j)/2是找到了中点
if(i>=j) //判断当只有一个数时,就返回它本身,即本身为较大值
return a[i];
else if(i+1==j) //i+1==j,表示的就是首尾,即为这组数只有两个数的时候就能够直接比较判断哪个较大,返回较大的数
return a[i]>a[j]?a[i]:a[j];
else
{
num1= max(a,i,mid); //如果前两种情况都不满足就是表示有多个数.将从第一个数开始到中点数归为一组,找到最值
num2=max(a,mid,j); //这里的就是从中点数一直到最后一个数归为一组来找最值。
return num1>num2?num1:num2; //接下来就是返回最值。
}
}
int min(int a[],int i,int j) //找最小值同理找最大值
{
int mid,num1,num2;
mid=(i+j)/2;
if(i==j)
return a[i];
else if(i+1==j)
return a[i]<a[j]?a[i]:a[j];
else
{
num1= min(a,i,mid);
num2=min(a,mid,j);
return num1<num2?num1:num2;
}
}
int max(int *a,int i,int j){
int mid,num1,num2;
mid=(i+j)/2;
if(i>=j)
{
return a[i];
}
else if(i+1==j){
return a[i]>a[j]?a[i]:a[j];
}
else{
num1 = max(a,i,mid);
num2=max(a,mid,j);
return num1>num2?num1:num2;
}
}
int min(int *a,int i,int j){
int mid,num1,num2;
mid=(i+j)/2;
if(i>=j)
{
return a[i];
}
else if(i+1==j){
return a[i]<a[j]?a[i]:a[j];
}
else{
num1 = min(a,i,mid);
num2=min(a,mid,j);
return num1<num2?num1:num2;
}
}
三种情况:
-
i==j时直接输出a【i】
-
当i+1==j时比较大小输出
-
else 递归
3、最短同度子序列
- 定义数据结构:
初始化,下标存储数值,初始化时全部=-1
数据结构:
typedef struct {
int first_index;
int last_index;
int count;
}ElementIofo;
初始化函数
计算每个元素出现的首尾下标,和次数
更新最大度
找到与原数组相同的最短子序列的长度
函数都在for里面
代码:
typedef struct {
int first_index;
int last_index;
int count; // 用于记录元素出现的次数
} ElementInfo;
int fun(int *nums, int numsSize) {
ElementInfo elements[10000]; // 用于存储每个元素的信息
int max_degree = 0;
// 初始化元素信息数组
for (int i = 0; i < 10000; i++) {
elements[i].first_index = -1; // 初始设为-1表示未出现
elements[i].last_index = -1;
elements[i].count = 0;
}
// 计算每个元素的出现次数和首尾位置
for (int i = 0; i < numsSize; i++) {
int num = nums[i];
if (elements[num].first_index == -1) {
elements[num].first_index = i; // 记录第一次出现的位置
}
elements[num].last_index = i; // 更新最后出现的位置
elements[num].count++; // 增加出现次数
// 更新最大度
if (elements[num].count > max_degree) {
max_degree = elements[num].count; // 更新最大度
}
}
// 找到与原数组相同度的最短子序列的长度
int min_length = numsSize; // 初始化为数组长度,即最大可能值
for (int i = 0; i < 10000; i++) {
if (elements[i].count == max_degree) {
int length = elements[i].last_index - elements[i].first_index + 1;
if (length < min_length) {
min_length = length; // 更新最短子序列的长度
}
}
}
return min_length;
}
第一个初始化的函数,for 里面时1000
第二个更新首尾下表和次数的,for里面时numSize
结构体里面是nums里面的值
if里面是对first_index进行赋值
更新最大度
- 找到最小子系列,for里面是1000,有if判断相等
初始化minSize=numSzie
num=10000
4、最长上升子序列:
int findLengthOfLIS(vector<int>& nums) {
int n = nums.size();
if (n == 0) return 0;
vector<int> dp(n, 1); // dp[i] 表示以 nums[i] 结尾的最长上升子序列的长度
for (int i = 1; i < n; i++) {
for (int j = 0; j < i; j++) {
if (nums[j] < nums[i]) {
dp[i] = max(dp[i], dp[j] + 1);
}
}
}
int maxLength = 0;
for (int i = 0; i < n; i++) {
maxLength = max(maxLength, dp[i]);
}
return maxLength;
}
int main() {
int n;
cin >> n; // 输入数组的长度
vector<int> nums(n); // 定义一个长度为 n 的整数数组 nums
for (int i = 0; i < n; i++) {
cin >> nums[i]; // 输入数组的元素
}
int result = findLengthOfLIS(nums); // 调用函数计算最长上升子序列的长度
cout << result << endl; // 输出结果
return 0;
}
vector<int>dp(n,1)
5、限和最长子序列:
代码:
int fun(int* A, int N,int S){
int sum=0,maxl=0;
int j=0;
int len=0;
for(int i =0;i<N;i++){
sum+=A[i];
while(sum>S){
sum-=A[j++];
}
len=i-j+1;
if(len>maxl){
maxl=len;
}
}
return maxl;
}
6、数组循环右移
代码:
void ArrayShift( int a[], int n, int m ){
int *copy=(int*)malloc(sizeof(int)*n);
for(int i=0;i<n;i++){
int j=(i+m)%n;
copy[j]=a[i];
}
for(int i=0;i<n;i++){
a[i]=copy[i];
}
}
7、折半查找的实现
代码:
Search_Bin(SSTable ST, KeyType key){
int start=1;
int end=ST.length;
int mid;
do{
mid=(start+end)/2;
if(ST.elem[mid].key==key){
return mid;
}
else if(start>end){
return NOT_FOUND;
}
else if(ST.elem[mid].key>key){
end=mid-1;
}
else{
start=mid+1;
}
}while(1);
}
8、最大子列和问题
代码:
#include <stdio.h>
#include <stdlib.h>
#define N 100000
int main()
{
int i,n;
int a[N];
int sum=0;//当前总和
int Maxsum=0;//最大的总和
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&a[i]);
for(i=0;i<n;i++)
{
sum+=a[i];
if(sum>Maxsum)
Maxsum=sum;
else if(sum<0)
sum=0;
}
printf("%d\n",Maxsum);
return 0;
9、淘汰竞赛
qsort:函数
struct:结构体
什么时候用->
代码:
#include<stdio.h>
#include<math.h>
struct my_struct
{
int sum; // 总和
int num; // 数量
double ave; // 平均值
int count; // 计数
};
int cmpave(const void* p1,const void* p2)
{
//return ((struct my_struct*)p1)->ave-((struct my_struct*)p2)->ave;
double ret=((struct my_struct*)p1)->ave-((struct my_struct*)p2)->ave;
if(ret>0)
{
return 1;
}
else
{
return -1;
}
}
int main()
{
int n;
double r;
scanf("%d %lf", &n, &r); // 输入 n 和 r
getchar(); // 捕获并丢弃换行符 好像这里是不需要的
struct my_struct arr[n]; // 定义结构体数组,大小为 n
// 输入每个结构体的数据
for (int i = 0; i < n; i++)
{
arr[i].count = i + 1;
scanf("%d %d", &arr[i].sum, &arr[i].num);
arr[i].ave = arr[i].sum * 1.0 / arr[i].num; // 计算平均值
}
// 使用 qsort 对结构体数组 arr 按照平均值 ave 进行升序排序
qsort(arr, n, sizeof(arr[0]), cmpave);
// 计算需要输出的元素个数,使用 ceil 函数确保向上取整
int ret = ceil(n * 1.0 * r);
// 输出排序后的前 ret 个结构体元素的信息
for (int i = 0; i < ret; i++)
{
printf("%d %d %d %.2lf\n", arr[i].count, arr[i].sum, arr[i].num, arr[i].ave);
}
return 0;
}
- 结构体:
总分
平均分
组号
总的组号
- 函数cmpave
- 参数const voiid * p1,两个指针
- qsort函数(arr,n,sizeof(arr[0]),cmpave)
- int ret =ceil(n1.0r)向上取整
cmpaves:大于0是1,小于0是-1
- 定义数组:
struct my_struct arr[n];定义一个数组,里面的数组元素是struct_mystruct
-
输入
scanf("%lf")
-
淘汰人数的向上取整
ceil
- 这里要加两个括号:
double ret =((struct my_struct*)p1)->ave-((struct my_struct)p2)->p2;
- 指针的运用