线性链表常用接口的实现

线性链表是数据结构中最常见,最常用的结构之一,其动态添加与删除优越性能在很多OS的任务调度中经常被使用到。通过最近的学习与归纳,有不小收获,整理一些常用的接口与实现如下:

1.link_list* create_list(void)

  创建链表,并包头结点,头结点内容为链表长度(或节点数)

2. STATUS head_insert( link_list* list,int index,int data)                                                                                                                        链表头插接口,index需从第二个节点开始,因为第一个节点是保留节点(存储链表长度信息)

3.STATUS tail_insert( link_list* list,int index,int data)                                                                                                                            链表尾插接口,index需从第一个节点开始

4. STATUS get_node( link_list* list, int index, int* node_data)                                                                                                               获取节点内容接口;

5.STATUS get_middle_node( link_list*list, int* node_data)                                                                                                                   获取中间节点内容接口,采用的是快慢指针的算法。具体实现,定义快慢两个指针,快指针步长为2,慢指针步长为1,当快指     针到达链尾时,慢指针指向的就是中间指针。                                                                                                                                   注:快慢指针的用法在链表里用的很多。

6.STATUS get_back_k_node( link_list*list,int k, int* node_data)                                                                                                             获取距离链尾第K个节点内容,采用的也是快慢指针的算法。具体实现,定义快慢两个指针,快指针先移至第K个节点,然后快慢指针同时移动,当快针到达链尾时,慢指针指向的就是距离链尾第K个节点。

7.STATUS delect_node( link_list* list,int index)                                                                                                                                          删除节点,这里有个地方要注意,被删除的节点一定要释放,否则就会造成内存泄漏

8.STATUS clear_list( link_list*list)                                                                                                                                                           清空链表,只保留头结点,也是要注意释放内存

9.STATUS show_list_content(link_list*list)                                                                                                                                              打印链表内容
 

详细代码,需要的可以直接CV

#ifndef __LIST_H__
#define __LIST_H__

/**************** include ********************/
#include "stdint.h"

/**************** define ********************/

/**************** struct ********************/
typedef struct list_node_t
{
    int data;	
    list_node_t* p_next;
}link_list;


typedef enum
{
    FINE,
    LIST_SHORT,
    NODE_NO_EXIT
} STATUS;

/**************** parameter *****************/
//struct list_node_t	 list_node,*p_list_node;
/**************** function ********************/

link_list* create_list(void);

STATUS head_insert( link_list* list,int index,int data);

STATUS tail_insert( link_list* list,int index,int data);

STATUS get_node( link_list* list, int index, int* node_data);

STATUS get_middle_node( link_list*list, int* node_data);

STATUS get_back_k_node( link_list*list,int k, int* node_data);

STATUS delect_node( link_list* list,int index);

STATUS clear_list( link_list*list);

STATUS show_list_content(link_list*list);

#endif /*__LIST_H__*/

/**************** (.h) end file *******************/

 

 

/* Includes ------------------------------------------------------------------*/
#include "list.h"
#include "stdio.h"
#include "stdlib.h"
/* prama define discrible -----------------------------------------------------*/

/* strcuct  discrible --------------------------------------------------------*/

/* prama  discrible ---------------------------------------------------------*/

/* private fucntion  declaration --------------------------------------------*/
/******************************************************************************
* @Function: link_list* create_list(void)
* @Discrible:  创建空链表,返回链表头指针
* @Param:
* @Return:
* @Others:
******************************************************************************
* @Recode    date       version         author             modify
*          ------------------------------------------------------------------
*          20190605      V1.0          VINCENT            Create
*
*******************************************************************************/
link_list *create_list(void)
{
	link_list *head;
	head = (link_list *)malloc(sizeof(link_list));
	head->data = 1;
	head->p_next = NULL;
	return head;
}

/******************************************************************************
* @Function:  STATUS head_insert(link_list* list,int index, int data)
* @Discrible: index 位置前插入元素
* @Param:
* @Return:
* @Others:
******************************************************************************
* @Recode    date       version         author             modify
*          ------------------------------------------------------------------
*          20190605      V1.0          VINCENT            Create
*
*******************************************************************************/
STATUS head_insert(link_list *list, int index, int data)
{
	int i = 1;
	struct list_node_t *list_node, *pre_node;

	pre_node = list;

	/* 节点头插入,需要从第二个节点开始,第一个节点是不使用的节点,存储的是链表长度信息*/
	if (index < 2)
	{
		return LIST_SHORT;
	}

	/*头插算法实现是找到需要头插节点的前一个节点进行尾插*/
	while ((i < (index - 1)) && pre_node && pre_node->p_next)
	{
		pre_node = pre_node->p_next;
		i++;
	}
	/*如果节点为空,则说明节点不存在*/
	if ((!pre_node) || (!pre_node->p_next))
	{
		return NODE_NO_EXIT;
	}

	/*创建新节点*/
	list_node = (link_list *)malloc(sizeof(link_list));
	list_node->data = data;

	/*插入节点*/
	list_node->p_next = pre_node->p_next;
	pre_node->p_next = list_node;

	/*头结点计数加1*/
	pre_node->data++;

	return FINE;
}

/******************************************************************************
* @Function:  STATUS tail_insert(link_list* list,int index,int data)
* @Discrible:  index 位置后插入元素
* @Param:
* @Return:
* @Others:
******************************************************************************
* @Recode    date       version         author             modify
*          ------------------------------------------------------------------
*          20190605      V1.0          VINCENT            Create
*
*******************************************************************************/
STATUS tail_insert(link_list *list, int index, int data)
{
	int ret = 0;
	int i = 1;
	struct list_node_t *list_node, *pre_node;

	pre_node = list;
	// 节点尾插入,需要从第一个节点开始,第一个节点是不使用的节点,存储的是链表长度信息
	if (index < 1)
	{
		return LIST_SHORT;
	}

	while ((i < index) && pre_node)
	{
		pre_node = pre_node->p_next;
		i++;
	}

	/*如果节点为空,则说明节点不存在*/
	if (!pre_node)
	{
		return NODE_NO_EXIT;
	}

	/*创建新节点*/
	list_node = (link_list *)malloc(sizeof(link_list));
	list_node->data = data;

	/*插入节点*/
	list_node->p_next = pre_node->p_next;
	pre_node->p_next = list_node;

	/*头结点长度+1*/
	pre_node->data++;
	return FINE;
}

/******************************************************************************
* @Function: STATUS get_node(link_list* list, int index)
* @Discrible:  获取index节点数据
* @Param:
* @Return:
* @Others:
******************************************************************************
* @Recode    date       version         author             modify
*          ------------------------------------------------------------------
*          20190605      V1.0          VINCENT            Create
*
*******************************************************************************/
STATUS get_node(link_list *list, int index, int *node_value)
{
	int ret = 0;
	struct list_node_t *pre_node = list;

	while((index-- > 1) && pre_node)
	{
		pre_node = pre_node->p_next;
	}

	if(!pre_node)
	{
		node_value = NULL;
		return NODE_NO_EXIT;
	}
	*node_value = pre_node->data;
	return FINE;
}

/******************************************************************************
* @Function: STATUS get_middle_node(link_list *list)
* @Discrible:   获取中间节点数值
* @Param:
* @Return:
* @Others:
******************************************************************************
* @Recode    date       version         author             modify
*          ------------------------------------------------------------------
*          20190605      V1.0          VINCENT            Create
*
*******************************************************************************/
STATUS get_middle_node(link_list *list,int *node_value)
{
	int ret = 0;
	struct list_node_t *fast_point,*slow_point,*pre_list_node;

	fast_point = list;
	slow_point = list;
	pre_list_node = list;

	/*取中间节点的值,链表长度不小于3*/
	if((!pre_list_node) && (!pre_list_node->p_next) && (!pre_list_node->p_next->p_next))
	{	
		return LIST_SHORT;
	}

	/*算法原理,快指针是慢指针的两倍,当快指针走到链位时,慢指针刚好走到一半*/
	while(fast_point&&fast_point->p_next)
	{
		fast_point  = fast_point->p_next->p_next;
		slow_point  = slow_point->p_next;
	}

	*node_value = slow_point->data;
	return FINE;
}

/******************************************************************************
* @Function:  STATUS get_back_k_node(link_list *list, int k, int* node_data)
* @Discrible:  获取倒数第K个节点的数值
* @Param:
* @Return:
* @Others:
******************************************************************************
* @Recode    date       version         author             modify
*          ------------------------------------------------------------------
*          20190605      V1.0          VINCENT            Create
*
*******************************************************************************/
STATUS get_back_k_node(link_list *list, int k, int* node_data)
{
	int ret = 0;
	struct list_node_t *fast_point,*slow_point,*pre_list_node;

	fast_point = list;
	slow_point = list;
	pre_list_node = list;

	/*先将快指针移但比慢指针多K个节点的位置*/
     while((k-->0) && fast_point)
	 {
		 fast_point = fast_point->p_next;
	 }

	if((!fast_point))
	{
		return LIST_SHORT;
	}

	/*然后同时移动快慢指针,当快指针到达链尾时,慢指针就在距离链尾K个节点的位置*/
	 while(fast_point)
	 {
		 fast_point = fast_point->p_next;
		 slow_point = slow_point->p_next;
	 }

	 *node_data = slow_point->data;

	return FINE;
}

/******************************************************************************
* @Function: STATUS delect_node(link_list *list, int index)
* @Discrible: 删除某个节点
* @Param:
* @Return:
* @Others:
******************************************************************************
* @Recode    date       version         author             modify
*          ------------------------------------------------------------------
*          20190605      V1.0          VINCENT            Create
*
*******************************************************************************/
STATUS delect_node(link_list *list, int index)
{
	int ret = 0;
	struct list_node_t *pre_list_node,*list_node,*free_list_node;

	pre_list_node =  list;
	/*节点删除必须从第二个节点开始,因为第一个节点是存储的长度信息,不可用*/
	if(index < 2 )
	{
		return LIST_SHORT;
	}

	while(pre_list_node  && (index-- > 2))
	{
		pre_list_node = pre_list_node->p_next;
	}

	if((!pre_list_node))
	{
		return NODE_NO_EXIT;
	}
	/*删除节点头结点计数减1*/
	list_node = pre_list_node->p_next->p_next;
	free_list_node = pre_list_node->p_next;
	pre_list_node->p_next = list_node;
	pre_list_node->data--;

	/*释放删掉节点的空间*/
	free(free_list_node);
	free_list_node = NULL ;

	return FINE;
}

/******************************************************************************
* @Function:  STATUS clear_list(link_list *list)
* @Discrible:   清空链表
* @Param:
* @Return:
* @Others:
******************************************************************************
* @Recode    date       version         author             modify
*          ------------------------------------------------------------------
*          20190605      V1.0          VINCENT            Create
*
*******************************************************************************/
STATUS clear_list(link_list *list)
{
	int ret = 0;
	struct list_node_t *list_node,*free_list_node;

	/*清空链表,只保留表头的信息*/
	list_node  = list->p_next;
	list->data = 1;
	list->p_next = NULL;

	while(list_node)
	{
		free_list_node =  list_node;
		list_node = list_node->p_next;
		free(free_list_node);
		free_list_node = NULL;
	}
	return FINE;
}

/******************************************************************************
* @Function:  STATUS show_list_content(link_list *list)
* @Discrible:  打印链表内容
* @Param:
* @Return:
* @Others:
******************************************************************************
* @Recode    date       version         author             modify
*          ------------------------------------------------------------------
*          20190605      V1.0          VINCENT            Create
*
*******************************************************************************/
STATUS show_list_content(link_list *list)
{
	int ret = 0;
	link_list *pre_node = list;
	printf("\r\n----------- beagin -----------\r\n");
	while (pre_node)
	{
		printf("%d  ", pre_node->data);
		pre_node = pre_node->p_next;
	}
	printf("\r\n----------- end -----------\r\n");
	return FINE;
}
/************************ (C) END OF FILE ************************************/

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值