自己实现一个单项的链表(C语言)

chenweimin 2月前 ⋅ 453 阅读
  1. 编写头文件 LinkNode.h
    #if 1
    /*单向链表*/
    #pragma once
    #include <stdlib.h>
    
    enum  _Bool_
    {
    	//假
    	_FALSE,
    	//真
    	_TRUE
    };
    typedef struct DataNode {
    	//存放数据指针
    	void* data;
    	//指向下一个节点的指针
    	struct DataNode * next;
    
    } DataNode;
    
    
    /*单向链表结构体*/
    typedef struct LinkNode {
    	//链表头节点指针
    	DataNode* heard;
    	//链表尾节点指针
    	DataNode* tail;
    	//链表大小
    	int size;
    
    }LinkNode;
    
    /*创建链表*/
    LinkNode* creat_node();
    
    /*
    插入数据
    link_node 链表指针
    pos 插入索引位置 如果超出则默认尾部插入
    data 插入数据
    */
    int insert_node_data(LinkNode* link_node, int pos, void* data);
    
    /*遍历链表*/
    void foreach_node_data(LinkNode* link_node, void(*print_data)(void* data));
    
    
    /*根据索引获取数据*/
    DataNode* get_node_data(LinkNode* link_node, int pos);
    
    /*销毁链表*/
    void destroy_node(LinkNode* link_node);
    
    /*根据索引下标删除数据*/
    int delete_node_data(LinkNode* link_node, int pos);
    
    /*清空链表*/
    int clean_node(LinkNode* link_node);
    
    /*获取链表大小*/
    int size_node(LinkNode* link_node);
    #endif 
    ​
  2. 编写实现 LinkNode.c
    #if 1
    
    #pragma once
    #include "LinkNode.h"
    
    /*创建链表*/
    LinkNode* creat_node() {
    	//初始化链表堆内存
    	LinkNode * link_node= malloc(sizeof(LinkNode));
    	if (NULL== link_node)
    	{
    		return NULL;
    	}
    	//初始化头节点堆内存指针
    	DataNode * _heard=malloc(sizeof(DataNode));
    	if (NULL == _heard)
    	{
    		return NULL;
    	}
    	//初始化链表
    	link_node->heard = _heard;
    	//尾节点指向头节点
    	link_node->tail = link_node->heard;
    	link_node->size = 0;
    	return link_node;
    }
    
    /*
    插入数据
    link_node 链表指针
    pos 插入索引位置 如果超出则默认尾部插入
    data 插入数据
    */
    int insert_node_data(LinkNode* link_node,int pos,void * data) {
    	if (NULL== link_node)
    	{
    		return _FALSE;
    	}
    
    	if (NULL == data)
    	{
    		return _FALSE;
    	}
    	//判断索引位置 如果不符合则尾部插入
    	if (pos<0||pos>link_node->size)
    	{
    		pos = link_node->size;
    	}
    	DataNode* before_node = link_node->heard;
    	//找到插入数据的前一个节点
    	for (int  i = 0; i < pos; i++)
    	{
    		before_node = before_node->next;
    	}
    	//创建节点
    	DataNode* node = malloc(sizeof(DataNode));
    	node->data = data;
    	node->next = NULL;
    	//节点建立关系
    	node->next = before_node->next;
    	before_node->next = node;
    	//更新链表长度
    	(link_node->size)++;
    	//更改尾部节点指向
    	link_node->tail = node;
    
    	return _TRUE;
    }
    
    /*遍历链表*/
    void foreach_node_data(LinkNode* link_node, void(*print_data)(void* data) ){
    
    	if (NULL == link_node)
    	{
    		return;
    	}
    
    	if (NULL == print_data)
    	{
    		return;
    	}
    
    	DataNode* currnt = link_node->heard->next;
    	for (int  i = 0; i < link_node->size; i++)
    	{
    		print_data(currnt->data);
    		currnt = currnt->next;
    	}
    }
    
    /*根据索引获取数据*/
    DataNode * get_node_data(LinkNode* link_node, int pos) {
    	if (NULL== pos)
    	{
    		return NULL;
    	}
    	if (pos<0||pos >link_node->size) {
    		return NULL;
    	}
    
    	//从头节点开始遍历
    	DataNode* current = link_node->heard->next;
    	for (int  i = 0; i < pos; i++)
    	{
    		current = current->next;
    	}
    
    	return current;
    
    }
    
    /*销毁链表*/
    void destroy_node(LinkNode* link_node) {
    	if (NULL== link_node)
    	{
    		return;
    	}
    
    	DataNode* current = link_node->heard;
    	//释放所有节点内存
    	for (int i  =0; i < link_node->size; i++)
    	{
    		//记录一下一个节点
    		DataNode* temp = current->next;
    		free(current);
    		current = NULL;
    		current = temp;
    	}
    	//释放链表堆内存
    	free(link_node);
    	link_node = NULL;
    }
    
    /*根据索引下标删除数据*/
    int delete_node_data(LinkNode* link_node, int pos) {
    	if (NULL == link_node)
    	{
    		return _FALSE;
    	}
    	if (pos<0||pos>link_node->size)
    	{
    		return _FALSE;
    	}
    	//找到需要删除节点的前一个节点
    	DataNode* current = link_node->heard->next;
    	for (int i = 0; i < pos; i++)
    	{
    		current = current->next;
    	}
    	//记住要删除的节点
    	DataNode* del = current->next;
    	//关联要删除节点的下一个节点的指向
    	current->next = del->next;
    	free(del);
    	del = NULL;
    
    	//修改链表大小
    	(link_node->size)--;
    	return _TRUE;
    }
    
    /*清空链表*/
    int clean_node(LinkNode* link_node) {
    	if (NULL == link_node)
    	{
    		return _FALSE;
    	}
    	DataNode* current = link_node->heard->next;
    
    	for (int i = 0; i < link_node->size; i++)
    	{
    		//记录当前需要释放节点
    		DataNode* temp = current;
    		current = current->next;
    		//释放内存
    		free(temp);
    		temp = NULL;
    	}
    	//初始化链表属性
    	link_node->size = 0;
    	link_node->tail = link_node->heard;
    	return _TRUE;
    }
    
    
    /*获取链表大小*/
    int size_node(LinkNode* link_node) {
    	if (NULL == link_node)
    	{
    		return -1;
    	}
    	return link_node->size;
    }
    #endif 
    ​
  3. 编写测试类 TestLinkNode.c
    #if 1
    
    #pragma once
    #include "LinkNode.h"
    #include <stdio.h>
    typedef struct Person {
    	char name[64];
    	int age;
    }Person;
    
    
    void test_print_node(void* data) {
    
    	Person* p = data;
    	printf("数据的名称为:%s,年龄为:%d\n", p->name, p->age);
    }
    int main(int argc, char* argv[]) {
    
    	//创建链表
    	LinkNode * node = creat_node();
    	Person p = { "孙悟空",500 };
    	Person p1 = { "猪八戒",1500 };
    	Person p2 = { "沙悟净",2500 };
    	Person p3 = { "白龙马",3500 };
    	Person p4 = { "唐僧",4500 };
    	Person p5 = { "玉皇大帝",5500 };
    	Person p6 = { "如来佛祖",6500 };
    
    	insert_node_data(node, 0, &p);
    	insert_node_data(node, 1, &p1);
    	insert_node_data(node, 2, &p2);
    	insert_node_data(node, 3, &p3);
    	insert_node_data(node, 4, &p4);
    	insert_node_data(node, 1, &p5);
    	insert_node_data(node, 0, &p6);
    
    	//遍历打印链表
    	foreach_node_data(node, test_print_node);
    	int node_size =size_node(node);
    	printf("链表的长度为:%d\n", node_size);
    	printf("----------------------------------------------\n");
    	//获取链表中的元素
    	DataNode * data =get_node_data(node,6);
    	Person* p_data =data->data;
    	printf("链表中的数据名称为:%s,年龄为:%d\n", p_data->name, p_data->age);
    	printf("----------------------------------------------\n");
    	//删除链表上的数据
    	delete_node_data(node, 1);
    	foreach_node_data(node, test_print_node);
    	 node_size = size_node(node);
    	printf("链表的长度为:%d\n", node_size);
    	printf("----------------------------------------------\n");
    	//清空链表
    	clean_node(node);
    	foreach_node_data(node, test_print_node);
    	node_size = size_node(node);
    	printf("链表的长度为:%d\n", node_size);
    	//销毁链表
    	destroy_node(node);
    	return EXIT_SUCCESS;
    }
    #endif
    ​

全部评论: 0

    我有话说: