数据结构
第一章 绪论
基本概念
数据结构(这门学科): 是一门研究数据的组织, 存储, 和运算的一般方法。
数据 : 是客观事物的符号表示, 是所有能输入到计算机中并被计算机程序处理的符号的总称。
数据元素 : 是数据的基本单位, 在计算机中通常作为一个整体进行考虑和处理。数据元素用于完整地描述一个对象。
数据项 : 组成数据元素的、 有独立含义的、 不可分割的最小单位。例如 :学生的姓名学号等。
数据对象 : 是性质相同的数据元素的集合, 是数据的一个子集。只要集合内的性质均相同, 都可称之为一个数据对象。
数据结构 : 是相互之间存在一种或多种特定关系的数据元素的集合。
数据结构
-
逻辑结构
- 集合结构(离散结构, 因为太简单, 所以不考虑)
- 线性结构
- 非线性结构
- 树结构
- 图结构或网状结构
-
存储结构
- 顺序存储结构
- 链式存储结构
逻辑结构
二元组 (D, R)
- D是数据关系的集合
- R是D关系上的集合
() 代表无序 <> 代表有序
抽象数据类型
抽象数据类型 : 一般指由用户定义的、 表示应用问题的数学模型, 以及定义在这个模型上的一组操作的总称。
具体包括三部分: 数据对象, 数据对象上关系的集合 以及 对数据对象的基本操作的集合。
定义格式:
ADT 抽象数据类型名{
数据对象:<数据对象的定义>
数据关系:<数据关系的定义>
基本操作:<基本操作的定义>
} ADT 抽象数据类型名
算法
**算法 :**是为了解决某类问题而规定的一个有限长的操作序列。
重要特性
- 有穷性
- 确定性
- 可行性
- 输入
- 输出
评价算法优劣的基本标准
- 正确性 能在有限的运行时间内得到正确的结果。
- 可读性
- 健壮性
- 高效性 时间空间
- 语句频度: 一条语句重复执行的次数
算法的时间复杂度: (一般指的是最坏时间复杂度)
常量阶实例
for (int i = 1; i <= 100000000; i++){
puts("我爱你啊亲!");
}
此算法时间复杂度 T(n) = O(1)。
算法的空间复杂度
- 常量阶
for (int i = 0; i <= n / 2; i++){
t = a[i];
a[i] = a[n - i + 1];
a[n - i - 1] = t;
}
- 线性阶
for (int i = 0; i < n; i++)
b[i] = a[n - i + 1];
for (int i = 0; i < n; i++)
a[i] = b[i];
此算法需要借助大小为n的辅助数组, 所以其空间复杂度为O(n)。
第二章 线性表
线性表是具有相同特性的数据元素的一个有限序列
- 其中数据元素的个数n定义为表的长度。
- 当n=0时称为空表
- 将非空的线性表(n>0)记作: (a1, a2, …an)
- 这里的数据元素ai(1≤i≤n)只是一个抽象的符号,其具体含义在不同的情况下可以不同。
特征:
- 在非空的线性表,有且仅有一个开始结点a1,它没有直接前趋,
而仅有一个直接后继a2; - 有且仅有一个终端结点an,它没有直接后继,而仅有一个直接
前趋an-1; - 其余的内部结点ai(2≤i≤n-1)都有且仅有一个直接前趋ai-1和一
个直接后继ai+1。
顺序存储结构
线形表顺序存储结构占用一片连续的存储空间
。知道某个元素的存储位置就可以计算其他元素的存储位置
存储位置公式
每个数据元素,不管它是整型,实型还是字符型,它都是需要占用一定的存储单元空间的
假设占用的是 c 个存储单元,那么对于线性表的第 i 个数据元素 的存储位置都可以由 推导算出:
顺序表的特点:
- 以物理位置相邻表示逻辑关系。
- 任一元素均可随机存取。(优点)
#define MAXSIZE 100000 //图书最大长度
typedef struct { //定义图书信息
char no[20]; //图书isbn
char name[50]; //图书名字
float price; //图书价格
}Book;
typedef struct
{
Book *elem; //存储空间基地址
int length; //图书表中单签的图书个数
}SqList; //图书表的顺序存储结构类型为SqList
c语言的内存动态分配
- malloc(m)函数, 开辟m字节长度的地址空间 并返回这段空间的首地址(需要加载头文件<stdlib.h>)
- sizeof(x)运算, 计算变量x的长度
- free§函数, 释放指针p所指变量的存储空间,即彻底删除一个变量
SqList L;
L.elem=(ElemType*)malloc(sizeof(ElemType)*MaxSize); //ElemType是数据类型 例如int
// ↑根据数据类型来分配要多少个空间 ↑这个来计算一共要多少空间
参数传递有两种方式
- 传值方式(不改变实参)
- (参数为整型、实型、字符型等)
- 传地址(可以改变实参)
- 参数为指针变量
- 参数为数组名
- 传递的是数组的首地址
- 对形参数组所做的任何改变都将反映到实参数组中
发生变化:
#include<stdio.h>
int main()
{
int a,b,*p1,*p2;
scanf("%d %d",&a,&b);
p1=&a;
p2=&b;
swap(p1,p2);
printf("%d %d",a,b);
return 0;
}
void swap(int *m,int *n){
int t;
t=*m; //这里交换的是m指针指向的内容即p1,p2的地址
*m=*n;
*n=t;
}
不发生变化:
#include<stdio.h>
int main()
{
int a,b,*p1,*p2;
scanf("%d %d",&a,&b);
p1=&a;
p2=&b;
swap(p1,p2);
printf("%d %d",a,b);
return 0;
}
void swap(int *m,int *n){
int *t;
t=m; //这里交换的是m指针本身
m=n;
n=t;
}