list.c
2018-05-02 本文已影响0人
cybersword
#include <stdio.h>
#include <stdlib.h>
/* 定义结点 `struct node` 是一个数据类型 类似 `int` */
struct node {
/* 结点的数据 */
int id;
/* 结点的后继指针 */
struct node* next;
};
/* 从给定结点开始删除之后的num个结点 返回实际删除的个数 */
int del_node(struct node* p_node, unsigned int num)
{
unsigned int n_del = 0;
struct node* p_cur = NULL;
while (n_del < num && p_node->next) {
n_del++;
p_cur = p_node->next;
p_node->next = p_cur->next;
/* 这里视情况释放结点的内存 */
free(p_cur);
}
return n_del;
}
/* 创建一个结点 分配内存和赋值 */
struct node* create_node(int id)
{
struct node* p_node = (struct node*)malloc(sizeof(struct node));
p_node->id = id;
p_node->next = NULL;
return p_node;
}
/* 创建包含 num 个结点的链表 并初始化 id */
struct node* create_list(int* id_list, unsigned int num)
{
if (id_list == NULL || num == 0) {
return NULL;
}
/* 创建链表头结点,并用一个指针指向头结点 */
struct node* p_head = create_node(id_list[0]);
/* 当前处理的结点 */
struct node* p_node = p_head;
/* 创建头结点以外的结点,并挂接到链表中 */
for (unsigned int i = 1; i < num; i++) {
/* 创建一个结点,并挂接在当前结点后面 */
p_node->next = create_node(id_list[i]);
/* 将当前结点指向新创建的结点 */
p_node = p_node->next;
}
/* 返回指向链表头结点的指针 */
return p_head;
}
/* 遍历打印 */
void print_list(struct node* p_node)
{
printf("-START-\n");
while (p_node) {
/* p_node是指针 用 -> 操作符 */
printf("node->id=%d\n", p_node->id);
p_node = p_node->next;
}
printf("-END-\n");
}
int main()
{
/* 本次模拟灾难恢复的场景,并做了简化
* 假设某次程序执行时
* 【1】将链表中的数据写入了文件中永久保存(backup)
* 现在已经
* 【2】将文件中的内容(一连串的id)读取到了一个数组中(arr_id)
*
* create_list函数将通过这个数组来恢复之前的链表(recovery)
* 【1】和【2】将在后面的课程实现,这里主要关注链表的初始化
*/
int arr_id[5] = {1,2,3,4,5};
/* 用数组中的id,创建一个链表,p_head 为链表的头结点地址 */
struct node* p_head = create_list(arr_id, 5);
print_list(p_head);
/* 批量删除给定指针后面的n个结点 */
del_node(p_head, 2);
print_list(p_head);
return 0;
}