一、基本概念
1.1什么是数据结构
1.1.1空间使用、算法效率
ONE : PrintN函数从1打印到N
/*
PrintN函数从1打印到N
输入1,100,1000两个程序都可以正常运行,但是到10000000时算法2不能正常运行
这是因为递归调用占用的空间太大
*/
#include <stdio.h>
#include <stdlib.h>
/*算法1for循环*/
PrintN_1(int N)
{
for(int i=1;i<=N;i++)
{
printf("%d ",i);
}
}
/*算法2递归调用*/
PrintN_2(int N)
{
if(N)//判断N是否为正整数
{
PrintN_2(N-1);
printf("%d ",N);
}
}
int main()
{
int N;
int t=1;
while(t)
{
printf("请输入数字N(输入0表示结束)");
scanf("%d",&N);
PrintN_1(N);
printf("\n");
PrintN_2(N);
printf("\n");
if(N==0) t=0;
}
return 0;
}
TWO : 计算函数运行时间
/*计算函数运行时间
函数时间过短可以重复函数再除以次数进行计算
*/
#include <stdio.h>
#include <math.h>
clock_t start,stop;//记录开始和结束时间
double duration;//stop-strat两者相减得出持续时间
int main()
{
int n;
strat=clock();
for(int i=1;i<=n;i++)//重复函数次数
{
myfunction();//测试函数
}
stop=clock();
duration=(double)(stop-start)/(n*CLK_TCK);
return 0;
}
THREE : 计算多项式在点x处的值
/*
计算多项式在点x处的值
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h> //pow(x,y)
#include <time.h> //clock_t
/*
算法1 直接带入
*/
Calculate_1(int n,double a[],double x)
{
double sum=a[0];
for(int i=1;i<n;i++)
{
sum=sum+a[i]*pow(x,i);
}
return sum;
}
/*
算法2 秦九韶算法(利用提公共因子的方法)
*/
Calculate_2(int n,double a[],double x)
{
double sum=a[n];
for(int i=1;i<n;i++)
{
sum=sum*x+a[i-1];
}
return sum;
}
clock_t start,stop;
double duration;
#define MAX 1e7
int main()
{
double a[10];
int x=2.1;
for(int i=1;i<=MAX;i++)
{
a[i-1]=i*1.0;
}
start=clock();
for(int i=1;i<=MAX;i++)
{
Calculate_1(10,a,x); //注意第二个参数传入的是a的地址
}
stop=clock();
duration=(double)(stop-start)/(CLK_TCK*MAX);
printf("one : %6.2e\n",duration);
start=clock();
for(int i=1;i<=MAX;i++)
{
Calculate_2(10,a,x); //注意第二个参数传入的是a的地址
}
stop=clock();
duration=(double)(stop-start)/(CLK_TCK*MAX);
printf("two : %6.2e\n",duration);
}
1.1.2抽象数据类型
1、什么是数据类型?什么是抽象?
数据类型:数据对象集
数据相关联的操作集
在例4中:将GetEntry(Matrix A,int i,int j);的返回值设定ElementType,既不是int 也不是double,
这是因为如果单单是一个数据类型的话,当数据变成int或者double时还需要重新写程序,
所以我们将其抽像成ElementType,需要其是什么数据类型,只需将其在开头#define一下即可
//for example
/*
计算最大子列和问题
*/
#include <stdio.h>
#include <stdlib.h>
#define ElementType int
/*
算法1 三重循环,规定头尾直接计算
将其数据类型抽象,
*/
ElementType MaxSum_1(ElementType A[],int N)
{
ElementType ThisSum,MaxSum=0;
for(int i=0;i<N;i++)
{
for(int j=i;j<N;j++)
{
ThisSum=0;
for(int k=0;k<N;k++)
{
ThisSum=ThisSum+A[k];
}
if(ThisSum>MaxSum) MaxSum=ThisSum;
}
}
return MaxSum;
}
/*
算法2:将算法简化最后一步
*/
ElementType MaxSum_2(ElementType A[],int N)
{
int ThisSum,MaxSum=0;
for(int i=0;i<N;i++)
{
ThisSum=0;
for(int j=0;j<N;j++)
{
ThisSum=ThisSum+A[j];
if(ThisSum>MaxSum) MaxSum=ThisSum;
}
}
return MaxSum;
}
/*Max
算法3:分而治之
二分法,分成两端,分别计算,然后还有一个跨两端的
*/
ElementType MaxSum_3(ElementType A[],int N)
{
ElementType ThisSum,MaxSum1=0,MaxSum2=0,MaxSum3=0,MaxSum=0;
MaxSum1 = MaxSum_2(A,N/2);
MaxSum2 = MaxSum_2(A+N/2,N/2);
for(int i=0;i<N/2;i++)
{
MaxSum3=MaxSum3+A[i];
}
ThisSum=MaxSum3;
for(int i=N/2;i<N;i++)
{
ThisSum=ThisSum+A[i];
if(ThisSum>MaxSum) MaxSum3=ThisSum;
}
if(MaxSum1>MaxSum2) MaxSum=MaxSum1;
else MaxSum=MaxSum2;
if(MaxSum<MaxSum3) MaxSum=MaxSum3;
return MaxSum;
}
int main()
{
int A[]={1,2,3,4,5,6};
int t=MaxSum_1(A,6);
printf("%d\n",t);
t=MaxSum_2(A,6);
printf("%d\n",t);
t=MaxSum_3(A,6);
printf("%d\n",t);
return 0;
}