普通
//优化版本一:设置flag及时停止比较
void Bubble(int arr[],int length)
{
int temp=0;
int flag=0;
//最少一趟 最多n-1趟
for(int i=0;i<length-1;i++)
{
//一趟开始
flag=0;
for(int j=0;j<length-1;j++)
{
if(arr[j]>arr[j+1])
{
temp=arr[j+1];
arr[j+1]=arr[j];
arr[j]=temp;
flag=1;
}
}
if(flag==0)
break;
}
}
改进版二:对数列有序区界定。每一轮理论上有界区+1(实际后面有界区可能远远大于理论上的,例如第一轮后面一半已有序)
我们可以在每一轮排序的最后,记录下最后一次元素交换的位置,那个位置也就是无序数列的边界,再往后就是有序区了。
void Bubble2(int arr[],int length)
{
int temp=0;
int flag=0;
int terminal = length-1;
//最少一趟 最多n-1趟
for(int i=0;i<length-1;i++)
{
//一趟开始 趟交换标志清零
flag=0;
//从下标0到下标terminal为无序区
for(int j=0;j<terminal;j++)
{
if(arr[j]>arr[j+1])
{
temp=arr[j+1];
arr[j+1]=arr[j];
arr[j]=temp; //temp执行交换终结任务,temp原有值不影响任务
temp = j; //temp执行记录右交换位置下标
flag=1; //趟交换标志为1
}
}
terminal = temp; //terminal记录最后交换位置,下标terminal之后为有序区
if(flag==0)
break; //一趟无交换则结束排序
}
}
递归:是函数直接或间接调用自身的一种方法。它通常可以把一个重复的大型问题转化为较小规模的问题来求解。
递归需要有结束条件,并且每次调用本身都使问题更接近于解。
递归包括:递推,将原问题分解为子问题,并使子问题变成已知解,也就是到达递归结束条件。
回归,从已知的条件(子问题的已知解)出发,不断求值回归,最终回到递推的开始处。
应用:斐波那契数列,定义:F(0)=1,F(1)=1, F(n)=F(n-1)+F(n-2)
int fib(int i)
{
if(i <= 1)
{
return 0;
}
return fib(i - 1) + fib(i - 2);
}
分而治之,就是把一个复杂的问题分成两个或更多个相互独立的子问题,之后再把子问题分成更小的子问题以此类推。
知道最后的子问题可以简单地直接求解,原问题的解即子问题解的合并。
(与分治法相同),将复杂的问题分解成若干子问题,先求解子问题,然后从子问题的解得到原问题的解。
(与分治法不同),经分解的子问题往往不是相互独立的,动态规划会将已解决的子问题的解保存下来,在需要子问题的解时可以直接获得,而不需要重复计算。
问题:
有N件物品和一个容量为V的背包,第i件物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使价值总和最大。
2.2 解题思路:用动态规划的思路,阶段就是“物品的件数”,状态就是“背包剩下的容量”,那么很显然f [ i , v ] 就设为从前 i 件物品中选择放入容量为 v 的背包最大的价值。那么状态转移方程为:
f[i][v]=max{
f[i-1][v] , f[i-1][v-w[i]]+val[i]
// f[i-1][v] 不放入第i件物品
// f[i-1][v-w[i]]+val[i] ,放入第i件物品
}
实例:
原文链接:https://blog.csdn.net/shanghairuoxiao/article/details/62426727
有编号分别为a,b,c,d,e的五件物品,它们的重量分别是2,2,6,5,4,它们的价值分别是6,3,5,4,6,
现在给你个承重为10的背包,如何让背包里装入的物品具有最大的价值总和?
这个方程可以如下解释:只考虑子问题“将前 i 个物品放入容量为 v 的背包中的最大价值”那么考虑如果不放入 i ,最大价值就和 i 无关,就是 f[ i - 1 ][ v ] , 如果放入第 i 个物品,价值就是 f[ i - 1][ v - w[i] ] + val[ i ],我们只需取最大值即可。
贪心算法核心思想:(每一步)总是选择当前状态下最优的策略,也就是说不易整体最优解为考虑,而是一个个局部最优解来接近整体最优解。
例如求图的源点最短路径和,则每一步都选取最短权值的边。
可想而知,这并不一定是最优解。
图片来自:https://blog.csdn.net/liushengxi_root/article/details/86676382
质数:大于1的自然数中,除了1和自身不再有其他因子
其他的自然数称为合数。
算法思想:合数能分解成a*b,假设a<=b;则a<=sqrt(n),所以求到sqrt(n)即可
for(int i=2;i<sqrt(n);i++)
if(n%i==0)
printf("是质数");
int i=0;
do
{
bin[i++]=n%2+'0';
n=n/2;
}while(n!=0)
bin[i]='\0';
reverse(bin);
void reverse(char s[])
{
int temp,i,j;
for(i=0,j=strlen(s);i<j;i++,j--)
{
temp=s[i];s[i]=s[j];s[j]=temp;
}
}
算法思想:tmp=原来数字都升一位+新个位数
void Print(int num)
{
int tmp = 0;
while (num != 0)
{
tmp = tmp * 10 + num % 10;
num /= 10;
}
printf("%d\n", tmp);
}