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

作者: 笑笑学生 | 来源:发表于2016-08-21 20:49 被阅读207次

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;
}

相关文章

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

    1、交换(两量交换借助第三者) 不借助第三个变量 参考:http://blog.csdn.net/hackbut...

  • 五种C语言非数值计算的常用经典排序算法

    摘要: 排序是计算机的一种操作方法,其目的是将一组“无序”的记录序列调整为“有序”的记录序列,主要分为内部排序和外...

  • 第二章 数据查找与资源分配算法——数值查找算法

    2.1 数值查找算法 查找是指在大量的数据中寻找到特定的元素,它是数值计算中常用的运算逻辑。 2.1.1 二分搜索...

  • 项目中常见的工具及技巧

    项目中的一些操作技巧 1、数值计算和常规处理[#1] 2、日期的常用处理及操作[#2] 数值计算和常规处理 这里简...

  • Java工程师之Oracle技术-SQL入门(2)

    分组计算函数和GROUP BY字句 常用分组计算函数 SUM(列) 数值类型,计算和 AVG(列) 数值类型,计算...

  • Excle常用函数

    常用加减乘除用法公式 =数值1+数值2=数值1-数值2=数值1*数值2=数值1/数值2 常用函数及用法 sum 求...

  • 数据结构和算法-C语言1-绪论

    数据结构与算法-目录 前言 程序设计 = 数据结构 + 算法 什么是数据结构? 数据结构是一门研究非数值计算的程序...

  • 数据结构 绪论

    数据结构 + 算法 = 程序 1. 数据结构研究的内容 如何合理的组织数据,高效的处理数据,主要研究非数值计算问题...

  • 第六课

    今天要讲的是最重要的是成本计算部分,分享三个常用的成本计算方法:(1)分步成本计算法(2)标准成本计算法(3)分批...

  • 概述

    数据结构考虑的要点 算法与模型 数据结构定义 描述现实世界实体的数学模型(非数值计算)及其上的操作在计算机中的表示...

网友评论

    本文标题:(2)非数值计算常用经典算法

    本文链接:https://www.haomeiwen.com/subject/yieisttx.html