表的结构
#define MAXSIZE 20
#define listData uint32_t
typedef struct list_t {
listData data;
struct list_t* next;
} list_t;
常用方法
- list_init:初始化,建立一个空表
- list_uninit:free整个链表
- list_clear:清空当前表
- list_insert_head:从表头插入数据
- list_insert_tail:从表尾部插入数据
- list_insert:插入一个数据,index = 2,则会替换掉原来的2,原来的2变成3
- list_delete:删除指定位置的节点
- list_merge:合并2个表
- list_reverse:逆序
- list_display:打印表数据
实现代码
list.h
#ifndef __LIST_H__
#define __LIST_H__
#include <stdint.h>
#include <stdbool.h>
#define OK 0x0000
#define ERROR 0xFFFF
#define MAXSIZE 20
#define listData uint32_t
typedef struct list_t {
listData data;
struct list_t* next;
} list_t;
list_t* list_init(); /* 构建头指针 */
void list_uninit(list_t** s_p_list); /* free整个链表 */
void list_clear(list_t* p_list);
uint32_t list_insert_head(list_t* p_list, listData data); /* 从表头插入数据 */
uint32_t list_insert_tail(list_t* p_list, listData data); /* 从表尾部插入数据 */
uint32_t list_insert(list_t* p_list, uint32_t index, listData data); /* index = 2,则会替换掉原来的2,原来的2变成3 */
uint32_t list_delete(list_t* p_list, uint32_t index); /* 删除指定位置的节点 */
uint32_t list_merge(list_t* p_list, uint32_t index, list_t* p_list_2); /* 在list_1指定节点之后拼接上List_2 */
void list_reverse(list_t* p_list);
void list_display(list_t* p_list); /* 遍历链表 */
#endif // __LIST_H__
list.c
#include "list.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
list_t* list_init() {
list_t* p_list = (list_t*)malloc(sizeof(list_t));
if (p_list != NULL) {
memset(&p_list->data, 0x00, sizeof(listData));
p_list->next = NULL;
}
return p_list; /* 返回头指针 */
}
void list_uninit(list_t** s_p_list) {
if (s_p_list == NULL || *s_p_list == NULL) {
return;
}
/* 清空链表所有数据 */
list_t* p = (*s_p_list)->next;
list_t* q = NULL;
while (p != NULL) {
q = p->next;
free(p);
p = q;
}
/* free掉头指针 */
free(*s_p_list);
*s_p_list = NULL;
}
void list_clear(list_t* p_list) {
list_t* p = p_list->next; /* 指向第一个节点 */
list_t* q = NULL; /* 中转 */
/* p != NULL的时候,表示一直还有后续的节点存在 */
while (p != NULL) {
q = p->next; /* q临时记录一下,p的下一个节点的位置 */
free(p); /* 释放当前节点p */
p = q; /* p继续指向自己的下一个节点 */
}
p_list->next = NULL;
/* 清空,没有删除掉头指针的,还可以继续利用p_list来操作链表 */
}
uint32_t list_insert_head(list_t* p_list, listData data) {
/* 创建一个节点,将数据放置进去 */
list_t* newNode = (list_t*)malloc(sizeof(list_t));
if (newNode == NULL) {
return ERROR;
}
memcpy(&newNode->data, &data, sizeof(listData));
newNode->next = NULL;
/* 插入为第一个节点 */
newNode->next = p_list->next;
p_list->next = newNode;
return OK;
}
uint32_t list_insert_tail(list_t* p_list, listData data) {
/* 创建一个节点,将数据放置进去 */
list_t* newNode = (list_t*)malloc(sizeof(list_t));
if (newNode == NULL) {
return ERROR;
}
memcpy(&newNode->data, &data, sizeof(listData));
newNode->next = NULL;
/* 找到最后一个节点的位置 */
list_t* p = p_list; /* 头指针 */
while (p->next != NULL) {
p = p->next;
}
/* 插入为最后一个节点 */
newNode->next = p->next;
p->next = newNode;
return OK;
}
uint32_t list_insert(list_t* p_list, uint32_t index, listData data) {
if (index <= 0) {
/* 节点从1开始,0属于无效节点 */
return ERROR;
}
/* 查找插入的位置 */
uint32_t i = 1; /* 从第一个节点开始 */
list_t* p = p_list; /* 指向头指针 */
while (p != NULL && i < index) {
/* 当前节点不为NULL,且当前节点数仍小于被插入的位置,则继续遍历 */
p = p->next; /* 指向下一个节点 */
i++; /* 节点数++ */
}
/* 遍历完成,检查有效性,如果p为NULL的话,说明index超过链表长度了,无法插入 */
if (p == NULL) {
return ERROR;
}
/* 创建一个节点,将数据放置进去 */
list_t* newNode = (list_t*)malloc(sizeof(list_t));
if (newNode == NULL) {
return ERROR;
}
memcpy(&newNode->data, &data, sizeof(listData));
newNode->next = NULL;
/* 从找到的位置的后面插入到链表 */
newNode->next = p->next;
p->next = newNode;
return OK;
}
uint32_t list_delete(list_t* p_list, uint32_t index) {
if (index <= 0) {
return ERROR;
}
/* 找到这个节点的前一个节点 */
uint32_t i = 1;
list_t* p = p_list;
while (p != NULL && i < index) {
p = p->next;
i++;
}
if (p == NULL) {
return ERROR;
}
list_t* q = p->next; /* 记录当前节点的下一个节点位置 */
p->next = q->next;
free(q);
return OK;
}
uint32_t list_merge(list_t* p_list, uint32_t index, list_t* p_list_2) {
if (index <= 0) {
return ERROR;
}
/* 找到p_list要插入的位置 */
uint32_t i = 1;
list_t* p = p_list->next;
while (p != NULL && index < i) {
p = p->next;
i++;
}
if (p == NULL) {
return ERROR;
}
/* 找到p_list_2的最后一个节点的位置 */
list_t* p2 = p_list_2;
while (p2->next != NULL) {
p2 = p2->next;
}
p2->next = p->next;
p->next = p_list_2->next;
p_list_2->next = NULL; // list_2没有节点了,next = NULL
return OK;
}
void list_reverse(list_t* p_list) {
/* 逆序,原第一个节点是不需要动的,只需要最终将next = NULL即可 */
node_t* temp = NULL;
node_t* p = list_head->next; /* 头节点 */
while (p != NULL && p->next != NULL) {
temp = p->next; /* 当前节点的下一个节点,temp这个节点就可以移动了 */
p->next = temp->next;
temp->next = list_head->next;
list_head->next = temp;
}
}
void list_display(list_t* p_list) {
list_t* p = p_list->next; /* 指向第一个节点 */
int i = 1; /* 节点计数 */
while (p != NULL) {
printf("node[%d].data = %d\n", i, p->data);
p = p->next;
i++;
}
}
测试代码 main.c
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
int main(int argc, char const *argv[])
{
list_t* list_head = list_init();
list_insert(list_head, 1, 10); // 10
list_insert(list_head, 2, 20); // 10 20
list_insert(list_head, 2, 30); // 10 30 20
list_insert(list_head, 3, 40); // 10 30 40 20
list_insert_head(list_head, 1); // 1 10 30 40 20
list_insert_head(list_head, 2); // 2 1 10 30 40 20
list_insert_head(list_head, 3); // 3 2 1 10 30 40 20
list_insert_tail(list_head, 100); // 3 2 1 10 30 40 20 100
list_insert_tail(list_head, 200); // 3 2 1 10 30 40 20 100 200
list_insert_tail(list_head, 300); // 3 2 1 10 30 40 20 100 200 300
list_delete(list_head, 1); // 2 1 10 30 40 20 100 200 300
list_delete(list_head, 2); // 2 10 30 40 20 100 200 300
list_delete(list_head, 3); // 2 10 40 20 100 200 300
list_t* list_head_2 = list_init();
list_insert(list_head_2, 1, 1000); // 1000
list_insert(list_head_2, 2, 2000); // 1000 2000
list_insert(list_head_2, 2, 3000); // 1000 3000 2000
list_merge(list_head, 2, list_head_2); // 2 1000 3000 2000 10 40 20 100 200 300
// list_clear(list_head);
list_display(list_head);
// list_display(list_head_2);
list_reverse(list_head);
list_display(list_head); // 300 200 100 20 40 10 2000 3000 1000 2
list_uninit(&list_head);
list_uninit(&list_head_2);
return 0;
}