存储类型、ADT、纯C去引用、算法及设计原则、时间复杂度---基本概念
来源:互联网 发布:dd linux命令复制磁盘 编辑:程序博客网 时间:2024/06/05 19:23
一、顺序印象&非顺序印象
是数据元素之间的关系在计算机中有两种不同的表示方法
二、顺序存储结构&链式存储结构
由两种印象得到两种不同的存储结构
1、顺序存储结构特点(连续)
借助元素在存储器中的相对位置来表示数据元素之间的逻辑关系
方便查找,增删数据麻烦
没有结点概念,只有元素
2、链式存储结构特点(不连续)
借助指示元素存储地址的指针表示数据元素之间的逻辑关系
方便增删数据,查找麻烦(得从头开始查找)
链式的插入不能先断之前的指针,否则会找不到后面的结点
结点含数据域和指针域
三、抽象数据类型(ADT)
ADT 抽象数据类型名{数据对象:<数据对象的定义>;数据关系:<数据关系的定义>;基本操作:<基本操作的定义>;}ADT 抽象数据类型名
其中数据对象和数据关系的定义用伪码描述,基本操作的定义格式为
基本操作(参数表) 初始条件:<初始条件描述> 操作结果:<操作结果描述>
基本操作有两种操作:
1.赋值操作只为操作提供输入值
2.引用参数以&打头,除可提供输入值外还将返回操作结果
“初始条件”
描述了操作执行之前数据结构和参数应满足的条件,若不满足,则操作失败,并返回相应出错信息。
“操作结果”
说明了操作正常完成之后,数据结构的变化状况和应返回的结果,若初始条件为空,则省略之
四、抽象数据类型例子
抽象数据类型三元组定义
ADT Triplet{数据对象:D={e1,e2,e3|e1,e2,e3属于ElemSet(定义了关系运算的某个集合)}数据关系:R1={<e1,e2>,<e2,e3>}基本操作: InitTriplet(&T,v1,v2,v3) //操作结果:构造了三元组T,元素e1,e2和e3分别被赋以参数v1,v2和v3的值 DestroyTriplet(&T) //操作结果:三元组T被销毁 Get(T,i,&e) //初始条件:三元组T已存在,1<=i<=3 //操作结果:用e返回T的第i元的值 Put(&T,i,e) //初始条件:三元组T已存在,1<=i<=3 //操作结果:改变T的第i元的值为e IsAscending(T) //初始条件:三元组T已存在 //操作结果:如果T的3个元素按升序排列,则返回1,否则返回0 IsDescending(T) //初始条件:三元组T已存在 //操作结果:如果T的3个元素按降序排列,则返回1,否则返回0 Max(T,&e) //初始条件:三元组T已存在 //操作结果:用e返回T的3个元素的最大值 Min(T,&e) //初始条件:三元组T已存在 //操作结果:用e返回T的3个元素的最小值 }
五、因为&为引用时是在C++中,在C中是取地址的意思,如果想写成纯C的两种办法
1.原例(直接在纯C下是无法实现的,必须要C和C++混用,强烈不推荐)
#include <stdio.h> #include <iostream>#include <stdlib.h> using namespace std; typedef struct{ float realpart;//实部 float imagpart;//虚部}complex;void Assign(complex &z,float r,float i){ z.realpart=r; z.imagpart=i;}int main(){ complex m; Assign(m,1.1,2.2); printf("%f",m.realpart); return 0;}
2、纯C方法一(将&引用取消)
#include <stdio.h> typedef struct{ float realpart;//实部 float imagpart;//虚部}complex;complex Assign(complex z,float r,float i){ z.realpart=r; z.imagpart=i; return z;}int main(){ complex m; complex C; C=Assign(m,1.1,2.2); printf("%f",C.realpart); return 0;}
3、纯C方法二(将&引用改为指针符号*)
#include<stdio.h>typedef struct { float realpart; float imagpart;}complex;void Assign(complex *z, float r, float i){ z->realpart = r; z->imagpart = i;}int main(){ complex *m = (complex *)malloc(sizeof(complex)); Assign(m, 1.1, 2.2); printf("%f %f", m->realpart, m->imagpart); free(m); return 0;}
六、算法五大特性
1.有穷性
一个算法必须总是(对任何合法的输入值)在执行有穷步之后结束,且每一步都可在有穷时间内完成
2.确定性
算法中每一条指令都要求确切的含义,且算法只有唯一的一条执行路径,即对于相同的输入只能得出相同的结果
3.可行性
算法是可行的
4.输入
5.输出
七、设计算法原则
1.正确性
2.可读性
3.健壮性
4.效率与低存储量需求
效率指算法执行时间,存储量需求指算法执行过程中所需要的最大存储量
八、时间复杂度
简单的说时间复杂度就是计算算法中基本操作重复执行的次数记为O(f(n)),基本操作是指最深层循环的语句的原操作
频度
指最深层循环的语句重复执行的次数
例子
1.常量阶,时间复杂度为O(1)
{++x;s=0}
2.线性阶,时间复杂度为O(n)
for(i=1;i<=n;i++){++x;s+=x}
3.平方阶,时间复杂度为O(n^2)
for(j=1;j<=n;j++) for(k=1;k<=n;K++) {++x;s+=x;}
4.对数阶,时间复杂度为O(logn)
最常见的是二分查找
#include<stdio.h>int main(){ int a[5]={1,2,3,4,5}; int right=5; int left=0; int mid; while(left<=right) { mid=(left+right)/2; if(a[mid]<1) { left=mid; } else if(a[mid]>1) { right=mid; } else{ printf("%d",mid); break; } }}
5.有时候算法的基本操作重复执行次数还随问题的输入数据集不同而不同
比如冒泡排序,输入数据有序而无序,其结果是不一样的
或是以下例子,数组数据和n都会影响
void bubble_sort(int a[],int n)
{
for(i=n-1,change=TURE;i>1&&change;–i)
{
change=false;
for(j=0;j
九、平均时间复杂度
平均时间复杂度就是计算出该算法最深层循环的原语句重复执行次数的方程后取最高次的(即取最坏的结果,其他的都可忽略(包括比如1/2*n^2,只要取n^2就好))
例
for(int i=2;i<=n;i++) for(j=2;j<=i-1;++j) {++x;a[i][j]=x;}
计算最深层循环的原语句操作次数
当i=2–》0次,i=3–》1次,i=4–》2次…..i=n–》n-2次
所以次数即1+2+3+…n-2,为1/2(n^2-3n+2),所以平均时间复杂度取O(n^2)
十、时间复杂度比较
多项式级
O(1)< O(logn)< O(n)< O(nlogn)< O(n^2)< O(n^3)
指数级
O(2^n)< O(n!)< O(n^n)
- 存储类型、ADT、纯C去引用、算法及设计原则、时间复杂度---基本概念
- 各种排序算法(c)及时间复杂度分析
- SOA设计模式--基本概念及原则
- UML基本概念及七大设计原则
- 数据结构之概述(数据和算法基本概念,时间复杂度)
- 【c/c++】算法的时间复杂度和空间复杂度
- 二分法实现插入排序,时间复杂度O(nlgn),算法导论练习2.3,linux纯C实现
- 设计时间复杂度小的算法
- 堆排序算法及时间复杂度分析
- url去重算法降低时间复杂度(python小技巧)
- 算法度量方法——时间复杂度及空间复杂度
- 各种排序算法时间复杂度及空间复杂度
- 各种排序算法比较及时间复杂度,空间复杂度
- 时间复杂度与空间复杂度的基本概念
- 六大设计原则基本概念
- 算法 时间复杂度|空间复杂度
- 算法 时间复杂度|空间复杂度
- 算法 时间复杂度|空间复杂度
- DB2和Oracle区别
- Eclipse/IDEA快捷键
- Linux 文件相关命令
- 机器学习(1)-KNN算法理解
- 2989:糖果(2.6基本算法之动态规划)
- 存储类型、ADT、纯C去引用、算法及设计原则、时间复杂度---基本概念
- mybatis_study03
- nodeJs之准备工作
- 网络框架okHttp源码分析
- HDU 4436 str2int
- TypeScript入门知识三(表达式和循环)
- Dialog 使用方法详解
- 排序算法小结
- Python中is和==的具体解释