数据结构教程绪论

7 篇文章 0 订阅

绪论

前言

数据是珍贵的东西,比系统本身更持久。

基本数据组织和数据处理的方法:

  • 各种数据的逻辑结构描述。
  • 各种数据的存储结构表示。
  • 各种数据结构的运算定义。
  • 设计实现运算的算法。
  • 分析算法的效率。

学习目标

  • 掌握数据结构的基本概念,基本原理和基本方法。
  • 掌握数据的逻辑结构存储结构基本运算的实现过程
  • 掌握算法基本的时间复杂度空间复杂度的分析方法,能够设计出求解问题高效算法。

学习方法

  • 理解各种数据结构的逻辑特性存储结构设计。
  • 掌握各种数据结构算法设计的基本方法。
  • 利用各种数据结构来求解实际问题
  • 演绎和归纳相结合。

A、什么是数据结构

1.数据:
所有能够输入到计算机中,且能被计算机处理的符号的集合。
2.数据项:
用于描述数据元素,是数据的最小单位。
3.数据对象:
具有相同性质的若干个数据元素的集合,如整数数据对象是所有整数的集合。
4.数据结构:
是指带结构的数据元素的结合。
数据结构=数据对象+结构
在这里插入图片描述
数据结构中讨论的元素关系主要是指相邻关系或邻接关系。
在这里插入图片描述

数据结构的构成

逻辑结构+存储结构+数据运算

  • 逻辑结构:
    数据元素之间的逻辑关系。
    在这里插入图片描述
    学生表的逻辑结构表示二元数组,二元组是一种通用的逻辑结构表示方法。
    在这里插入图片描述

  • 存储结构:
    数据元素及其关系在计算机存储器中的存储方式。

  • 数据运算:
    施加在该数据上的操作。

1.数据的逻辑结构表示

每个关系用若干个序偶来表示:
序偶<x,y>(x,y ∈ \in D) ⇒ \Rightarrow x为第一元素,y为第二元素。
x为y的前驱元素,y为x的后继元素。
若某元素没有前驱元素,则该元素为开始元素,若某元素没有后继元素,则该元素为终端元素。
序偶<x,y>表示x,y是有向的,序偶(x,y)表示x,y是无项的。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.数据的存储结构表示

在这里插入图片描述
设计存储结构的这种映射应满足两个要求:

  • 存储所有元素
  • 存储数据间的关系
1.学生表存储结构1——结构体数组

在这里插入图片描述
在这里插入图片描述
由此可看出:两个逻辑上相邻的元素,其存储空间也相邻。
这种存储空间结构(顺序存储结构)的特点:

  • 所有元素占用一整块内存空间。
  • 逻辑上相邻的元素,物理上也相邻。
2.学生表存储结构2——链表

在这里插入图片描述
在这里插入图片描述
这种存储结构(链式存储结构)的特点:

  • 一个逻辑元素用一个结点储存,每个结点单独分配,所有结点的地址不一定是连续的。
  • 用指针来表示逻辑关系。

3.数据运算

数据运算分两个层次:
运算描述和运算实现。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
结论:

  • 同一逻辑结构可以对应多种存储结构。
  • 同样的运算,在不同的存储结构中,其实现过程是不同的。

一、逻辑结构类型

1.集合
元素之间的关系:无
特点:数据之间属于同一集合。
在这里插入图片描述

2.线性结构
元素之间的关系:一对一
特点:开始元素与终端元素唯一,另外,其余元素有且仅有一个前驱元素和一个后继元素。
在这里插入图片描述

3.树形结构
元素之间的关系:一对多
特点:开始元素唯一,终端元素不唯一。另外,每个元素有一个或多个后继元素(除终端元素),么个元素有且仅有一个前驱元素(除开始元素)。
在这里插入图片描述
4.图形结构
元素之间的关系:多对多
特点:所有元素都有可能有多个前驱元素和多个后继元素。
在这里插入图片描述

二、存储结构类型

  1. 顺序存储结构
  2. 链式存储结构
  3. 索引存储结构
  4. 哈希存储结构

数据类型和抽象数据类型

1.数据类型:
是一个值的集合和定义在此集合上的一组操作的总称。
在这里插入图片描述

2.抽象数据类型(ADT):

指从求解问题的数学模型中抽象出来的数据结构和运算,不考虑计算机的运算。
抽象数据类型=逻辑结构+抽象运算
在这里插入图片描述

B、什么是算法

通常把基于存储结构的运算实现的步骤或过程称为算法。

1.算法的五个重要特性

  • 有穷性:在有穷步之后结束,算法能够停机。
  • 确定性:无二义性。
  • 可行性:可通过基本运算有限次执行来实现,即每一个动作都能被机械地执行。
  • 输入:0个或多个输入。
  • 输出:1个或多个输出。

2.算法与程序的区别

程序指的是某种计算机语言对一个算法的具体实现,及具体怎么做。而算法侧重于对解决问题的方法的描述,即要做什么。算法用计算机语言描述就得到程序。

3.算法描述

在这里插入图片描述
在这里插入图片描述
参数传递:
在这里插入图片描述
在这里插入图片描述
例如,设计一个算法在这里插入图片描述
在这里插入图片描述
代码实现:

#include<iostream>
#include<cmath>
using namespace std;
void solution(float a, float b, float c, float& x1, float& x2);
int main()
{
	float a, b, c,m,x1,x2;
	cout << "请输入a,b,c的值:" << endl;
	cout << "a=";
	cin >> a;
	cout << "b=";
	cin >> b;
	cout << "c=";
	cin >> c;
	cout << "求得的方程的根为:";
	solution(a, b, c, x1, x2);
	return 0;
}
void solution(float a, float b, float c, float& x1, float& x2)
{
	float d;
	d = b * b - 4 * a * c;
	if (d > 0)
	{
		x1 = (-b + sqrt(d)) / (2 * a);
		x2 = (-b - sqrt(d)) / (2 * a);
		cout << x1 << " " << x2 << endl;
	}
	else if (d == 0)
	{
		x1 = (-b) / (2 * a);
		cout << x1 << endl;
	}
	else
		cout << "该方程无实根!";
}

4.算法分析

在这里插入图片描述
算法分析的目的:
分析算法的时空效率以便改进算法性能。

一、算法时间复杂度分析

一个算法是由控制结构(顺序,分支和循环)和原操作构成的。
在这里插入图片描述
顺序结构:按照所述顺序处理。
分支结构:根据判断条件改变执行流程
循环结构:当条件成立时,反复执行给定的处理操作。
原操作:指固有数据类型的操作,如+,-,*,/,++,–等。
算法的执行时间取决于两者的综合效果。
例如:
在这里插入图片描述

算法分析方式

1.事后分析统计方法:
编写算法对应程序,统计其执行时间。
在这里插入图片描述
2.事前估算分析方法:
撇开上述因素,认为算法执行时间是问题规模n的函数。

分析算法执行时间
  • 求出算法所有原操作的执行次数(也称为频度),它是问题规模n的函数,用T(n)表示。
  • 算法执行时间大致=原操作所需时间*T(n)。所以T(n)与算法的执行时间成正比。为此用T(n)表示算法的执行时间。
  • 比较不同算法的T(n)大小得出算法执行时间的好坏。
    T(n)表示求解问题大小的正整数,如n个记录排序。
    例如:求两个n阶方阵的相加C=A+B的算法如下,分析其时间复杂度。

伪代码:

#define NAX=28
voidmatrixadd(int n,int A[MAX][MAX],int B[MAX][MAX],int C[MAX][MAX])
{
int i,j;
for(i=0;i<n;i++)	//1
for(j=0;j<n;j++)		//2
C[i][j]=A[i][j]+B[i][j];	//3
}

除变量定义语句外,该算法包括3个可执行语句1,2和3。
1.频度为n+1,循环体执行n次。
2.频度为n*(n+1)。
3.频度为n*n。
因此,所有语句频度之和为:
在这里插入图片描述
算法执行时间用时间复杂度来表示:
算法中执行时间T(n)是问题规模n的某个函数f(n),记作:
T(n)=O(f(n))
"O"表示随问题规模n的增大算法执行时间的增长率和f(n)的增长率相同。
在这里插入图片描述
"O"的形式定义为:
T(n)=O(f(n))表示存在一个正的常数c,使得当n>=n0时都满足:
|T(n)|<=|c(f(n)|
f(n)是T(n)的上界,
通常有:
在这里插入图片描述
也即只求出T(n)的最高阶,忽略其低阶项和常系数,这样既可以简化T(n)的计算,又能比较客观地反映当n很大时算法的时间性能。
一般地:

  • 一个没有循环的算法的执行时间与问题规模n无关,记作0(1),也称作常数阶。
  • 一个只有一重循环的算法的执行时间与问题规模n的增长呈线性增大关系,记作0(n),也称线性阶。
  • 在这里插入图片描述
    各种不同算法时间复杂度的比较关系如下:
    在这里插入图片描述
    算法时间性能比较:
    假如求同一问题有两个算法:A和B,如果算法A的平均时间复杂度为0(n),而算法B的平均复杂度为0(n*n)。
    一般情况下,认为算法A的时间性能比算法B好。
简化的算法时间复杂度的分析

算法中的基本操作一般是最深层循环内的原操作。
算法执行时间大致=基本操作所需的时间*其运算次数
在算法分析时,计算T(n)时仅仅考虑基本操作的运算次数。

最好、最坏和平均时间复杂度分析

定义:设一个算法的输入规模为n,Dn是所有输入的集合,任意输入I ∈ \in Dn,P(I)是I出现的概率,有 ∑ \displaystyle\sum P(I)=1,T(I)是算法输入I下的执行时间,则算法的平均时间复杂度为:
在这里插入图片描述
例如:10个1~10的整数序列递增排序。(n=10):
在这里插入图片描述
所有可能的初始序列有m个,m=10! ⇒ \Rightarrow P(I)=1/m。
在这里插入图片描述
在这里插入图片描述
解:
算法的主要时间花费在元素比较上:

  • i的取值范围为1~n,共n种情况。
  • 在等概率的情况(每种情况的概率为1/n).
  • 求前i个元素的最大值时,max=a[0],将其与a[1…i-1]元素进行比较。比较次数=(i-1)-1+1=i-1次。
    在这里插入图片描述
  • i=1时,比较次数为0 ⇒ \Rightarrow 算法的最好复杂度B(n)=0(1)。
  • i=n时,比较次数为n-1 ⇒ \Rightarrow 算法的最坏复杂度W(n)=0(n)。
二、算法空间复杂度的分析

空间复杂度:
用于度量一个算法运行过程中临时占用的内存空间的大小。
一般也作为问题规模n的函数,采用数量级形式描述,记作:
S(n)=0(g(n))
若一个算法的空间复杂度为0(1),则称此算法为原地工作或就地工作算法。

空间复杂度考虑临时占用的存储空间

在这里插入图片描述
在这里插入图片描述

第一课:数据结构的基本概念和术语 第二课:抽象数据类型的表示与实现 第三课:算法算法设计要求 第四课:算法效率的度量和存储空间需求 第五课:线性表的类型定义 第六课:线性表的顺序表示和实现 第七课:实验一 线性表的顺序存储实验 第八课:线性表的链式表示与实现 第九课:循环链表与双向链表 第十课:栈的表示与实现 第十一课:栈的应用 第十二课:实验二 循环链表实验 第十三课:队列 第十四课:串的定义 第十五课:串的表示和实现 第十六课:串操作应用举例 第十七课:实验三:栈的表示与实现及栈的应用 第十八课:数组的顺序表示与实现 第十九课:实验四 串的实现实验 第二十课:广义表 第二十一课:树、二叉树定义及术语 第二十二课:实验五 数组实验 第二十三课:二叉树的存储结构 第二十四课:遍历二叉树 第二十五课:单元测验 第二十六课:图的定义与术语 第二十七课:实验六 二叉树实验 第二十八课:图的存储结构 第二十九课:静态查找表(一)顺序表的查找 第三十课:静态查找表(二)有序表的查找 第三十一课:动态查找表 第三十二课:哈希表(一) 第三十三课:哈希表(二) 第三十四课:插入排序,快速排序 第三十五课:实验七 查找 第三十六课:选择排序,归并排序 第三十七课:实验八 排序实验 第三十八课:文件概念,顺序文件 第三十九课:索引文件 第四十课:总复习
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

神秘的老年人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值