数据结构+算法

Posted 悉宇馨

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构+算法相关的知识,希望对你有一定的参考价值。

1.编程的灵魂:数据结构+算法

程序=数据结构+算法+程序设计语言

2.递推算法

(1)顺推法:是指从已知条件出发,逐步推算出要解决问题的方法。例如:斐波拉契数列就可以通过顺推法不断递推算出新的数据。

(2)逆推法:是从已知结果出发,用迭代表达式逐步推算出问题开始的条件。

eg:兔子的繁殖过程(顺推法)

 

 1 #include  <stdio.h>
 2 #define NUM 13
 3 int main()
 4 {
 5    int  i;
 6    long fib[NUM]={1,1};
 7    for(i=2;i<NUM;i++)
 8   {
 9      fib[i]=fib[i-1]+fib[i-2];
10    }
11    for(i=0;i<NUM;i++)
12    {
13      printf("%d月兔子总数:%d\n",i,fib[i]);
14    }
15    getch();
16    return 0;
17 }

3.枚举(穷举)算法

 

本质:从所有候选答案中去搜索正确的解,使用该算法需要满足两个条件:(1)可预先确定候选答案的数量;(2)候选答案的范围在求解之前必须有一个确定的集合。

4.递归算法

一种直接或间接地调用自身的算法。

具体实现过程:通过函数或子过程来完成,在函数或子过程的内部,编写代码直接或间接地调用自己,即可完成递归操作。

eg:求阶乘

#include <stdio.h>
int fact(int n);
int main()
{
   int i;
   printf("请输入要求阶乘的一个整数:");
   scanf("%d",&i);
   printf("%d的阶乘结果为:%d\n",i,fact(i));
   getch();
   return 0;
}
int fact(int n)
{
   if(n<=1)
           return 1;
   else
           retrun n*fact(n-1);
}

 5.分治算法

算法思路:使用分治算法设计程序时,一般可按以下步骤进行:

(1)分解:将要求解的问题划分成若干规模较小的同类问题;

(2)求解:当子问题划分的足够小时,用较简单的方法解决;

(3)合并:按求解问题的要求,将子问题的解逐层合并,即可构成最终的解。

#include <stdio.h>
#define MAXN 64
int a[MAXN+1][MAXN+1]={0};
void gamecal(int k,int n)//处理编号k开始的n个选手的日程
{
   int i,j;
   if(n==2)
    {
        a[k][1]=k;//参赛选手编号
a[k][2]=k+1;//对阵选手编号
a[k+1][1]=k+1;//参赛选手编号
a[k+1][2]=k;//对阵选手编号 }else{
gamecal(k,n/2);
gamecal(k+n/2,n/2);
for(i=k;i<k+n/2;i++)//填充右上角
{
for(j=n/2+1;j<=n;j++)
{
a[i][j]=a[i+n/2][j-n/2];
}
}
for(i=k+n/2;i<k+n;i++)
{
for(j=n/2+1;j<=n;j++)
{
a[i][j]=a[i-n/2][j-n/2];
}
}
} }

int main()
{
int m,i,j;
printf("输入参赛选手人数:");
scanf("%d",&m);
j=2;
for(i=2;i<8;i++)
{
j=j*2;
if(j==m)break;
}
if(i>=8)

printf("参赛选手人数必须为2的整书次幂,且不超过64!\n");
getch();
return 0;

gamecal(1,m);
printf("\n编号 ");
for(i=2;i<=m;i++)
{
printf("%2d天",i-1);
}
printf("\n");
for(i=1;i<=m;i++)
{
for(j=1;j<=m;j++)

printf("%4d ",a[i][j]);

printf("\n");
}
getch();
return 0;
}

 6.贪婪算法

基本思路:从问题的某一个初始解出发逐步逼近给定的目标,以尽可能快地求得更好的解。当达到算法中的某一步不能再继续前进时,就停止算法,给出近似解。

由贪婪算法的特点和思路可看出,该算法存在以下问题:

(1)不能保证最后的解是最优的;(2)不能用来求最大或最小解问题;(3)只能求满足某些约束条件的可行解的范围。

eg:换零钱

 1 #include <stdio.h>
 2 #define MAXN 9
 3 int parvalue[MAXN]={10000,5000,1000,500,200,100,50,20,10};
 4 int num[MAXN]={0};
 5 int exchange(int n)
 6 {
 7    int i,j;
 8    for(i=0;i<MAXN;i++)
 9    {
10       if(n>parvalue[i]) //找到比n小的最大面额
11            break;
12    }
13    while(n>0 && i<MAXN)
14    {
15      if(n>=parvalue[i])
16       {
17          n-=parvalue[i];
18          num[i]++;
19       }else if(n<10 &&n>=5)
20       {
21         num[MAXN-1]++;
22         break;
23       }else i++;
24    }
25     return 0;
26 }
27 int main()
28 {
29    int i;
30    float m;
31    printf("请输入找零的金额: ");
32    scanf("%f",&m);
33    exchange((int)100*m);
34    printf("\n%.2f元零钱的组成: \n",m);
35    for(i=0;i<MAXN;i++)
36    {
37       if(num[i]>0)
38           printf("%6.2f:%d张",(float)parvalue[i]/100.0,num[i]);
39 
40    }
41    getch();
42    return 0;
43 }

7.模拟算法

算法思路:在程序设计语言中,可使用随机函数来模拟自然界中发生不可预测情况。C语言中使用srand()和rand()函数可生成随机数。

 1 #include <time.h>
 2 #include <stdio.h>
 3 int main()
 4 {
 5    int n,m,i=0;
 6    srand(time(NULL));
 7    n=rand()%100+1;
 8    do{
 9       printf("输入所猜数字:");
10       scanf("%d",&m);
11       i++;
12       if(m>n)
13           printf("错误!所猜数字太大了!\n");
14       else if(m<n)
15            printf("错误!所猜数字太小了!\n");
16     }while(m!=n);
17     printf("答对了!\n");
18     printf("共猜测了%d次.\n",i);
19     if(i<=5)
20        printf("你太聪明了,这么快就猜出了!");
21     else 
22          printf("还需改进方法,以便更快猜出来!");
23     getch();
24     return 0;
25 }

8.试探算法

算法思路:为了求得问题的解,先选择某一种可能情况进行试探,在试探过程中,一旦发现原来的选择的假设情况是错误的,就退回一步重新选择,继续向前试探,如此反复进行,直至得到解或证明无解。

eg:生成彩票号码组合

假设有一种彩票,每注由7个1~29的数字组成,且这7个数字不能相同,编写程序生成所有的号码组合。

 1 #include <stdio.h>
 2 int main()
 3 {
 4    int i[7],j;
 5    for(i[0]=1;i[0]<=29;i[0]++)
 6           for(i[1]=1;i[1]<=29;i[1]++)
 7            {
 8              if(i[1]==i[0])  continue;
 9               for(i[2]==1;i[2]<=29;i[2]++)
10                 {
11                   if(i[0]==i[2]  ||  i[1]==i[2])  continue;
12                    for(i[3]==1;i[3]<=29;i[3]++)
13                        {
14                           if(i[0]==i[3] || i[1]==i[3]  || i[2]==i[3]) 
15                             continue;
16                             for(i[4]==1;i[4]<=29;i[4]++)
17                                {
18                                   if(i[0]==i[4] || i[1]==i[4]  || i[2]==i[4] || i[3]==i[4])  continue;
19                                  for(i[5]=1;i[5]<=29;i[5]++)
20                                   {
21                                       if(i[0]==i[5] || i[1]==i[5]  || i[2]==i[5] || i[3]==i[5] || i[4]==i[5])  continue;
22                                       for(i[6]=1;i[6]<=29;i[6]++)
23                                        {
24                                         if(i[0]==i[6] || i[1]==i[6]  || i[2]==i[6] || i[3]==i[6] || i[4]==i[6] || i[5]==i[6])  continue;
25                                         for(j=0;j<7;j++)
26                                                 printf("%3d",i[j]);
27                                        printf("\n");
28                                        getch();
29                                        }
30                                    }
31                                }
32 
33                        }
34                 }
35            }
36 }

上面的程序不具有代表性和通用性, 采用递归的方法可以解决这个问题:

 1 #include <stdio.h>
 2 #define MAXN 7 //设置每一注彩票的位数
 3 #define NUM 29  //设置组成彩票的数字
 4 int num[NUM];
 5 int lottery[MAXN];
 6 void combine(int n, int m)
 7 {
 8    int i,j;
 9    for(i=n;i>=m;i--)
10     {
11        lottery[m-1]=num[i-1];//保存每一位数字
12        if(m>1)
13         {
14            combine(i-1,m-1);
15         }
16         else   //若m=1输出一注号码
17          {
18            for(j=MAXN-1;j>=0;j--)
19                 printf("%3d",lottery[j]);
20             getch();
21             printf("\n");
22          }
23     }
24 }
25 int main()
26 {
27   int i,j;
28   for(i=0;i<NUM;i++)
29  {
30    num[i]=i+1;
31  }
32   for(i=0;i<MAXN;i++)
33   {
34     lottery[i]=0;
35   }
36   combine(NUM,MAXN);
37   getch();
38   return 0;
39 }

 

以上是关于数据结构+算法的主要内容,如果未能解决你的问题,请参考以下文章

片段(Java) | 机试题+算法思路+考点+代码解析 2023

可以解密加密数据的片段吗?

如何标记从卷积神经网络的分割算法生成的图像片段?

从搜索文档中查找最小片段的算法?

C语言100个经典算法源码片段

一致性哈希算法PHP测试片段