ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

数据结构与算法

2021-02-20 21:04:26  阅读:323  来源: 互联网

标签:return int double 复杂度 PtrL 算法 数据结构


数据结构与算法

关于数据结构组织-例_图书的摆放

一、定义:数据结构是数据对象,以及存在于该对象的实例和组成实例的数据元素之间的各种联系。这些联系可以通过定义的函数来给出。(定义并不唯一)
二、对定义的解释(举例)
1、如何在书架上摆放图书?
<1>新书怎么插入?
<2>怎么找到某本指定的书?
方法1:随便放
方便新书插入,但极不方便找到某本指定的书。
方法2:按照书名的拼音字母顺序排放
用二分查找法查找指定的书,方便查找但不方便新书插入。
方法3:把书架划分成几块区域,每块区域指定摆放某种类别的图书;在每种类别内,按照书名拼音字母顺序排放
操作1:新书怎么插入?
先定类别,二分查找确定位置,移出空位
操作2:怎么找到某本指定的书?
先定类别,再二分法查找
问题:空间的分配及类别的分类
总结:解决问题方法的效率和数据的组织方式有关

关于空间使用-例_PrintN函数的实现

例子:写程序实现一个函数printN,使得传入一个正整数为N的参数后,能顺序打印从1到N的全部正整数
循环实现

vido PrintN(int N)
{
int i;
for(i=1;i<=N;i++)
printf("%d",N);
return;
}

递归实现

vido PrintN(int N)
{if(N)
{
PrintN(N-1)
printf("%d",N);
}
return;
}

当N=1000000时,递归方法无法实现;
总结:解决问题方法的效率,跟空间的利用效率有关。

关于算法效率

例子:写程序计算给定多项式在给定点x的值
在这里插入图片描述
方法一:

double f(int n,double a[],double x)
{
	int i;
	double p=a[0];
	for(i=1;i<=n;i++)
	p+=(a[i]*pow(x,i));
	return p;
}

方法二:

double f(int n,double a[],double x)
{
	int i;
	double p=a[i];
	for(i=n;i>0;i--)
	{
		p=a[i-1]+x*p;
	}
	return p;
}

相关知识:函数pow(x,y)即数学函数,x的y次方;
clock():捕捉从程序开始运行到clock()被调用时所耗费的时间。这个时间单位是clock tick,即“时钟打点”
常数CLK_TCK:机器时钟每秒所走的时钟打点数。
计算程序时间的代码

#include<stdio.h>
#include<time.h>
#include<math.h>
clock_t start ,stop;
double duration;
#define MAXN 10
#define MAXK 1e7
double f1(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 f2(int n,double a[],double x)
{
	int i;
	double p=a[i];
	for(i=n;i>=0;i--)
		p=a[i-1]+x*p;
	return p;
}
int main()
{
	int i;
	double a[MAXN];
	for(i=0;i<MAXK;i++)a[i]=(double)i;

		start=clock();
		for(i=0;i<MAXK;i++)
	f1(MAXN-1,a,1.1);
	stop=clock();
	duration=(double)(stop-start)/CLK_TCK/MAXK;
	printf("tickes=%f\n",(double)(stop-start));
	printf("duration1=%6.2e\n",duration);
	
		for(i=0;i<MAXK;i++)a[i]=(double)i;
	start=clock();
	for(i=0;i<MAXK;i++)
	f2(MAXN-1,a,1.1);
	stop=clock();
	duration=(double)(stop-start)/CLK_TCK/MAXK;
	printf("tickes=%f\n",(double)(stop-start));
	printf("duration2=%6.2e\n",duration);
	return  0;
}

运行结果如下:在这里插入图片描述
总结:解决问题方法的效率与算法的巧妙有关。

抽象数据类型

一、所以到底什么是数据结构
1、数据对象在计算机的中的组织方式

  • 逻辑结构(一对一,一对多,多对多)
  • 物理存储结构(计算机如何存储数据)
    2、数据对象必定与一系列加在其上的操作相关联
    3、完成这些操作所用的方法就是算法
    二、抽象数据类型(Abstract Data Type)
    1、数据类型
    <1>数据对象集(是什么东西)
    <2>数据集合相关联的操作集(对数据的操作)
    2、抽象:描述数据类型的方法并不依赖于具体实现
    <1>与存放数据的机器无关
    <2>与数据存储的物理结构无关
    <3>与实现操作的算法和编程语言均无关
    也就是说只描述对象集和相关操作集“是什么”,并不涉及“如何做到”的问题。

算法

一、定义:
1、一个有限指令集
2、接受一些输入(有些情况下不需要输入)
3、必须产生输入
4、一定在有限步骤之后终止
5、每一条指令必须:

  • 有充分明确的目标,不可以有歧义;
  • 计算机能处理的范围之内
  • 描述应不依赖于任何一种计算机语言以及具体的实现手段
    二、什么是好的算法
    1、空间复杂度S(n)——根据算法写成的程序在执行时占用存储单元的长度。这个长度往往与输入数据的规模有关。空间复杂度过高的算法可能导致使用的内存超限,造成程序非正常中断
    2、时间复杂度T(n)——根据算法写成的程序在执行时耗费时间长度。这个长度往往也与输入数据的规模有关。时间复杂度过高的低效算法可能导致我们在有生之年都等不到结果
    3、在分析一般算法的效率时,我们经常关注下面两种复杂度
    <1>最坏情况复杂度
    <2>平均复杂度
    分析时常分析最坏情况复杂度
    4、复杂度的渐进表示法
    在这里插入图片描述
    分析时,竭尽所能寻找最大的下届和最小的上界。
    在这里插入图片描述
    总结:1、若两段算法分别有复杂度T1(n)=O(f1(n))和T2(n)=O(f2(n)),则
    <1>T1(n)+T2(n)=max(O(f1(n)),O(f2(n)))
    <2>T1(n)*T2(n)=O(f1(n)*f2(n))
    2、若T(n)是关于n的k阶多项式,那么T(n)=Θ(n的k次方)
    3、一个for循环的时间复杂度等于循环次数乘以循环体代码的复杂度
    4、if—else结构的复杂度取决于if的条件判断复杂度和两个分支的复杂度,总体复杂度取三者最大
    例题:在这里插入图片描述
    算法1:
int MaxSubseqsum1(int A[],int N)
{
	int ThisSum,MaxSum=0;
	for(i=0;i<N;i++)
	{
		for(j=i;j<N;j++)
		{
			ThisSum=0;
			for(k=i;k<=j;k++)
			ThisSum+=A[k];
			if(ThisSum>MaxSum)
			MaxSum=ThisSum;
		}
	}
	return MaxSum;
 } 

算法2:

int MaxSubseqSum1(int A[],int N)
{
	int i,j;
	for(i=0;i<n;i++)
	ThisSum=0;
	for(j=i;j<N;j++)
	{
	ThisSum+=A[j];
	if(ThisSum>MaxSum)
	MaxSum=ThisSum;
	}
	return MaxSum;
}

算法2要比算法1简单。
算法三(在线算法):

int MaxSubseqSum4(int A[],int N)
int ThisSum,MaxSum;
int i;
ThisSum=MaxSum=0;
for(i=0;i<N;i++)
{
ThisSum+=A[i];
if(ThisSum>MaxSum)
else if(ThisSum<0)
ThisSum=0;}
return MaxSum;

引子_多项式表示

一、线性表及其实现
1、线性结构的定义:数据元素之间构成一个有序的序列
例子:在这里插入图片描述
方法1:采用顺序存储结构直接表示一元多项式
在这里插入图片描述
缺点:如果要表示x+pow(x,3000),就必须采用一个大小至少为3001的数组,而在这个数据中大多数数据均为0,只有两项不为0,显然空间浪费得厉害。
方法二:顺序存储结构表示非零项:在这里插入图片描述
按指数大小有序排列
方法三:链表结构存储非零项
在这里插入图片描述
启示:
<1>同一个问题可以有不同的表示(存储)方法
<2>有一类共性问题:有序线性序列的组织和管理
2、什么是线性表
<1>定义:由同类型数据元素构成有序序列的线性结构
<2>特点:
1)表中元素个数被称为线性表长度
2)线性表没有元素时,称为空表
3)表起始位置称表头,表结束位置称表尾

在这里插入图片描述

typedef strcut LNode *List
strcut LNode{
   ElementType Data[MAXSIZE];
   int Last;
   };
   struct LNode L;
   List PtrL;

访问下标为i的元素:L.Data[i]或PtrL->Data[i]
线性表的长度:L.Last+1或PtrL->Last+1
主要操作的实现
1.初始化(建立空的顺序表)

List MakeEmpty()
{List PtrL;
PtrL=(List)malloc(sizeof(struct LNode));
PtrL->=-1;
return PtrL;}

2.查找

int Find(ElementType X,List PtrL)
{int i=0;
while(i<=PtrL->Last&&PtrL->Data[i]!=X)
i++;
if(i>PtrL->Last)
return -1;
else return i;}

3.插入(第i(1<=i<=n+1))个位置上插入一个值为X的新元素)
在这里插入图片描述

void Insert(ElementType X,int,List PtrL)
{
if(PtrL->Last==MAXSIZE-1)
{printf("表满");
return;
}
if(i<1||i>PtrL>Last+2)
{printf("位置不合法");
return;
}
for(j=PtrL->Last;j>=i-1;j--)
PtrL->Data[j+1]=PtrL->Data[j];
PtrL->Data[i-1]=X;
PtrL->Last++;
return;
}

平均移动次数为n/2
平均时间性能为O(n)
4.删除(删除表的第i(1<=i<=n)个位置上的元素)
在这里插入图片描述

void Delete(int i,List PtrL)
{int j;
if(i<1||i>PtrL->Last+1){
printf("不存在第%d个元素",i);
return;
}
for(j=i;j<=PtrL->Last;j++)
PtrL->Data[j-1]=PtrL-->Data[j];
PtrL->Last--;
}

标签:return,int,double,复杂度,PtrL,算法,数据结构
来源: https://blog.csdn.net/weixin_53549425/article/details/113737757

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有