嵌入式学习DAY19 --- 数据结构开始学习(时间复杂度,顺序表)

本文是嵌入式学习的Day19笔记,主要探讨了数据结构的重要性,介绍了逻辑结构和存储结构的概念,并阐述了学习数据结构的方法。作者通过实例讲解了顺序表,包括创建、插入、删除、查找和排序等操作,并讨论了顺序表的动态扩容问题。此外,文章还涉及了算法的时间复杂度和顺序表代码实现。

嵌入式入门学习笔记,遇到的问题以及心得体会!
DAY19

1、什么是数据结构
1、数据结构就是研究数据元素之间关系的一门计算机的基础学科
2、数据结构主要是研究非数值性程序设计中计算机操作的对象(数据)及其相互间关系和运算的学科
在这里插入图片描述
在这里插入图片描述

逻辑结构:
在这里插入图片描述

存储结构:
在这里插入图片描述
在这里插入图片描述

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"

List *createlist()
{
	List *pList = (List *)malloc(sizeof(List));
	if(NULL == pList)
	{
		return NULL;
	}
	memset(pList,0,sizeof(List));

	//给data赋值,让data指向一块连续的内存空间
	pList->size = SIZE;
	pList->data = (data_t *)malloc(sizeof(data_t)*pList->size);
	if(NULL == pList->data)
	{
		return NULL;
	}
	memset(pList->data, 0, sizeof(data_t)*pList->size);
	return pList;
}

int insert_list_item(List *pList,int ioffset,data_t tdata)
{
	if(NULL == pList || ioffset < 0 || ioffset > pList->size)
	{
		printf("1111\n");
		return LIST_ERROR;
	}
	
	//当表满的时候,需要实现扩容
	if(pList->size == pList->count)
	{
		//先保存一下原来的size
		int size = pList->size;
		//申请一块更大的空间
		pList->size += 5;
		data_t *pTmp = (data_t *)malloc(sizeof(data_t) * pList->size);
		if(NULL == pTmp)
		{
		    printf("222\n");
			return LIST_ERROR;
		}
		memset(pTmp, 0, sizeof(data_t)*pList->size);
        //将原来小的空间的内容拷贝到新的空间
		memcpy(pTmp, pList->data, sizeof(data_t)*size);

		//将原来的空间释放
		free(pList->data);
		//使得data指向新的空间
		pList->data = pTmp;
	}
	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;
}

int delete_list_item(List *pList,int ioffset,data_t *pdata)
{
	if(NULL == pList || ioffset < 0 || ioffset > pList->count || NULL ==pdata || 0 == pList->count)
	{
		return LIST_ERROR;
	}
	*pdata = pList->data[ioffset];
	int i;
	for(i = ioffset;i < pList->count - 1;i++)
	{
		pList->data[i] = pList->data[i+1];
	}
	pList->count--;
	return LIST_OK;
}

int update_list_item(List *pList,data_t oldata,data_t newdata)
{
	if(NULL == pList)
	{
		return LIST_ERROR;
	}
	int i;
	for(i = 0;i < pList->count;i++)
	{
		if(pList->data[i] == oldata)
		{
			pList->data[i] = newdata;
		}
	}
	return LIST_OK;
}

int search_list_item(List *pList,data_t tdata,int *pindex)
{
	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 sort_list(List *pList)
{
	if(NULL == pList)
	{
		return LIST_ERROR;
	}
	int i, j;
	for(i = 0; i < pList->count-1; i++)
	{
		for(j = 0; j < pList->count-i-1; j++)
		{
			if(pList->data[j] > pList->data[j+1])
			{
				data_t tmp = pList->data[j];
				pList->data[j] = pList->data[j+1];
				pList->data[j+1] = tmp;
			}
		}
	}
	return LIST_OK;
}

void show_list(List *pList)
{
	if(NULL == pList)
	{
		return;
	}
	int i;
	for(i = 0;i < pList->count;i++)
	{
		printf("%d\t",pList->data[i]);
	}
	puts("");
}

void destroy_list(List **pplist)
{
	if(NULL == pplist || NULL == *pplist)
	{
		return;
	}
	free(*pplist);
	*pplist = NULL;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值