数据结构概述
定义:我们如何把现实中大量而复杂的问题以特定的数据类型和存储结构保存到主存储器中,以及在此基础上为实现某个功能而执行相应操作,这个相应的操作也叫算法。
数据结构 = 个体加个体的关系
算法 = 对存储数据的操作
程序 = 数据的存储 + 数据的操作 + 可以被计算机执行的语言
算法:
解题的方法和步骤
衡量算法的标准
1、 时间复杂度
大概程序要执行的次数,而非执行的时间
2、空间复杂度
算法执行过程中大概所占用的最大内存
3、难易程度(可读性)
4、健壮性
预备知识:
指针
结构体
动态内存的分配和释放
预备知识
模块一:线性结构
连续存储 数组
离散存储 链表
线性结构常见的两种应用 堆栈 、队列
堆属于分配内存的一种方式。
专题:递归
模块二:非线性结构 树 图
模块三: 查找和排序
二分法查找
排序:
冒泡、插入、 选择、快速排序、归并排序
模块四:Java中容器和数据结构相关知识
Iterator接口
Map
哈希表
指针:
定义
地址: 内存单元的编号
地址线 内存地址的编号访问内存地址单元
控制线 读 、写、 只读、只写
数据线
指针变量:是存放内存单元地址的变量
分类:
基本类型的指针
指针和数组的关系
C语言
int *p; p 是指针变量,表示该p变量只能存储 int 类型变量的地址
&取地址符
int i = 10 ;
int j ;
int *p; //p是个变量名字,只能存储int类型的地址
p = &i;
j = *p; // C语言中不能把不确定的值赋给变量
数组下标和指针的关系
a[i] = * (a + i);
a + 1 是指向下一个元素 偏移地址需要看数组中存储的数据类型。
在C语言中,如何通过被调函数修改主调函数中一维数组的内容?
两个参数:存放数组首元素的指针变量
存放数组元素长度的整型变量
int main(void)
{
double * p;
double x = 66.6;//x 占用8个字节,
p = &x;// p 存放第一个字节的地址。
printf("%p\n",p);//以十六进制输出
return 0
}
//指针变量占用字节数: 4
修改实参的值
int main(void)
{
int i = 10;
f(&i);
printf("i = %d\n",i)
return 0;
}
void f(int * p)
{
*p = 99;
}
结构体
为什么会出现结构体?
为了表示一些复杂的数据,而普通的基本类型变量无法满足。
结构体中只有属性没有方法。
什么叫结构体?
结构体是用户根据实际需求自己定义的数据类型
如何使用结构体
struct Student{
int age;
int num;
char name[200];
}
int main(void){
struct Student st ;// strcpy 访问属性
// st.name //error
struct Student * pst; //地址总线是32位,地址只占四个字节。一个字节8位。
pst = &st;
pst->age = 18;// 等价于(*pst).age 等价于st.age
return 0;
}
注意事项:
结构体变量可以相互赋值
普通结构体变量和结构体指针变量作为函数传参的问题
Java里用类来表示。
class Student{
int id;
String name;
int sage;
}
动态内存的分配和释放
int * pArr = (int *) malloc( sizeof(int) * len );
解释:malloc函数只有一个形参,传递一个整型变量。
(int*) 强制类型转换 只能返回第一个字节的地址,但是很困难确定变量占用几个字节 ,所以需要强制类型转换。
(int* )表示 第一个字节地址代表四个字节的地址。
free(pArr); // 把pArr所代表的的动态分配的20个字节内存释放。
模块一 : 线性结构【把所有的结点用一根直线穿起来】
连续存储【数组】
1、 什么叫数组
元素类型相同,大小相同
2、数组的优缺点:
底层实现数组:
//定义了一个数据类型,该数据类型的名字叫做Arr,有成员。
struct Arr
{
int * pBase;//存储的是数组第一个元素的地址
int len;// 数组所能容纳最大元素的个数
int cnt;// 当前数组有效元素的个数
int increment; // 自动增长因子
};
void init_arr(struct Arr * pArr,int length);
bool append(); //追加
bool insert_arr();
bool delete_arr();
int get();
bool is_empty(struct Arr * pArr);
bool is_full();
void sort_arr();
void show_arr(struct Arr * pArr);
void inversion_arr();
int main(void){
struct Arr arr;
init_arr(&arr,6);
// printf("%d\n",arr.len);
return 0;
}
void init_arr(struct Arr * pArr,int length)
{
// (* pArr).len = 99;
pArr->pBase = (int *)malloc(sizeof(int) * length);
if (NULL == pArr->pBase)
{
printf{"动态内存分配失败!\n");
exit(-1);
}
else
{
pArr->len = length;
pArr->cnt = 0;
}
return ;
}
bool is_empty(struct Arr * pArr)
{
if (0 == pArr->cnt)
return true;
else
return false;
}
void show_arr(struct Arr * pArr)
{
if (is_empty(pArr))
printf("数组为空"):
else
{
for(int i = 0; i<pArr->cnt;++i)
print("%d",pArr->pBase[i]);
}
}
离散存储【链表】