文章目录
数据
- 数据包含数据对象
- 数据对象是数据元素的集合
- 数据元素是数据的基本单位,有若干个数据项组成,数据项是数据元素的不可分割的最小单位
2.数据结构分为逻辑结构和物理结构
数据之间的结构:(数据元素之间的关系,逻辑结构)
- 集合结构:数据元素不能重复
- 线性结构:1:1
- 树形结构:1:N
- 网状结构或图状结构:N:M
物理结构:(存储结构)是指数据的逻辑结构在计算机中的存储形式
- 顺序存储结构
把数据元素存放在地址连续的存储单元中,数据间的逻辑结构和物理关系是一致的 - 链式存储结构
把数据元素存放在任意的存储单元里,可以连续也可以不连续,不能反映其逻辑关系,因此需要一个指针存放数据元素的地址
线性表
1.特点:
存在唯一的一个被称为"第一个"的数据元素
存在唯一的一个被称为"最后一个"的数据元素
除第一个之外,集合中的每个数据元素均只有一个前驱
除最后一个之外,集合中每个数据元素均只有一个后继
- 线性表中的元素是一对一的
- 线性表中的元素是连续的
- 线性表中的数据元素是有同一类性质的元素
typedef 起别名
1.概念:把一切合法的变量定义或声明转换成类型声明
typedef unsigned char u_int8;
typedef int Array[10];//Array整形数组类型 开辟十个空间
int main()
{
Arrar ar = {
13,23,45,56} ,br= {
1,2,3};
u_int8 a,b;
3.typedef 与 struct
#define SEQ_INIT_SIZE 10
struct SeqList
{
//定义SeqList结构体类型
ElemType data[SEQ_INIT_SIZE];
int cursize;
};
int main()
{
//使用时前面必须要加上struct
struct SeqList myseq;
struct SeqList *pseq;
}
typedef struct
{
ElemType data[SEQ_INIT_SIZE];
int cursize;
}SeqList; //将SeqList变量变成SeqList类型
int main()
{
//在使用时不需要写struct
SeqList myseq;
SeqList *pseq;
}
定义固定大小的数组缺陷:
1.定义的空间在栈上开辟,栈的大小只有1M
2.大开小用
char 1;short 2;int 4;long int 4; long long 8
float 4;double 8; bool 1
1字节(存储单元)有8个bit
函数内定义的变量都在栈区;全局变量、静态变量、静态局部变量在数据区;malloc,new的变量在堆区
- 初始化时传的是地址 void InitSeqList(SeqList *plist)
{//如果定义的(SeqList plist)会出现 内存泄漏 值传递(未改变主函数中的值)
线性表
顺序表:
1.逻辑相邻,物理相邻
2.随机访问时间复杂度O(1)
3.插入时间复杂度O(n) 尾插时间复杂度O(1)
4.删除时间复杂度O(n) 尾删时间复杂度O(1)
5.查找Search时间复杂度O(n)单链表:
1.逻辑相邻,物理上不一定相邻
2.随机访问时间复杂度O(n)
3.插入时间复杂度O(1) 不需要挪动数据
4.删除时间复杂度O(1) 不需要挪动数据
5.查找Search时间复杂度O(n)
//for(p = plist; p->next != nullptr; p = p->next);//需要前驱 插入和删除操作等
//for(p = plist->next; p != nullptr; p = p->next);//不需要前驱,打印、查找操作等
//插入操作
pnewnode->next=p->next;p->next=pnewnode;
//删除操作
Node* q=p->next;p->next=q->next;free(q); p是删除节点的前驱 q是删除节点
*/
顺序表
- 顺序表 :权限更多的数组 逻辑相邻 物理上也相邻
插入 删除 判空 判满 获取长度 清空 销毁
#include<stdio.h> 库函数自带的头文件
#include"sqlist.h" 用户自己定义的头文件
typedef struct SQlist //定长顺序表
{
int data[10];
int length;
}SQList,*PSQlist;
typedef struct DSQlist //不定长顺序表
{
//需要扩容
int *data; //存储空间基址
int length; //当前长度(有效长度个数)
int listsize;//当前分配的存储容量(总的格子数)
}DSQList,*DPSQlist;
void Init_list(PDSQlist ps)//初始化函数
{
assert(ps != nullptr);
if (nullptr == ps)
{
return;
}
ps->data = (int*)malloc(sizeof(int) * INIT_SIZE);
assert(ps->data != nullptr);
ps->length = 0;
ps->listsize = INIT_SIZE;
}
void Inc(PDSQlist ps) //扩容
{
//malloc calloc realloc
ps->data = (int*)realloc(ps->data, sizeof(int) * ps->listsize*2);
//ps->length 不改 有效长度个数
ps->listsize *= 2;
}
void Destroy(PDSQlist ps) //销毁顺序表
{
free(ps->data);
ps->data = nullptr;
ps->length = 0;
ps->listsize = 0;
}
- 特点:
1.简单
2.随机访问数据时间复杂度O(1)
3.插入数据时间复杂度为O(n) 尾插时间复杂度为O(1)
4.插入和删除要挪动大量数据
链表
2.链表 :逻辑相邻 物理上不一定相邻
不需要挪动数据
数值域
指针域
void Swap(int *a,int *b) //交换函数
{
int tmp = *a;
*a = *b
*b = tmp;
}
void Swap(int &a,int &b)
{
int temp = a;
a = b;
b = temp;
}
单链表
1.带头节点(实现简单)
2.不带头结点 (头指针 出现二级指针)
头节点是在栈区开辟的不需要释放,而数据节点是在堆区,malloc开辟的空间,销毁单链表需要释放掉全部数据节点
typedef int ELEMTYPE;
typedef struct Node
{
ELEMTYPE data; 数据域
struct Node* next;指针域
}Node,*PNode;
//Node * = PNode
- 插入
单链表插入新节点首先要将新节点的next域指向之前上一个节点的next域,能够保证后边节点不丢失,再将上一个节点的next域指向新节点
//头插 头节点之后
bool Insert_head(Node* plist, int val)
{
assert(plist != nullptr);
Node *newnode = (Node *)malloc(sizeof(Node) * 1);
assert(newnode != nullptr);
newnode->data = val;
newnode->next = plist->next; //1
plist->next = newnode; //2 顺序不能变
return true;
}
//尾插
bool