常用的算法思想(C版)

1.穷举法思想,在可能的解空间种穷举每一种可能的解,并对每种可能的解进行判断,从中得到问题的答案.
优缺点:用时间上的牺牲换来了解的全面性保证。
eg:寻找指定区间的素数
#include <stdio.h>

/* n 是素数返回1 否则返回0 */
int isPrime(int n){
    int i;
    for(i=2; i<n;i++){
        if(n%i==0) return 0;
    }
    return 1;
}

void printPrime(int low,int high){
    int i = 0;
    for(i = low; i<=high; i++){
        if(isPrime(i)){
            printf("%d ",i);    
        }
    }
}

int main(void){
    int low,high;
    printf("please input the domain prime:\n");
    printf("low:");
    scanf("%d",&low);
    printf("hight:");
    scanf("%d",&high);
    printf("The whole primes:\n");
    printPrime(low,high);
    return 0;
}

2.递归与分治思想
递归:直接或者间接的调用原算法本身的一种算法。
设计递归注意点:
(1) 每个递归函数必须有一个非递归定义的初始值,作为递归结束标志。
(2) 设计递归算法的时候,要解决的问题必需具有递归性。
(3) 递归算法运行效率低,时间和空间复杂度比较高,因此设计到对于一些对时间和空间要求比较高的程序,建议使用非递归算法
分治思想:解决一些规模较大的问题时,常常将问题进行分解成规模较小的同类问题,然后将小问题逐个解决,最终也就将整个大问题解决。比如折半查找。

3.贪心算法思想
所谓的贪心算法,总是在做出当前看来是最好的选择的一种方法,比如有三种硬币,面值分别为1元,5角,1角,如果给客户找2元7角,请问怎么找才能使硬币数目最少。
方案:首先找一个面值不超过2元7角的最大硬币,即1元硬币。
     然后从2元7角种减去1元,得到1元7角,再找一个面值不超过1元7角的最大硬币,即1元硬币,以此类推,
我们长用的哈夫曼编码算法,最小生成树算法,求解最短路径算法都属于贪心算法思想。
eg:最优装船问题
有一批集装箱要装入一个载质量为C的货船中,每个集装箱的质量由用户自己输入,在货船的体积不限的前提下,如何装载集装箱才能尽可能多的将集装箱装入货船中。

#include <stdio.h>
#include <stdlib.h>

void sort(int w[],int t[],int n){
	int i,j,temp;
	int *w_temp = (int *) malloc(sizeof(int) *n);//用于排序
	for(i = 0;i<n;i++){
		w_temp[i] = w[i];
	}
	for(i = 0; i<n;i++){
		t[i] = i;
	}
	for(i=0; i<n; i++){
		for(j=i+1;j<n;j++){
			if(w_temp[i]>w_temp[j]){
				temp = w_temp[j];
				w_temp[j] = w_temp[i];
				w_temp[i] = temp;
				//交换下标
				temp=t[i];
				t[i] = t[j];
				t[j] = temp;  		
			}
		}
	}
}


void loading(int x[],int w[],int c, int n){
	int i;
	int *t = (int *) malloc(sizeof(int) *n);//存放排序好的数组下标
	sort(w,t,n);
	for(i=0; i<n && w[t[i]]<=c;i++){
		//上船的box标识为1
		x[t[i]] = 1;
		//剩余质量
		c = c - w[t[i]];
	}
}
int main(void){
	int x[5];//存放下标,1表示已经上船
	int w[5];//存放box
	int c;//总质量
	int i;
	printf("Please input the max\n");
	scanf("%d",&c);
	printf("Please input the weight of five box\n");
	for(i = 0; i<5;i++){
		scanf("%d",&w[i]);
	}
	loading(x,w,c,5);
	for(i=0; i<5; i++){
		if(x[i]==1) {
			printf("BOX:%d ",i);
		}
	}
	return -1;
}


4.回溯法

处理规模较大的问题可以用回溯法。
基本思想:在包含问题的所有解的解空间树中,按照深度优先搜索的策略,从根结点出发深度探索解空间树。当搜索到某一个结点时,要先判断该结点是否包含问题的解,如果包含,从该结点继续探索,如果不包含,那就说明以该结点为根结点的字树一定不包含问题的最终解,因此要跳过对该结点为根的子树的探索,逐层向其祖先结点回溯。
eg:N皇后问题,求解如何在一个N * N 的棋盘上无冲突地摆放N个皇后棋子,在任意一个皇后所在位置的水平,竖直,以及45度斜线上都不能出现出现其它皇后的棋子。


5.概率算法
概率算法允许执行过程中随机的选择下一步的计算步骤,因此使用概率算法有时会大大提高算法的效率s





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值