算法练习(二分查找、快速求最大值最小值、最短同度子序列、最长上升子序列、限和最长子序列、数组循环右移、折半查找的实现、最大子列和问题淘汰竞赛)

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时,二者比大小,返回较大的那个3else{
    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;
}

}

三种情况

  1. i==j时直接输出a【i】

  2. 当i+1==j时比较大小输出

  3. else 递归

3、最短同度子序列

  • 定义数据结构

初始化,下标存储数值,初始化时全部=-1

数据结构

typedef struct {
    int first_index;
    int last_index;
    int count;
}ElementIofo;
  1. 初始化函数

  2. 计算每个元素出现的首尾下标,和次数

  3. 更新最大度

  4. 找到与原数组相同的最短子序列的长度

函数都在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;
}
  1. 第一个初始化的函数,for 里面时1000

  2. 第二个更新首尾下表和次数的,for里面时numSize

  • 结构体里面是nums里面的值

  • if里面是对first_index进行赋值

  • 更新最大度

  1. 找到最小子系列,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;
}
  1. 结构体:
  • 总分

  • 平均分

  • 组号

  • 总的组号

  1. 函数cmpave
  • 参数const voiid * p1,两个指针
  1. qsort函数(arr,n,sizeof(arr[0]),cmpave)
  • int ret =ceil(n1.0r)向上取整

cmpaves:大于0是1,小于0是-1

  1. 定义数组:

struct my_struct arr[n];定义一个数组,里面的数组元素是struct_mystruct

  1. 输入scanf("%lf")

  2. 淘汰人数的向上取整

ceil

  1. 这里要加两个括号

double ret =((struct my_struct*)p1)->ave-((struct my_struct)p2)->p2;

  1. 指针的运用
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

week_泽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值