数据结构
数据结构概述
定义:
我们如何把现实中大量而复杂的问题以特定的数据类型和特定的存储结构保存到主存储器(内存)中,以及在此基础上为实现某个功能(比如查找某个元素,删除某个元素,对所有元素进行排序)而执行的相应操作,这个相应的操作也叫算法
狭义
数据结构是专门研究数据存储的问题
数据结构 = 个体 的存储+ 个体关系的储存
从某个角度而言,数据的存储最核心的就是个体关系的存储,个体的存储可以忽略不计
广义
数据结构包含数据的存储也包含数据的操作
对数据的操作就是算法
算法:
狭义:算法是和数据的存储方式密切相关
广义:算法和数据的存储方式无关,泛型思想
泛型:利用某种技术达到的效果就是:不同的存储方式,执行的操作是一样的
同一种逻辑结构,无论该逻辑结构内部物理存储是什么样子,我们可以对它执行相同的操作
解题的方法和步骤
衡量算法的标准
1. 时间复杂度
大概程序要执行的次数,而非执行的时间
2. 空间复杂度
算法执行过程中大概所占用的最大内存
3. 难易程度
4. 健壮性
数据结构的地位
数据结构是软件中最核心的课程
程序 = 数据的存储 + 数据的操作 + 可被计算机执行的语言
预备知识
1. 指针
指针的重要性:指针是C语言的灵魂
定义
地址:内存存储的编号
从0开始的非负整数
范围:0 – FFFFFFFF(4G-1)
指针:指针就是地址 地址就是指针
指针变量是存放内存单元地址的变量
指针的本质是一个操作受限的非负整数(不能加乘除,只能在某种特定情况下进行减法)
分类:
1) 基本类型的指针
p存放了i的地址,说明 ①p保存了i的地址,p指向i ②修改p或者i不会相互影响 ③ *p 就是i,i就是 *p
内存的基本单位是字节
1字节是8位
整数型
short :2个字节,16位 int :4个字节,32位 long:8个字节,64位;
浮点型:
float:4个字节,32 位 double:8个字节,64位
注:默认的是double类型,如3.14是double类型的,加后缀F(3.14F)则为float类型的。
字节类型:char:2个字节,16位
字节和编号是一一对应的,每个字节都有一个唯一确定的编号,一个编号对应一个字节,这个编号也叫地址
int i = 10;
int * p = &i; //相当于int * p ; p = &i;
如何通过被调函数修改主调函数中普通变量的值
①实参为相关变量的地址
②形参为以该变量的类型为类型的指针变量
③在被调函数中通过 *形参变量名 的方式就可以修改主函数的变量值
#include <stdio.h>
void f(int * i)
{
* i = 100;
}
int main(void)
{
int i = 9;
f(&i);
printf("%d\n", i); //i = 100
return 0;
}
2) 指针和数组的关系
一维数组名是个指针常量,它存放数组第一个元素的地址,它指向数组的第一个元素,值不能被改变
a[i] = *(a+i)
a[3] = *(a+3) = *(3+a) = 3[a]
printf("%p\n", a); //%p表示输出p的地址以16进制输出
# include <stdio.h>
void Show_Array(int * p, int len) //p是int * 类型,a传送给了p,a = &a[0],则p = &a[0]
{
p[0] =-1; // p[0] == *p == *a == a[0]
}
int main(void)
{
int a[5] = {
1,2,3,4,5};
Show_Array(a, 5); //a本来就是int * 类型的,所以可以发送给 同类型 的p
printf("%d\n", a[0]);
return 0;
}
p+i 的值是p+i*(p所指向的变量所占的字节数)
如何通过被调函数修改主调函数中一维数组的内容
两个参数①存放数组首元素的指针变量 ②存放数组元素长度的整型变量
int i, * p;
p = &i; //p和i占8个字节,1字节1地址,但是p并非保存了i的8个地址,而是只存放其首地 址或者末地址
在64位计算机中,无论指针变量是int,char,double*类型,统统只占8个字节
2. 结构体
结构体是一种复合的数据类型,不是变量
结构体名字叫做struct student,有有限个成员
定义
struct Student
{
int age;
char name[100];
int score;
}; //分号不能省
定义了一个数据类型,该数据类型叫做struct Student,该数据类型有三个成员,没有定义变量
结构体的使用 重点:(3)
1)struct Student st = {50, “lisi”, 150};
2)struct Student st;
st.age = 50;
strcpy(st.name, “lisi”); //定义库<string.h> ,不能是st.name = “lisi”
st.score = 150;
3) struct Student st;
struct Student * pst; //pst占了4个字节
pst = &st;
pst->age = 50; //pst->age == (*pst).age
pst->name = “lisi”;
pst->score