嵌入式学习第二十九天!(数据结构的概念、单向链表)

数据结构:

1. 定义:

一组用来保存一种或者多种特定关系的数据的集合(组织和存储数据)

1. 程序设计:

将现实中大量而复杂的问题以特定的数据类型和特定的数据结构存储在内存中,并在此基础上实现某个特定的功能的操作(程序 = 数据结构 + 算法)

**高内聚:**一个功能模块只干一件事

**低耦合:**功能模块与功能模块之间的耦合度要低

**可读性:**程序需要添加注释

**健壮性:**程序在运行过程中不能产生异常

2. MVC软件设计架构:

M:mode,数据的管理(数据结构)

V:view,视图,数据的反映及人机交互

C:ctrl,逻辑控制

2. 数据与数据之间的关系

1. 数据的逻辑结构:数据元素与元素之间的关系

集合:关系平等

**线性结构:**元素之间一对一的关系(表(数组、链表)),队列,栈)

**树形结构:**元素之间一对多的关系(二叉树)

图形结构:元素之间多对多的关系(网状结构)

2. 数据的物理结构:数据的逻辑结构在计算机内存中的存储形式

1. 顺序存储:

采用一段连续的内存空间保存元素

**优点:**数据访问方便

**缺点:**1. 数据插入删除需要移动大量的元素

  1. 需要预分配内存空间

  2. 容易造成存储空间碎片

2. 链式存储:

采用一种非连续的内存空间保存元素

**优点:**1. 插入删除数据效率高

  1. 不需要预分频内存

**缺点:**访问元素必须遍历,效率低

3. 索引存储:

通过关键字构建索引表,通过索引表来找到数据的存储位置

4. 散列存储(哈希存储):

将数据元素的存储位置与关键码之间建立确定对应关系从而实现查找的存储方式

索引存储和散列存储都是为了提高数据的查找速度

单向链表:

1. 有头链表:

第一个链表节点中不存储有效数据

嵌入式学习第十五天!(内存管理、链表)-CSDN博客

2. 无头链表:

第一个链表结点中存储有效数据

1. 定义无头链表的句柄和结点:

cpp 复制代码
#ifndef _LINK_H_
#define _LINK_H_

typedef int DATA_TYPE;

typedef struct node
{
	DATA_TYPE data;
	struct node *pnext;

}LINK_NODE;


typedef struct list
{
	LINK_NODE *phead;
	int curlen;

}LINK_LIST;

#endif

说明其中struct node还未定义的时候就用struct node *定义pnext:因为不管是char *还是int *等还是struct node *都是指针类型,它都占8个字节,但是如果不加*,那么系统就不知道结构体构建的内存空间的大小,所以就会报错。

2. 创建无头链表:

cpp 复制代码
LINK_LIST *Create_Link(void)
{
	LINK_LIST *plist = malloc(sizeof(LINK_LIST));
	if(plist == NULL)
	{
		return NULL;
	}

	plist->phead = NULL;
	plist->curlen = 0;

	return plist;
}

3. 头插法:

cpp 复制代码
int Push_Head_Link(LINK_LIST *plist, DATA_TYPE data)
{
	LINK_NODE *pnode = malloc(sizeof(LINK_NODE));
	if(pnode == NULL)
	{
		return -1;
	}

	pnode->data = data;
	pnode->pnext = NULL;

	pnode->pnext = plist->phead;
	plist->phead = pnode;

	plist->curlen++;

	return 0;
}

4. 尾插法:

cpp 复制代码
int Push_Tail_Link(LINK_LIST *plist, DATA_TYPE data)
{
	LINK_NODE *pnode = malloc((sizeof(LINK_NODE)));
	if(pnode == NULL)
	{
		return -1;
	}
	
	pnode->data = data;
	pnode->pnext = NULL;

	LINK_NODE *ptmp = plist->phead;
	if(ptmp == NULL)
	{
		ptmp = pnode;
	}
	else
	{
		while(ptmp->pnext != NULL)
		{
			ptmp = ptmp->pnext;
		}
		ptmp->pnext = pnode;
	}
	plist->curlen++;

	return 0;
}

5. 遍历:

cpp 复制代码
int list_for_each(LINK_LIST *plist)
{
	LINK_NODE *ptmp = plist->phead;

	while(ptmp != NULL)
	{
		printf("%d ", ptmp->data);
		ptmp = ptmp->pnext;
	}
	printf("\n");

	return 0;
}

6. 尾删法:

cpp 复制代码
int Pop_Tail_Link(LINK_LIST *plist)
{
	LINK_NODE *ptmp = plist->phead;

	if(ptmp == NULL)
	{
		return 0;
	}
	else if(ptmp->pnext == NULL)
	{
		free(ptmp);
		plist->phead = NULL;
	}
	else
	{
		while(ptmp->pnext->pnext == NULL)
		{
			ptmp = ptmp->pnext;
		}
		free(ptmp->pnext);
		ptmp->pnext = NULL;
	}

	plist->curlen--;

	return 0;
}

7. 头删法:

cpp 复制代码
int Pop_Head_Link(LINK_LIST *plist)
{
	LINK_NODE *ptmp = plist->phead;

	if(ptmp == NULL)
	{
		return 0;
	}
	else if(ptmp->pnext == NULL)
	{
		free(ptmp);
		plist->phead = NULL;
	}
	else
	{
		plist->phead = plist->phead->pnext;
		free(ptmp);
	}
	plist->curlen--;

	return 0;
}

8. 查找:

cpp 复制代码
LINK_NODE *Find_Link_Node(LINK_LIST *plist, DATA_TYPE data)
{
	LINK_NODE *ptmp = plist->phead;
	
	while(ptmp != NULL)
	{
		if(ptmp->data == data)
		{
			return ptmp;
		}
		ptmp = ptmp->pnext;
	}

	return NULL;
}

9. 修改:

cpp 复制代码
int Replace_link_data(LINK_LIST *plist, DATA_TYPE olddata, DATA_TYPE newdata)
{
	LINK_NODE *ptmp = plist->phead;

	while(ptmp != NULL)
	{
		if(ptmp->data = olddata)
		{
			ptmp->data = newdata;
		}
		ptmp = ptmp->pnext;
	}

	return 0;
}

10. 销毁:

cpp 复制代码
int Destroy_Link(LINK_LIST *plist)
{
	LINK_NODE *ptmp = plist->phead;
	LINK_NODE *pfree = plist->phead;

	while(ptmp != NULL)
	{
		ptmp = ptmp->pnext;
		free(pfree);
		pfree = ptmp;
	}
	free(plist);

	return 0;
}

在链表用完以后需要销毁,是为了防止内存泄露(内存空间完全被占用,没有内存可以分配),可以利用valgrind判断是否发生内存泄露。

bash 复制代码
sudo apt-get install valgrind
valgrind ./a.out

malloc7次,释放7次,所以并没有发生内存泄露

相关推荐
霍格沃兹测试开发学社测试人社区14 分钟前
软件测试学习笔记丨Flask操作数据库-数据库和表的管理
软件测试·笔记·测试开发·学习·flask
今天我又学废了31 分钟前
Scala学习记录,List
学习
XuanRanDev1 小时前
【每日一题】LeetCode - 三数之和
数据结构·算法·leetcode·1024程序员节
代码猪猪傻瓜coding1 小时前
力扣1 两数之和
数据结构·算法·leetcode
王俊山IT1 小时前
C++学习笔记----10、模块、头文件及各种主题(一)---- 模块(5)
开发语言·c++·笔记·学习
Mephisto.java2 小时前
【大数据学习 | kafka高级部分】kafka中的选举机制
大数据·学习·kafka
南宫生2 小时前
贪心算法习题其三【力扣】【算法学习day.20】
java·数据结构·学习·算法·leetcode·贪心算法
weixin_432702263 小时前
代码随想录算法训练营第五十五天|图论理论基础
数据结构·python·算法·深度优先·图论
武子康3 小时前
大数据-212 数据挖掘 机器学习理论 - 无监督学习算法 KMeans 基本原理 簇内误差平方和
大数据·人工智能·学习·算法·机器学习·数据挖掘
使者大牙3 小时前
【大语言模型学习笔记】第一篇:LLM大规模语言模型介绍
笔记·学习·语言模型