收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人
都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
逻辑结构:
存储结构:
2、为什么要学习数据结构
以前我们在c语言程序,只需要想着我只要实现题目要求的功能就可以了,数据结构研究的是如何让程序运行起来更加高效,数据在内存中的操作更加流畅。
3、学习数据结构的方法
数据结构的特点:
1、比较抽象,对逻辑思维能力要求较高
2、代码量比较大
学习方法:
1、学会画图,将脑袋中抽象的东西画出来,变成具体的步骤
2、带着自己的思考敲代码
1、照着老师的代码敲(在敲的过程中,要思考每一行代码是在干什么,把对应注释写上)
2、自己尝试敲,重复,直到自己可以不看别人的代码,按照自己的思考敲出来
3、慢,自己的节奏,一点一点突破
4、什么是算法—时间复杂度
算法:解决问题的步骤的集合
算法的特点:1、可行性 2、有穷 3、与具体的计算机无关 3、确定性
程序=数据结构+算法
衡量一个算法的好坏:语句执行的次数(T(n))
int main()
{
Printf(“hello world”); T(n) = 1 T(n) = O(1)
}
Int main()
{
Printf(“hello world”);
Printf(“hello world”); T(n) = 2; T(n) = O(1)
}
void fun(int n)
{
Int i; 1
For(i = 0; i < n; i++) 1 n+1 n
{
Printf(“hello world”); n
}
}
T(n) = 1+1+n+1+n+n = 3n+3 T(n) = 0(n)
5、顺序表 — 敲代码
1、顺序表的三个方面:
逻辑结构:线性结构—一对一
存储结构:顺序存储—数据元素和元素之间在内存中是连续的
运算:创建 增加 删除 查找 修改 排序 销毁
也就是:顺序表就是一块连续的内存空间,我们要实现的是对这块连续内存空间增删改查的操作
创建:就是申请一块连续的内存空间,然后将这块连续的内存空间的首地址返回
插入操作:
删除操作:
代码展示:
关于实现一个顺序表的功能步骤
第一步:首先编辑一个list.h文件
#ifndef \_LIST\_H\_
#define \_LIST\_H\_
typedef int data_t;
#define SIZE 5
/\*
\* 创建一个顺序表
\* 增加一个元素
\* 删除一个元素
\* 修改元素的值
\* 查找
\* 排序
\* 销毁
\*/
//通过该结构体来描述顺序表
typedef struct List
{
data_t data[SIZE];
int count; //当前顺序表的元素个数(插入了多少个元素)
}List;
enum LIST_OP
{
LIST_ERROR = -1,
LIST_OK,
NOT_FOUND
};
List\* createList();
int insertItemList(List \*pList, int iOffset, data_t tData);
int deleteItemList(List \*pList, int iOffset, data_t \*pData);
int updateList(List \*pList, data_t oldData, data_t newData);
int searchItemList(List \*pList, data_t tData, int \*pIndex);
int sortList(List \*pList);
void destroyList(List \*\*ppList);
void showList(List \*pList);
#endif //防止头文件重复包含
第二步:编辑一个list.c文件,用来具体编写各个功能如何实现
#include<stdio.h>
#include <stdlib.h>
#include <string.h>
#include "list.h"
/\*功能:创建一个顺序表
\* 返回值:成功 顺序表的首地址
\* 失败:NULL
\*/
List \*createList()
{
List \*pList = (List \*)malloc(sizeof(List));
if(NULL == pList)
{
return NULL;
}
memset(pList, 0, sizeof(List));
return pList;
}
/\*
\* 功能:给顺序表插入一个元素
\* 参数:pList 顺序表的首地址
\* iOffset 插入的位置
\* tData 插入的值
\*返回值:成功 LIST\_OK
失败 LIST\_ERROR
\*/
int insertItemList(List \*pList, int iOffset, data_t tData)
{
if(NULL == pList || iOffset < 0 || iOffset >= SIZE || SIZE == pList->count)
{
return LIST_ERROR;
}
//根据iOffset将tData插入
int i;
for(i = pList->count-1; i >= iOffset; i--)
{
pList->data[i+1] = pList->data[i];
}
pList->data[iOffset] = tData;
pList->count++;
return LIST_OK;
}
/\*
\* 功能:删除一个元素
\* 参数:pList 首地址
\* iOffset 删除的位置
\* pData 保存删除的元素
\*返回值:成功 LIST\_OK
失败 LIST\_ERROR
\*/
int deleteItemList(List \*pList, int iOffset, data_t \*pData)
{
if(NULL == pList || iOffset < 0 || iOffset >= SIZE || NULL == pData || 0 == pList->count)
{
return LIST_ERROR;
}
//保存要删除的值
\*pData = pList->data[iOffset];
//删除:用后面的元素把前面的覆盖掉,count--
int i;
for(i = iOffset; i < pList->count-1; i++)
{
pList->data[i] = pList->data[i+1];
}
pList->count--;
return LIST_OK;
}
int updateList(List \*pList, data_t oldData, data_t newData)
{
if(NULL == pList)
{
return LIST_ERROR;
}
//一旦发现顺序表中元素的值等于oldData就换成newData
int i;
for(i = 0; i < pList->count; i++)
{
if(pList->data[i] == oldData)
{
pList->data[i] = newData;
}
}
return LIST_OK;
}
int searchItemList(List \*pList, data_t tData, int \*pIndex)
{
//查找tData,如果找到了,就将这个元素的下标赋值给\*iIndex
//如果没有找到,就返回NOT\_FOUND
if(NULL == pList || NULL == pIndex)
{
return LIST_ERROR;
}
int i;
for(i = 0; i < pList->count; i++)
{
if(pList->data[i] == tData)
{
\*pIndex = i;
return LIST_OK;
}
}
return NOT_FOUND;
}
int sortList(List \*pList)
{
}
void destroyList(List \*\*ppList)
{
if(NULL == ppList || NULL == \*ppList)
{
return;
}
free(\*ppList);
\*ppList = NULL;
}
void showList(List \*pList)
{
if(NULL == pList)
{
return;
}
int i;
for(i = 0; i < pList->count; i++)
{
printf("%d ", pList->data[i]);
}
printf("\n");
}
第三步:编辑一个main.c文件用来具体实现如何调用
#include<stdio.h>
#include "list.h"
int main()
{
List \*pList = createList();
if(NULL == pList)
{
printf("创建失败!\n");
return -1;
}
int i, ret;
for(i = 0; i < 3; i++)
{
ret = insertItemList(pList, i, i+100);
if(LIST_ERROR == ret)
{
printf("插入失败!\n");
return -1;
}
}
showList(pList);
ret = insertItemList(pList, 0, 888);
if(LIST_ERROR == ret)
{
printf("插入失败!\n");
return -1;
}
showList(pList);
data_t data;
deleteItemList(pList, 2, &data);
printf("删除的元素:%d\n", data);
showList(pList);
updateList(pList, 888, 999);
showList(pList);
printf("请输入要查找的数据:");
scanf("%d", &data);
int index;
ret = searchItemList(pList, data, &index);
if(NOT_FOUND == ret)
{
printf("没有找到!\n");
}
else
{
printf("查找的结果是:%d\n", index);
}
//destroy之后pList就变成了NULL
destroyList(&pList);
return 0;
}
扩展:
我们讲的顺序表的大小是固定的,最多只能是5个元素,那么能不能进行扩容呢?
也就是就算满了,我再继续插入也是可以的
顺序表的动态扩容
现在遇到的问题:原来的空间不够用了,会导致插入失败
解决办法:申请一块更大的空间,把原来小的空间的内容全部拷贝到新的空间,把要插入的数据插入到新的空间,将原来旧的空间给释放掉
Insert()
{
如果顺序表满了,就申请更大的空间
也就是data的大小变化了
}
回忆昨天的顺序表是如何定义的:
Struct List
{
Data_t data[SIZE];
Int count;
};
但是data_t data[SIZE];这个数组大小没办法改变,因为data是数组名,是常量,没办法修改
所以结构体需要重新定义
Struct List
{
Data_t \*data; //首地址
Int count; //元素的个数
Int size; //数组的容量
};
基础代码同上方差不多,我在这只贴出来list.c的代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "list.h"
**收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。**


**[如果你需要这些资料,可以戳这里获取](https://gitee.com/vip204888)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人**
**都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**