数据结构 - 链表(单向链表 、 单一结构)

链表的概念

链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。(文字引自百度百科)单向链表结构

链表的插入

链表的插入,就是将一个结点插入到某个位置,而就要将该位置的前后两个结点的链接断开,将前面的结点指向新插入的结点,新插入的结点指向后一个结点。

链表的删除

链表的删除,就是将特定位置结点断开与其前后结点的链接,让其前面的结点直接指向后面的结点,然后把该节点释放掉。

C语言代码

头文件

#ifndef __list_H
#define __list_H

typedef int LIST_TYPE;

/* 节点结构体定义 */
typedef struct _LIST_NODE_
{
	struct _LIST_NODE_ *next;
	LIST_TYPE data;
}LIST_NODE;

/* 链表结构体定义 */
typedef struct _LIST_
{
	LIST_NODE *list_head;
	unsigned int count;
}LIST;

unsigned char list_init(LIST *list);
unsigned char list_add(LIST *list, unsigned int position, LIST_TYPE data);
unsigned char list_add_head(LIST *list, LIST_TYPE data);
unsigned char list_add_tail(LIST *list, LIST_TYPE data);
unsigned char list_get(LIST *list, unsigned int position, LIST_TYPE *data);
unsigned char list_alter(LIST *list, unsigned int position, LIST_TYPE data);
unsigned char list_delete(LIST *list, unsigned int position);
unsigned char list_delete_head(LIST *list);
unsigned char list_delete_tail(LIST *list);
void list_clean(LIST *list);
void list_free(LIST *list);
unsigned int list_get_count(LIST *list);
unsigned char list_empty(LIST *list);

#endif

看到头文件中分别定义了结点的结构体和链表的结构体。结点结构体里面,分别是指向下个结点的指针,和“LIST_TYPE”类型的数据,只要把“LIST_TYPE”定义成自己想要的数据格式即可。链表结构体也很简单,一个记录链表开始的链表头指针,一个记录链表计数的变量。其余声明的函数,顾名思义就可知道函数的作用。

源文件

#include "list.h"
#include <stdlib.h>
#include <stdio.h>

/*********************************************************************************************************
** 函数名称:	list_init
** 功能描述:	链表初始化
** 输 入:		list: 链表
** 输 出:		1: 初始化成功
				0: 初始化失败
********************************************************************************************************/
unsigned char list_init(LIST *list)
{
	// 申请空间
	list->list_head = (LIST_NODE *)malloc(sizeof(LIST_NODE));
	if (list->list_head == NULL)
	{
		return 0;
	}

	list->list_head->data = 0;
	list->list_head->next = NULL;

	list->count = 0;

	return 1;
}

/*********************************************************************************************************
** 函数名称:	list_add
** 功能描述:	增加元素
** 输 入:		list: 链表
				position: 位置,索引从0开始
				data: 数据
** 输 出:		1: 增加成功
				0: 增加失败
********************************************************************************************************/
unsigned char list_add(LIST *list, unsigned int position, LIST_TYPE data)
{
	unsigned int index = 0;
	LIST_NODE *temp_node = NULL;
	LIST_NODE *prev_node = NULL, *next_node = NULL;

	/* 检查位置是否超过链表的长度 */
	if (position > list->count)
	{
		return 0;
	}

	/* 循环找到插入位置 */
	prev_node = list->list_head;
	for (index = 0; index < position; index++)
	{
		prev_node = prev_node->next;
	}
	next_node = prev_node->next;

	/* 创建空间,赋值 */
	temp_node = (LIST_NODE *)malloc(sizeof(LIST_NODE));
	if (temp_node == NULL) 
	{
		return 0;
	}
	temp_node->data = data;

	/* 连接新节点 */
	temp_node->next = next_node;
	prev_node->next = temp_node;

	/* 链表节点数更新 */
	list->count++;

	return 1;
}

/*********************************************************************************************************
** 函数名称:	list_add_head
** 功能描述:	头插
** 输 入:		list: 链表
				data: 数据
** 输 出:		1: 增加成功
				0: 增加失败
********************************************************************************************************/
unsigned char list_add_head(LIST *list, LIST_TYPE data)
{
	return list_add(list, 0, data);
}

/*********************************************************************************************************
** 函数名称:	list_add_tail
** 功能描述:	尾插
** 输 入:		list: 链表
				data: 数据
** 输 出:		1: 增加成功
				0: 增加失败
********************************************************************************************************/
unsigned char list_add_tail(LIST *list, LIST_TYPE data)
{
	return list_add(list, list->count, data);
}

/*********************************************************************************************************
** 函数名称:	list_get
** 功能描述:	获取元素
** 输 入:		list: 链表
				position: 位置,索引从0开始
				data: 数据变量的地址
** 输 出:		1: 获取成功
				0: 获取失败
********************************************************************************************************/
unsigned char list_get(LIST *list, unsigned int position, LIST_TYPE *data)
{
	unsigned int index = 0;
	LIST_NODE *temp_node = NULL;

	/* 检查位置是否超过链表 */
	if (position >= list->count)
	{
		return 0;
	}

	/* 遍历找到节点位置 */
	temp_node = list->list_head->next;
	for (index = 0; index < position; index++)
	{
		temp_node = temp_node->next;
	}

	// 赋值
	*data = temp_node->data;

	return 1;
}

/*********************************************************************************************************
** 函数名称:	list_alter
** 功能描述:	修改元素
** 输 入:		list: 链表
				position: 位置,索引从0开始
				data: 数据
** 输 出:		1: 修改成功
				0: 修改失败
********************************************************************************************************/
unsigned char list_alter(LIST *list, unsigned int position, LIST_TYPE data)
{
	unsigned int index = 0;
	LIST_NODE *temp_node = NULL;

	/* 检查位置是否超过链表 */
	if (position >= list->count)
	{
		return 0;
	}

	/* 遍历找到节点位置 */
	temp_node = list->list_head->next;
	for (index = 0; index < position; index++)
	{
		temp_node = temp_node->next;
	}

	/* 覆盖修改旧内容 */
	temp_node->data = data;

	return 1;
}

/*********************************************************************************************************
** 函数名称:	list_delete
** 功能描述:	删除元素
** 输 入:		list: 链表
				position: 位置,索引从0开始
** 输 出:		1: 删除成功
				0: 删除失败
********************************************************************************************************/
unsigned char list_delete(LIST *list, unsigned int position)
{
	unsigned int index = 0;
	LIST_NODE *temp_node = NULL;
	LIST_NODE *prev_node = NULL, *next_node = NULL;

	/* 检查位置是否超过链表 */
	if (position >= list->count)
	{
		return 0;
	}

	/* 遍历找到节点位置 */
	prev_node = list->list_head;
	temp_node = list->list_head->next;
	for (index = 0; index < position; index++)
	{
		prev_node = temp_node;
		temp_node = temp_node->next;
	}

	next_node = temp_node->next;

	/* 重新连接链表 */
	prev_node->next = next_node;

	/* 删除data,释放节点 */
	free(temp_node);

	/* 链表节点数更新 */
	list->count--;

	return 1;
}

/*********************************************************************************************************
** 函数名称:	list_delete_head
** 功能描述:	头删
** 输 入:		list: 链表
** 输 出:		1: 删除成功
				0: 删除失败
********************************************************************************************************/
unsigned char list_delete_head(LIST *list)
{
	return list_delete(list, 0);
}

/*********************************************************************************************************
** 函数名称:	list_delete_tail
** 功能描述:	尾删
** 输 入:		list: 链表
** 输 出:		1: 删除成功
				0: 删除失败
********************************************************************************************************/
unsigned char list_delete_tail(LIST *list)
{
	return list_delete(list, list->count - 1);
}

/*********************************************************************************************************
** 函数名称:	list_clean
** 功能描述:	清空链表
** 输 入:		list: 链表
** 输 出:		无
********************************************************************************************************/
void list_clean(LIST *list)
{
	unsigned int index = 0;
	LIST_NODE *temp_node = NULL;
	LIST_NODE *delete_node = NULL;

	/* 检查链表是否为空 */
	if (list->count == 0)
	{
		return;
	}

	/* 循环删除每个节点 */
	temp_node = list->list_head->next;
	for (index = 0; index < list->count; index++)
	{
		delete_node = temp_node;
		temp_node = temp_node->next;

		free(delete_node);
	}

	/* 重新连接链表头尾节点 */
	list->list_head->next = NULL;

	list->count = 0;
}

/*********************************************************************************************************
** 函数名称:	list_free
** 功能描述:	释放链表
** 输 入:		list: 链表
** 输 出:		无
********************************************************************************************************/
void list_free(LIST *list)
{
	unsigned int index = 0;
	LIST_NODE *temp_node = NULL;
	LIST_NODE *delete_node = NULL;

	/* 循环删除每个节点 */
	temp_node = list->list_head;
	for (index = 0; index < list->count + 1; index++)
	{
		delete_node = temp_node;
		temp_node = temp_node->next;

		free(delete_node);
	}

	list->list_head = NULL;
	list->count = 0;
}

/*********************************************************************************************************
** 函数名称:	list_get_count
** 功能描述:	获取链表结点数
** 输 入:		list: 链表
** 输 出:		链表结点数
********************************************************************************************************/
unsigned int list_get_count(LIST *list)
{
	return list->count;
}

/*********************************************************************************************************
** 函数名称:	list_empty
** 功能描述:	判断链表是否为空
** 输 入:		list: 链表
** 输 出:		1: 为空
				0: 非空
********************************************************************************************************/
unsigned char list_empty(LIST *list)
{
	if (list->count == 0)
	{
		return 1;
	}
	else 
	{
		return 0;
	}
}

每个函数就不一一细说了。

测试代码

#include <stdio.h>
#include "list.h"

void show_list(LIST *list)
{
	LIST_NODE *t_node = NULL;
	unsigned int index = 0;

	t_node = list->list_head->next;
	while (t_node != NULL)
	{
		printf("list<%d> = %d\r\n", index++, t_node->data);
		t_node = t_node->next;
	}
}

int main()
{
	LIST list;
	int i = 0;
	int data = 0;

	list_init(&list);

	for (i = 0; i < 10; i++)
	{
		list_add_head(&list, i+1);
	}

	show_list(&list);
	list_add(&list, 3, 79);
	list_add(&list, 3, 89);
	list_add_tail(&list, 110);
	list_alter(&list, list.count, 11);
	list_delete(&list, 3);
	list_delete_head(&list);
	list_delete_tail(&list);
	show_list(&list);
	list_clean(&list);
	show_list(&list);

	for (i = 0; i < list.count; i++)
	{
		list_get(&list, i, &data);
		printf("data: %d\r\n", data);
	}
	
	printf("list len: %d\r\n", list.count);

	getchar();
	return 0;
}

“show_list”函数来打印链表的每个成员

最后的最后,本人才疏学浅,此代码仅供参考交流,本人如有叙述错误,麻烦各位指正,有什么好的建议欢迎留言。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值