您的当前位置:首页正文

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

来源:图艺博知识网

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

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.排序

冒泡排序

假设要对含有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)插入法排序

#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个数据的升序序列。

#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)折半查找(即二分法)

//递归折半 
#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;
}
Top