Data Structure1

数据结构第一天
到底什么是数据结构?
答:数据对象必须与一系列加在其上的操作相关联
完成这些操作所用的方法就是算法
除此之外呢,还有就是逻辑结构和计算机内部的物理存储结构(数组or链表)
抽象数据类型
数据类型:数据对象集合,数据集合相关联的操作集(C语言中独立处理,java和C++是封装在一个类中的)
抽象:描述数据类型的方法不具体实现,1.与存放数据的机器无关 2.与数据存储的物理结构无关 3.与实现操作的算法和编程语言均无关,只需要知道它是什么,而不具体去实现 ,比如矩阵的抽象数据类型定义。
eg1:写程序实现一个函数printN,使得传入一个正整数为N的参数后,能顺序打印从1到N的全部整数。

//一般实现
int  printN(int N){
int  i;
for(i=1;i<N;i++){
printf("%d\n",N);
    }
    return ;
}
//递归实现
int printN(int N){
if(N){
printf(N-1)printf("%d\n",N);
}
return ;
}
//测试
#include<stdio.h>
void printN(int N);
int main(){
int N;
scanf("%d",&N);
printfN(N);
return 0;
}

eg2:写程序计算给定多项式在定点x处的值f(x)=a0+a1x+…+an-1Xn-1+an*Xn;

//数学思维 从外到内
int printN(int n,double a[],double x){
int i;
double p=a[0];
for(i=0;i<n;i++){
p+=(a[i]*pow(x,i));
return p;
	}
}
//秦九韶算法 从内到外
int printN(int n,double a[],double x){
int i;
double p=a[N];
for(i=N;i>0;i--){
p+=a[i-1]+x*p;
return p;
	}
}

测试两个函数的程序运行时间

#include<stdio.h>
#include<time.h>
#include<math.h>
#define MAXN 10000
clock_t start,stop;
clock_t start1,stop1;
double duration,duration1;
double printN1(int n,double a[],double x);
double printN2(int n,double a[],double x);
int main(){
int i;
double a[MAXN];
printN1(MAXN-1,a,1.1);
start=clock();
printN1(MAXN-1,a,1.1);
stop=clock();
start1=clock();
printN2(MAXN-1,a,1.1);
stop1=clock();
duration=(double)(stop-start)/CLK_TCK;
duration1=(double)(stop1-start1)/CLK_TCK;
printf("%lf\n%lf",duration,duration1);
	return 0;
}
double printN1(int n,double a[],double x){
int i;
double p=a[0];
for(i=0;i<n;i++){
p+=(a[i]*pow(x,i));
return p;
	}
}
double printN2(int n,double a[],double x){
int i;
double p=a[n];
for(i=n;i>0;i--){
p+=a[i-1]+x*p;
return p;
	}
}

给定N个整数的序列{A1,A2,…An},求最大子列和(算法)

int MaxSubseqSum1( int A[], int N )  
{   int ThisSum, MaxSum = 0;
    int i, j, k;
    for( i = 0; i < N; i++ ) { /* i是子列左端位置 */
          for( j = i; j < N; j++ ) { /* j是子列右端位置 */
                  ThisSum = 0;  /* ThisSum是从A[i]到A[j]的子列和 */
                  for( k = i; k <= j; k++ )
                            ThisSum += A[k];
                            if( ThisSum > MaxSum ) /* 如果刚得到的这个子列和更大 */
                                      MaxSum = ThisSum;    /* 则更新结果 */
          } /* j循环结束 */
     } /* i循环结束 */
     return MaxSum;  
}

减少时间复杂度后的算法(O(n3)—>O(n2))

int MaxSubseqSum2( int A[], int N )  
{   int ThisSum, MaxSum = 0;
    int i, j;
    for( i = 0; i < N; i++ ) { /* i是子列左端位置 */
          ThisSum = 0;  /* ThisSum是从A[i]到A[j]的子列和 */
          for( j = i; j < N; j++ ) { /* j是子列右端位置 */
                  ThisSum += A[j];        /*对于相同的i,不同的j,只要在j-1次循环的基础上累加1项即可*/ 
                  if( ThisSum > MaxSum ) /* 如果刚得到的这个子列和更大 */
                            MaxSum = ThisSum;    /* 则更新结果 */
          } /* j循环结束 */    
     } /* i循环结束 */    
     return MaxSum;  
}

给定N个整数的序列{A1,A2,…An},求最大子列和(分而治之)
在这里插入图片描述


#include<stdio.h>
 int Max3(int A,int B,int C)//求三个数中的最大值 
 {
 	return A>B?A>C?A:C:B>C?B:C; 
 }
 int DivideAndConquer(int List[],int left,int right)//分治策略 
 {
 	int MaxLeft,MaxRight;
 	int MaxLeftSum,MaxRightSum;
 	int LeftSum,RightSum;
 	int center,i;
 	  
 	if(left==right)//递归的终止条件 
 	   if(List[left]>0) return List[left];
 	     else return 0;
 	    
		 center=(left+right)/2; //分 
 	     
   MaxLeft=DivideAndConquer(List,left,center);//求左边的最大值 
   MaxRight=DivideAndConquer(List,center+1,right);//求右边的最大值 
   
   MaxLeftSum=0;LeftSum=0;//从中间开始往两边求 
   for(i=center;i>=left;i--){
   
      LeftSum=LeftSum+List[i];
       if(LeftSum>MaxLeftSum)    //从中间往左边扫描 
            MaxLeftSum=LeftSum;
     }       
   
   MaxRightSum=0;RightSum=0;
   for(i=center+1;i<=right;i++){
   
      RightSum=RightSum+List[i];
       if(RightSum>MaxRightSum)  //从中间往右边扫描 
            MaxRightSum=RightSum;
     }    
	 return Max3(MaxLeft,MaxRight,MaxLeftSum+MaxRightSum);//将三个结果合在一起选取最大值 
	         
}
 
int MaxSubseqSum3(int List[],int N)//把借口转换过去 
{
	return DivideAndConquer(List,0,N-1);
}
 
    int main()
 {
 	 int subsque[100000],n,j;//输入n个随机的数 
 	 scanf("%d",&n);/*首先输入数的个数*/ 
 	 for(j=0;j<n;j++)
 	    scanf("%d",&subsque[j]);
 	   
 	    printf("%d",MaxSubseqSum3(subsque,n));
     	return 0;
 }	     


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值