链表、栈和队列
1、malloc()和free()
定义:
#include <stdlib.h> //malloc在这头文件
/malloc动态申请size个字节
的内存空间/
void *malloc(size_t size);
/calloc: 申请nmembsize个字节的内存空间,并将内存内容全部置为0*/
void *calloc(size t nmemb,size t size);
/调整之前动态申请的内存大小,并将原有数据从头到尾拷贝到新分配的内存区域/
void *realloc(void *ptr, size t newsize);
/释放alloc()申请的内存空间*/
void free(void *ptr);
代码演示:
#include <stdio.h>
#include<stdlib.h>
int main()
{
char *ptr;
ptr = malloc(10); //分配10个字节内存空间
memset(ptr, 0, 10); //memset法设置内容0
ptr = calloc(10,1); //calloc法设置内容0
realloc(ptr 100);
free(ptr);
}
- 申请的malloc内存在堆区。
- 申请较大的内存时,要知道用共享内存的mmap映射映射一段内存空间,而不是用malloc。
- free:如果不free,会一直在堆区分配空间,会把栈区都覆盖,程序就会挂掉,然后退出后。程序退出后就不存在内存泄漏,内存会被系统重新收回,下一个进程运行时又可以使用这段内存空间。内存泄漏只是在程序运行时存在。
2、链表、栈、队列
链表
1. 链表原理图
注意:
- 这段空间不一定是按顺序分配的,只是通过链表连接起来。
2. 链表的使用
代码实现:
typedef struct _st_node
{
int data;
struct _st_node *next;
} st_node;
注意:
- 结构体不能嵌套定义,也不可以自包含。
错误示范:
struct test
{
int data;
struct test b; //不能确定test的大小,死循环
}
正确示范:
struct test
{
int data;
struct test *b; //b是一个指针,知道大小
}
3. 带头节点/不带头节点
4. 头/尾插法
- 头插法:实行栈
- 尾插法:实行队列
代码实现:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define LIST_HEAD_INSERT
typedef struct _st_node
{
int data;
struct _st_node *next;
} st_node;
int main()
{
st_node *head = NULL;
st_node *new_node;
st_node *tail;
int i;
for(i = 0; i < 10; i++)
{
new_node = malloc(sizeof(st_node));
memset(new_node, 0, sizeof(*new_node));
new_node->next = NULL;
new_node->data = i+1;
#ifdef LIST_HEAD_INSERT
if(head == NULL)
{
head = new_node;
}
else
{
tail->next = new_node;
}
tail = new_node;
#else
new_node->next = head;
head = new_node;
#endif
}
st_node *node = NULL;
for(node = head; node != NULL; node = node->next)
{
printf("%d\n", node->data);
}
}
5. 数组和链表的区别
- 数组在访问时可通过下标访问,效率更高,可浪费更多内存空间。
- 链表节省内存空间,但访问时间更长一点,因为要遍历整个链表。
栈
1. 栈原理示意图
代码实现:
队列
1. 队列的两种实现方式
- 队列是一种“先进先出的数据结构FIFO”,数据从rear中入队列,从front中读出。队列的存储可以由数组和链表两种方式实现。
2. 队列循环buffer原理图
3. 循环队列的使用
-
将地址线性增长的数组抽象成环形。
rear=(rear+1)%rb size; -
判断循环buffer是否为空或满。
空条件:rear == front
满条件:(rear + 1) % rb_size == front
(空一个存储单位不存储数据)
(rb_size:队列的大小) -
判断buffer中数据大小
(rear + rb_size - front) % rb_size