(2)非数值计算常用经典算法

1、交换(两量交换借助第三者) 不借助第三个变量

参考:
http://blog.csdn.net/hackbuteer1/article/details/6531775

2、累加

累加算法的要领是形如“s=s+A”的累加式,此式必须出现在循环中才能被反复执行,从而实现累加功能。“A”通常是有规律变化的表达式,s在进入循环前必须获得合适的初值,通常为0。
例如:求1+2+3+……+100的和。
sum=0;i=1;
sum=sum+i;
i++;

3、累乘

累乘算法的要领是形如“s=s*A”的累乘式,此式必须出现在循环中才能被反复执行,从而实现累乘功能。“A”通常是有规律变化的表达式,s在进入循环前必须获得合适的初值,通常为1。
例如:求10!
n=10;sum=1;
n>0
sum=sum*n;
n--;


非数值计算常用经典算法

1、穷举**

也称为“枚举法”,即将可能出现的每一种情况一一测试,判断是否满足条件,一般采用循环来实现。
例如:用穷举法输出所有的水仙花数(即这样的三位正整数:其每位数位上的数字的立方和与该数相等,比如:13+53+33=153)。

#include <stdio.h>
int main()
{
    int a,b,c,i;
    for(i=100;i<1000;i++){
        a=i/100;
        b=(i/10)%10;
        c=i%10;
        if(i==a*a*a+b*b*b+c*c*c)
            printf("%d\n",i);
    }
}
2.排序

参考:
http://www.cnblogs.com/fanyong/archive/2012/03/23/2413559.html
http://www.cnblogs.com/kkun/archive/2011/11/23/2260312.html

冒泡排序

假设要对含有n个数的序列进行升序排列,冒泡排序算法步骤是:
1、从存放序列的数组中的第一个元素开始到最后一个元素,依次对相邻两数进行比较,若前者大后者小,则交换两数的位置;
2、第一趟结束后,最大数就存放到数组的最后一个元素里了,然后从第一个元素开始到倒数第二个元素,依次对相邻两数进行比较,若前者大后者小,则交换两数的位置;
3、重复步骤1 n-1趟,每趟比前一趟少比较一次,即可完成所求。

#include <stdio.h>
#define GET_ARRAY_LEN(array,len) {len = (sizeof(array) / sizeof(array[0]));}
int main()
{
    int i,j,len=0;
    int a[5]={1,5,3,2,4};
    
    GET_ARRAY_LEN(a,len);
    printf("%d\n",len);
    
    for(i=0;i<len-1;i++){
        for(j=0;j<len-i-1;j++){
            if(a[j]>a[j+1]){
                int temp=a[j];
                a[j]=a[j+1];
                a[j+1]=temp;
            }
        }
    }
    for(i=0;i<len;i++){
        printf("%d\n",a[i]);
    }
}

(2)选择法排序

选择法排序是相对好理解的排序算法。假设要对含有n个数的序列进行升序排列,算法步骤是:
1、从数组存放的n个数中找出最小数的下标(算法见下面的“求最值”),然后将最小数与第1个数交换位置;
2、除第1个数以外,再从其余n-1个数中找出最小数(即n个数中的次小数)的下标,将此数与第2个数交换位置;
3、重复步骤1 n-1趟,即可完成所求。

#include <stdio.h>
#define GET_ARRAY_LEN(array,len) {len = (sizeof(array) / sizeof(array[0]));}
int main()
{
    int a[5]={5,2,1,4,3};
    int i,j,min,temp;
    for(i=0;i<5-1;i++){
        min=i;
        //查找最小值 
        for(j=i+1;j<5;j++)
            if(a[min]>a[j])
                min=j;
        //交换 
        if(min!=i){
            temp =a[min];
            a[min]=a[i];
            a[i]=temp;
        }
    }
    for(i=0;i<5;i++){
        printf("%d\n",a[i]);
    }
}

(3)插入法排序

要想很好地掌握此算法,先请了解“有序序列的插入算法”,就是将某数据插入到一个有序序列后,该序列仍然有序。插入法排序的要领就是每读入一个数立即插入到最终存放的数组中,每次插入都使得该数组有序。
参考:
http://www.cnblogs.com/fanyong/archive/2012/03/23/2413553.html

#include <stdio.h>
#define GET_ARRAY_LEN(array,len) {len = (sizeof(array) / sizeof(array[0]));}
int main()
{
    int a[5]={5,2,1,4,3};
    int i,j,temp;
    //假定第一个元素被放到了正确的位置 
    for(i=1;i<5;i++){
        j=i;
        temp=a[i];
        while(j>0&&temp<a[j-1]){
            a[j]=a[j-1];
            j--;
        } 
        a[j]=temp;
    }
    for(i=0;i<5;i++){
        printf("%d\n",a[i]);
    }
}

**(4)归并排序 **

即将两个都升序(或降序)排列的数据序列合并成一个仍按原序排列的序列。
例如:有一个含有6个数据的升序序列和一个含有4个数据的升序序列,将二者合并成一个含有10个数据的升序序列。

参考: http://blog.csdn.net/cwj649956781/article/details/7409635

#include <stdlib.h>
#include <stdio.h>   
typedef int RecType;//要排序元素类型  
void Merge(RecType *R,int low,int m,int high)  
{  
    //将两个有序的子文件R[low..m)和R[m+1..high]归并成一个有序的子文件R[low..high]  
    int i=low,j=m+1,p=0;                //置初始值  
    RecType *R1;                        //R1是局部向量  
    R1=(RecType *)malloc((high-low+1)*sizeof(RecType));  
    if(!R1)  
    {  
        return;                         //申请空间失败  
    }  
  
    while(i<=m&&j<=high)                //两子文件非空时取其小者输出到R1[p]上  
    {  
        R1[p++]=(R[i]<=R[j])?R[i++]:R[j++];  
    }  
  
    while(i<=m)                         //若第1个子文件非空,则复制剩余记录到R1中  
    {  
        R1[p++]=R[i++];  
    }  
    while(j<=high)                      //若第2个子文件非空,则复制剩余记录到R1中  
    {  
        R1[p++]=R[j++];  
    }  
  
    for(p=0,i=low;i<=high;p++,i++)  
    {  
        R[i]=R1[p];                     //归并完成后将结果复制回R[low..high]  
    }  
}  
  
void MergeSort(RecType R[],int low,int high)  
{     
    //用分治法对R[low..high]进行二路归并排序  
    int mid;  
    if(low<high)  
    {   //区间长度大于1   
        mid=(low+high)/2;               //分解  
        MergeSort(R,low,mid);           //递归地对R[low..mid]排序  
        MergeSort(R,mid+1,high);        //递归地对R[mid+1..high]排序  
        Merge(R,low,mid,high);          //组合,将两个有序区归并为一个有序区  
    }  
}  
void main()  
{  
    int a[7]={49,38,65,97,76,13,27}; //这里对8个元素进行排序  
    int low=0,high=6,i;                   //初始化low和high的值  
  
    printf("Before merge sort: ");  
    for(i=low;i<=high;i++)  
    {  
        printf("%d ",a[i]);             //输出测试  
    }  
    printf("\n");  
  
    MergeSort(a,low,high);  
  
    printf("After merge sort:  ");  
    for( i=low;i<=high;i++)  
    {  
        printf("%d ",a[i]);             //输出测试  
    }  
    printf("\n");  
}   
3.查找

(1)顺序查找(即线性查找)

顺序查找的思路是:将待查找的量与数组中的每一个元素进行比较,若有一个元素与之相等则找到;若没有一个元素与之相等则找不到。
例如:任意读入10个数存放到数组a中,然后读入待查找数值,存放到x中,判断a中有无与x等值的数。

#include <stdio.h>
#define MAX 10
int main(){
    int a[MAX];
    int x,i;
    for(i=0;i<MAX;i++){
        scanf("%d",&a[i]);
    }
    printf("\n");
    for(i=0;i<MAX;i++){
        printf("%d",a[i]);
    }
    printf("\n");
    scanf("%d",&x);
    for(i=0;i<MAX;i++){
        if(x==a[i])
            printf("%d ",i);
    }   
    return 0;
}

(2)折半查找(即二分法)

顺序查找的效率较低,当数据很多时,用二分法查找可以提高效率。使用二分法查找的前提是数列必须有序。
二分法查找的思路是:要查找的关键值同数组的中间一个元素比较,若相同则查找成功,结束;否则判别关键值落在数组的哪半部分,就在这半部分中按上述方法继续比较,直到找到或数组中没有这样的元素值为止。
例如:任意读入一个整数x,在升序数组a中查找是否有与x等值的元素。
参考:http://blog.csdn.net/shuilan0066/article/details/7608096

//递归折半 
#include <stdio.h> 
int binary_search(int search_table[],int low,int high,int key)  
{  
  
    if (low>high)  
        return -1;  
  
    int mid=(low+high)/2;  
  
    if (search_table[mid]==key)  
        return mid;  
  
    if (search_table[mid]>key)  
        return binary_search(search_table,low,mid-1,key);  
    else  
        return binary_search(search_table,mid+1,high,key);  
}

int main(){
    int a[10]={0,1,2,3,4,5,6,7,8,9};
    int x,i,y;
    scanf("%d",&x);
    if((y=binary_search(a,0,9,x))>=0)
        printf("%d是第%d个数",x,y+1);
    else
        printf("未找到%d\n",x); 
    return 0;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335

推荐阅读更多精彩内容

  • 概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部...
    蚁前阅读 5,149评论 0 52
  • 概述:排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部...
    每天刷两次牙阅读 3,723评论 0 15
  • Ba la la la ~ 读者朋友们,你们好啊,又到了冷锋时间,话不多说,发车! 1.冒泡排序(Bub...
    王饱饱阅读 1,779评论 0 7
  • 每周三,我都会从同一个地方回学校。错过了末班车,却遇上来自社会各类的人,他们都有一个共同的职业,都是滴滴司机。 我...
    LIANG贪杯者阅读 339评论 0 0
  • 1、安装cnpm 2安装webpack 3、安装vue脚手架 4、安装项目依赖 一定要从官方仓库安装,npm 服 ...
    疯狂的冰块阅读 185评论 0 1