[数据结构]抽象数据类型算法

2023-10-15 05:38

本文主要是介绍[数据结构]抽象数据类型算法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

第一章 绪论

1.3 抽象数据函数

数据类型:一个值的集合和定义在这个值集上一组操作的总称。

例:C语言中,提供int,  char, float, double等基本数据类型,数组、结构体、共用体、枚举等构造数据类型,还有指针、空(void)类型等。

用户也可用typedef自己定义数据类型

typedef   struct  {     

        int   num;

        char  name[20];

        float   score;

} STUDENT;

STUDENT    stu1,stu2, *p;

抽象数据类型(ADT):指一个数学模型以及定义在该模型上的一组操作。“抽象”的意义在于数据类型的数学抽象特性。

例:矩阵 +(求转置、加、乘、求逆、求特征值)构成一个矩阵的抽象数据类型

数据结构 +定义在此数据结构上的一组操作   =抽象数据类型

描述方法:

形式定义:我们用一个三元组(D,S,P)来表示一个 抽象数据类型 ,其中D是数据对象,S是D上的关系集,P是对D的基本操作集。

格式: ADT抽象数据类型名{

                     数据对象:〈数据对象的定义〉

                     数据关系:〈数据关系的定义〉

                     基本操作:〈基本操作的定义〉

                } ADT抽象数据类型名

基本操作的定义格式:          

     基本操作名(参数表(赋值参数引用参数,以“&”打头))

              初始条件:〈初始条件描述〉

              操作结果:〈操作结果描述〉

例:抽象数据类型三元组的定义:

   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个元素中的最小值。

       }ADT Triplet

 

1.4 算法和算法分析

算法:是对特定问题求解步骤的描述,是指令的有限序列。

算法五个重要特性:

有穷性:对于任意一组合法输入值,在执行有穷步之后结束,即算法中的每个步骤都能在有限时间内完成;

确定性:每条指令都有确切的含义,在任何条件下算法都只有一条执行路径;

可行性:算法中的所有操作都必须足够基本,都可以通过已经实现的基本操作运算有限次实现之;

有输入:有零个或多个输入,取自特定的对象集合;

有输出:有一个或多个输出,是算法进行信息加工后得到的结果。

 

算法设计的原则

正确性:在合理的数据输入下,能在有限的运算时间内得到正确结果;

对算法是否“正确”的理解可以有以下四个层次:

   a.程序中不含语法错误;

   b.程序对于几组输入数据能够得出满足要求的结果;

   c.程序对于精心选择的、典型、苛刻且带有刁难性的几组输入数据能够得出满足要求的

      结果;

   d.程序对于一切合法的输入数据都能得出满足要求的结果;

可读性:易于人对算法的理解;另一方面,晦涩难读的程序易于隐藏较多错误而难以调试;

健壮性: 当输入的数据非法时,算法应当恰当地作出反应或进行相应处理,而不是产生莫名奇妙的输出结果。并且,处理出错的方法不应是中断程序的执行,而应是返回一个表示错误或错误性质的值,以便在更高的抽象层次上进行处理。

高效率与低存储量需求:通常,效率指的是算法执行时间;存储量指的是算法执行过程中所需的最大存储空间。两者都与问题的规模有关。

 

算法效率的衡量方法和准则

有两种衡量算法效率的方法:

  1.事后统计法:利用计算机内记时功能,用一组或多组相同的统计数据区分。

  2.事前分析估计法:求出算法的一个时间界限函数。

和算法执行时间相关的因素:

算法选用的策略    

  问题的规模      

  编写程序的语言       

  编译程序产生机器代码质量

  机器执行指令速度

时间复杂度:程序运行从开始到结束所需要的时间。

设解决一个问题的规模为n,基本操作被重复执行的次数是n的一个函数f(n),假如,随着问题规模n的增长,算法执行时间的增长率和f(n)的增长率相同,则可记作:

                            T (n) = O(f(n))

其中T(n)叫算法的渐进时间复杂度,简称时间复杂度。

算法=控制结构+原操作(固有数据类型的操作)

算法的执行时间=∑原操作(i)的执行次数╳原操作(i)执行时间

从算法中选取一种对于所研究的问题来说是基本运算的原操作,以该原操作重复执行的次数作为算法运行时间度衡量准则。

例1:NXN矩阵相乘

for(i=1; i<=n; i++)

  for(j=1; j<=n; j++)

     { c[i][j]=0;

        for(k=1; k<=n; k++)

                 c[i][j]=c[i][j]+a[i][k]*b[k][j]; }

 

显然,被称做问题的基本操作的原操作应是其重复执行次数和算法的执行时间成正比的原操作,多数情况下是最深层循环内的语句中的原操作,它的执行次数和包含它的语句频度相同。

例2.{++x;s=0;}                           T(n)=O(1)  常量阶

例3.for(i=1; i<=n; ++i)

       {++x; s+=x;}                        T(n)= O(n)   线性阶

例4. for(i=2; i<=n; ++i)

         for(j=2; j<=i-1; ++j)

              {++x; a[i,j]=x;}

++x语句频度为:1+2+3+…+n-2

               =(n-1)(n-2)/2

               =(n2-3n+2)/2    

          T(n)= O(n2)  平方阶 

Ο(1)<Ο(log2n)<Ο(n)<Ο(n2)<Ο(n3)<Ο(2n)

例5:Void bubble-sort(int a[ ],int n)

              for( i=n-1,change=TURE; i>=1 && change; - -i)

                    {   change=false;

                         for(j=0; j<i; ++j )

                         if (a[j]>a[j+1])

                          { a[j]←→a[j+1]; change=TURE;}

                    }

最好情况:0次

最坏情况:1+2+3+…+n-1 = n(n-1)/2

平均时间复杂度为:O(n2)

算法的存储空间需求

空间复杂度:算法所需存储空间的度量,记作:S(n)=O(f(n))       

算法的存储量包括:(1)输入数据所占空间;

                 (2)程序本身所占空间;

                 (3)辅助变量所占空间。

注意:算法的所有性能之间都存在着或多或少的相互影响,因此,当设计一个算法,特别是大型算法时,要综合考虑算法的各项性能、算法的使用频率、算法处理的数据量的大小、算法描述语言的特性及算法运行的机器系统环境等各方面因素,才能设计出比较好的算法。

这篇关于[数据结构]抽象数据类型算法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/215669

相关文章

C#数据结构之字符串(string)详解

《C#数据结构之字符串(string)详解》:本文主要介绍C#数据结构之字符串(string),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录转义字符序列字符串的创建字符串的声明null字符串与空字符串重复单字符字符串的构造字符串的属性和常用方法属性常用方法总结摘

SpringBoot实现MD5加盐算法的示例代码

《SpringBoot实现MD5加盐算法的示例代码》加盐算法是一种用于增强密码安全性的技术,本文主要介绍了SpringBoot实现MD5加盐算法的示例代码,文中通过示例代码介绍的非常详细,对大家的学习... 目录一、什么是加盐算法二、如何实现加盐算法2.1 加盐算法代码实现2.2 注册页面中进行密码加盐2.

Java时间轮调度算法的代码实现

《Java时间轮调度算法的代码实现》时间轮是一种高效的定时调度算法,主要用于管理延时任务或周期性任务,它通过一个环形数组(时间轮)和指针来实现,将大量定时任务分摊到固定的时间槽中,极大地降低了时间复杂... 目录1、简述2、时间轮的原理3. 时间轮的实现步骤3.1 定义时间槽3.2 定义时间轮3.3 使用时

如何通过Golang的container/list实现LRU缓存算法

《如何通过Golang的container/list实现LRU缓存算法》文章介绍了Go语言中container/list包实现的双向链表,并探讨了如何使用链表实现LRU缓存,LRU缓存通过维护一个双向... 目录力扣:146. LRU 缓存主要结构 List 和 Element常用方法1. 初始化链表2.

golang字符串匹配算法解读

《golang字符串匹配算法解读》文章介绍了字符串匹配算法的原理,特别是Knuth-Morris-Pratt(KMP)算法,该算法通过构建模式串的前缀表来减少匹配时的不必要的字符比较,从而提高效率,在... 目录简介KMP实现代码总结简介字符串匹配算法主要用于在一个较长的文本串中查找一个较短的字符串(称为

通俗易懂的Java常见限流算法具体实现

《通俗易懂的Java常见限流算法具体实现》:本文主要介绍Java常见限流算法具体实现的相关资料,包括漏桶算法、令牌桶算法、Nginx限流和Redis+Lua限流的实现原理和具体步骤,并比较了它们的... 目录一、漏桶算法1.漏桶算法的思想和原理2.具体实现二、令牌桶算法1.令牌桶算法流程:2.具体实现2.1

Go语言中三种容器类型的数据结构详解

《Go语言中三种容器类型的数据结构详解》在Go语言中,有三种主要的容器类型用于存储和操作集合数据:本文主要介绍三者的使用与区别,感兴趣的小伙伴可以跟随小编一起学习一下... 目录基本概念1. 数组(Array)2. 切片(Slice)3. 映射(Map)对比总结注意事项基本概念在 Go 语言中,有三种主要

Python中的随机森林算法与实战

《Python中的随机森林算法与实战》本文详细介绍了随机森林算法,包括其原理、实现步骤、分类和回归案例,并讨论了其优点和缺点,通过面向对象编程实现了一个简单的随机森林模型,并应用于鸢尾花分类和波士顿房... 目录1、随机森林算法概述2、随机森林的原理3、实现步骤4、分类案例:使用随机森林预测鸢尾花品种4.1

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第