数据结构之单向链表(C语言实现)

4 篇文章 0 订阅
4 篇文章 0 订阅

单向链表是链表的一种,其特点是链表的链接方向是单向的,对链表的访问要通过顺序读取从头部开始;链表是使用指针进行构造的列表;
list.h

#ifndef LIST_H_INCLUDE
#define LIST_H_INCLUDE
#include <sys/types.h>
/*节点*/
typedef struct LIST_NODE
{
	int data;
	struct LIST_NODE *next;
}list_node;
/*链表*/
typedef struct LIST{
	list_node *head;
	list_node *tail;
	list_node *frwd;
}LIST;
/*初始化链表*/
void list_init(LIST *list);
/*清空链表*/
void list_deinit(LIST *list);
/*判空*/
int list_empty(LIST *list);
/*添加节点*/
void list_append(LIST *list,int data);
/*迭代*/
void list_iteration(LIST *list);
/*元素数量*/
size_t list_size(LIST *list);
/*正向输出*/
void list_print(LIST *list);
/*反向输出*/
void list_rprint(LIST *list);
/*逆转链表*/
void list_reverse(LIST *list);
/*取中间值*/
int list_mid(LIST *list);
#endif

头文件包含功能为
链表的初始化
链表的清除
判空
追加节点
迭代
统计元素的数量
正向输出
反向输出(递归实现)
逆转链表(递归实现)
去中间值

list.c

#include"list.h"
#include<stdio.h>
#include<stdlib.h>
/*创建节点*/
static list_node* creart_node(int data)
{
	list_node* node=malloc(sizeof(list_node));
	node->data=data;
	node->next=NULL;
	return node;
}
/*删除节点*/
static list_node* destory_node(list_node* node)
{
    list_node* next=node->next;
    free(node);
    return next;
}
/*初始化链表*/
void list_init(LIST *list)
{
	list->head=NULL;
	list->tail=NULL;
	list->frwd=NULL;
}
/*清除链表*/
void list_deinit(LIST *list)
{
	while(list->head)
		list->head=destory_node(list->head);
	list->tail=NULL;
	list->frwd=NULL;
}
/*判空*/
int  list_empty(LIST *list)
{
	return !list->head && !list->tail;
}
/*增加节点*/
void list_append(LIST *list,int data)
{
	list_node* node=creart_node(data);
	if(list->tail)
		list->tail->next=node;
	else
		list->head=node;
	    list->tail=node;
}
/*开始迭代*/
void list_iteration(LIST *list)
{
	list->frwd=list->head;
}
/*数量*/
size_t list_size(LIST *list)
{
	size_t size=0;
	list_node* find=list->head;
	for(;find;find=find->next)
		size++;
	return size;
}
/*正向打印*/
void list_print(LIST *list)
{
	list_node *node=list->frwd;
	for(;node;node=node->next)
		printf("%d\t",node->data);
}
/*由于单向没有前节点,实现反向打印可利用递归*/
/*原理*/
void rtail(list_node* frwd)
{
	if(frwd)
	{
		rtail(frwd->next);
		printf("%d\t",frwd->data);
	}
}
/*实现原理*/
void list_rprint(LIST *list)
{
	rtail(list->frwd);
}
/*逆转函数*/
void reverse(list_node* head)
{
	if(head&&head->next)
	{
		reverse(head->next);
		/*其实空节点作用就是存当前的头结点*/
		head->next->next=head;
		/* 没逆转之前   1->2->3->4->NULL*/
		/*当前head 在4(head)那个位置   head->NULL */
		/*逆转一个节点后后      1->2->3<-4    */
		head->next=NULL;
	}
}
void list_reverse(LIST *list)
{
	/*随着递归的结束,每个节点也逆转完了*/
	reverse(list->head);
	/*逆转完之后,head的next是空的,tail的next是有数据的节点*/
	list_node* temp=list->head;
	/*所以正常从head开始顺序打印的话,需要将逆转后的head和tail换一下*/
	list->head=list->tail;
	list->tail=temp;
	list->frwd=list->head;
}
int list_mid(LIST *list)
{
	list_node* node=NULL,*mid=NULL;
	for(node=mid=list->frwd;node->next&&node->next->next;mid=mid->next,node=node->next->next);
		return mid->data;
}
int main()
{
	int i;
	LIST list;
	list_init(&list);
	for(i=0;i<5;i++)
		list_append(&list,i+1);
		list_iteration(&list);
		printf("正向打印\n");
		list_print(&list);
		printf("\n");
		printf("反向打印\n");
		list_rprint(&list);
		printf("\n");
		list_print(&list);
		printf("\n");
		list_reverse(&list);
		printf("逆转后\n");
		list_print(&list);
		printf("\n");
		list_deinit(&list);
		return 0;
}

可能相对较难理解的是逆转链表那个功能。
下面画图描述逆转的过程

具体可结合代码和注释理解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值