vxworks下的lstLib库的使用

1、lstLib库简介

记得在学《数据结构》这门课的时候,链表好难理解。listlib库是Vxworks源代码中的双向链接库,由于是操作系统的源代码,所以库的代码质量师非常好的,标准的C语言,而且接口的命名、易用性和通用移植性都是非常好的。

仔细研究lstLib源码,对提高编程语言能力以及自己封装API都是由非常大的帮助。

代码:

lstLib.h

#ifndef __INClstLibh
#define __INClstLibh

#ifdef __cplusplus
extern "C" {
#endif

	typedef struct _Vx_node		    /* Node of a linked list. */
	{
		struct _Vx_node *next;	    /* Points at the next node in the list */
		struct _Vx_node *previous;	/* Points at the previous node in the list */
	} _Vx_NODE;


	typedef struct			/* Header for a linked list. */
	{
		_Vx_NODE node;		/* Header list node */
		int count;			/* Number of nodes in list */
	} _Vx_LIST;


	typedef _Vx_NODE NODE;
	typedef _Vx_LIST LIST;

	extern void	    lstLibInit(void);
	extern NODE *	lstFirst(LIST *pList);
	extern NODE *	lstGet(LIST *pList);
	extern NODE *	lstLast(LIST *pList);
	extern NODE *	lstNStep(NODE *pNode, int nStep);
	extern NODE *	lstNext(NODE *pNode);
	extern NODE *	lstNth(LIST *pList, int nodenum);
	extern NODE *	lstPrevious(NODE *pNode);
	extern int 	    lstCount(LIST *pList);
	extern int 	    lstFind(LIST *pList, NODE *pNode);
	extern void 	lstAdd(LIST *pList, NODE *pNode);
	extern void 	lstConcat(LIST *pDstList, LIST *pAddList);
	extern void 	lstDelete(LIST *pList, NODE *pNode);
	extern void 	lstExtract(LIST *pSrcList, NODE *pStartNode, NODE *pEndNode, LIST *pDstList);
	extern void 	lstFree(LIST *pList);
	extern void 	lstInit(LIST *pList);
	extern void 	lstInsert(LIST *pList, NODE *pPrev, NODE *pNode);

#ifdef __cplusplus
}
#endif

#endif /* __INClstLibh */

lstLib.c

#include "lstLib.h"
#include <stdlib.h>

#define HEAD	node.next		    /* first node in list */
#define TAIL	node.previous		/* last node in list */

#define ERROR -1
#define OK     0


void lstLibInit(void)
{
	return;
}

/*********************************************************************
*
* lstInit - initialize a list descriptor
*
* This routine initializes a specified list to an empty list.
*
* RETURNS: N/A
*/

void lstInit(LIST *pList)
{
	pList->HEAD = NULL;
	pList->TAIL = NULL;
	pList->count = 0;
}
/*************************************************************************
*
* lstAdd - add a node to the end of a list
*
* This routine adds a specified node to the end of a specified list.
*
* RETURNS: N/A
*/

void lstAdd(LIST *pList, NODE *pNode)
{
	lstInsert(pList, pList->TAIL, pNode);
}
/**************************************************************************
*
* lstConcat - concatenate two lists
*
* This routine concatenates the second list to the end of the first list.
* The second list is left empty.  Either list (or both) can be
* empty at the beginning of the operation.
*
* RETURNS: N/A
*/

void lstConcat(LIST *pDstList, LIST *pAddList)
{
	if (pAddList->count == 0)		/* nothing to do if AddList is empty */
		return;

	if (pDstList->count == 0)
		*pDstList = *pAddList;
	else
	{
		/* both lists non-empty; update DstList pointers */

		pDstList->TAIL->next = pAddList->HEAD;
		pAddList->HEAD->previous = pDstList->TAIL;
		pDstList->TAIL = pAddList->TAIL;

		pDstList->count += pAddList->count;
	}

	/* make AddList empty */

	lstInit(pAddList);
}
/**************************************************************************
*
* lstCount - report the number of nodes in a list
*
* This routine returns the number of nodes in a specified list.
*
* RETURNS:
* The number of nodes in the list.
*/

int lstCount(LIST *pList)
{
	return (pList->count);
}
/**************************************************************************
*
* lstDelete - delete a specified node from a list
*
* This routine deletes a specified node from a specified list.
*
* RETURNS: N/A
*/

void lstDelete(LIST *pList, NODE *pNode)
{
	if (pNode->previous == NULL)
		pList->HEAD = pNode->next;
	else
		pNode->previous->next = pNode->next;

	if (pNode->next == NULL)
		pList->TAIL = pNode->previous;
	else
		pNode->next->previous = pNode->previous;

	/* update node count */

	pList->count--;
}
/************************************************************************
*
* lstExtract - extract a sublist from a list
*
* This routine extracts the sublist that starts with <pStartNode> and ends
* with <pEndNode> from a source list.  It places the extracted list in
* <pDstList>.
*
* RETURNS: N/A
*/

void lstExtract(LIST *pSrcList, NODE *pStartNode, NODE *pEndNode, LIST *pDstList)
{
	int i;
	NODE *pNode;

	/* fix pointers in original list */

	if (pStartNode->previous == NULL)
		pSrcList->HEAD = pEndNode->next;
	else
		pStartNode->previous->next = pEndNode->next;

	if (pEndNode->next == NULL)
		pSrcList->TAIL = pStartNode->previous;
	else
		pEndNode->next->previous = pStartNode->previous;


	/* fix pointers in extracted list */

	pDstList->HEAD = pStartNode;
	pDstList->TAIL = pEndNode;

	pStartNode->previous = NULL;
	pEndNode->next = NULL;


	/* count number of nodes in extracted list and update counts in lists */

	i = 0;

	for (pNode = pStartNode; pNode != NULL; pNode = pNode->next)
		i++;

	pSrcList->count -= i;
	pDstList->count = i;
}
/************************************************************************
*
* lstFirst - find first node in list
*
* This routine finds the first node in a linked list.
*
* RETURNS
* A pointer to the first node in a list, or
* NULL if the list is empty.
*/

NODE *lstFirst(LIST *pList)
{
	return (pList->HEAD);
}

/************************************************************************
*
* lstGet - delete and return the first node from a list
*
* This routine gets the first node from a specified list, deletes the node
* from the list, and returns a pointer to the node gotten.
*
* RETURNS
* A pointer to the node gotten, or
* NULL if the list is empty.
*/

NODE *lstGet(LIST *pList)
{
	NODE *pNode = pList->HEAD;

	if (pNode != NULL)                      /* is list empty? */
	{
		pList->HEAD = pNode->next;          /* make next node be 1st */

		if (pNode->next == NULL)            /* is there any next node? */
			pList->TAIL = NULL;             /*   no - list is empty */
		else
			pNode->next->previous = NULL;   /*   yes - make it 1st node */

		pList->count--;                     /* update node count */
	}

	return (pNode);
}
/************************************************************************
*
* lstInsert - insert a node in a list after a specified node
*
* This routine inserts a specified node in a specified list.
* The new node is placed following the list node <pPrev>.
* If <pPrev> is NULL, the node is inserted at the head of the list.
*
* RETURNS: N/A
*/

void lstInsert(LIST *pList, NODE *pPrev, NODE *pNode)
{
	NODE *pNext;

	if (pPrev == NULL)
	{				/* new node is to be first in list */
		pNext = pList->HEAD;
		pList->HEAD = pNode;
	}
	else
	{				/* make prev node point fwd to new */
		pNext = pPrev->next;
		pPrev->next = pNode;
	}

	if (pNext == NULL)
		pList->TAIL = pNode;		/* new node is to be last in list */
	else
		pNext->previous = pNode;	/* make next node point back to new */


		/* set pointers in new node, and update node count */

	pNode->next = pNext;
	pNode->previous = pPrev;

	pList->count++;
}
/************************************************************************
*
* lstLast - find the last node in a list
*
* This routine finds the last node in a list.
*
* RETURNS
* A pointer to the last node in the list, or
* NULL if the list is empty.
*/

NODE *lstLast(LIST *pList)
{
	return (pList->TAIL);
}
/************************************************************************
*
* lstNext - find the next node in a list
*
* This routine locates the node immediately following a specified node.
*
* RETURNS:
* A pointer to the next node in the list, or
* NULL if there is no next node.
*/

NODE *lstNext(NODE *pNode)
{
	return (pNode->next);
}
/************************************************************************
*
* lstNth - find the Nth node in a list
*
* This routine returns a pointer to the node specified by a number <nodenum>
* where the first node in the list is numbered 1.
* Note that the search is optimized by searching forward from the beginning
* if the node is closer to the head, and searching back from the end
* if it is closer to the tail.
*
* RETURNS:
* A pointer to the Nth node, or
* NULL if there is no Nth node.
*/

NODE *lstNth(LIST *pList, int nodenum)
{
	NODE *pNode;

	/* verify node number is in list */

	if ((nodenum < 1) || (nodenum > pList->count))
		return (NULL);


	/* if nodenum is less than half way, look forward from beginning;
	otherwise look back from end */

	if (nodenum < (pList->count >> 1))
	{
		pNode = pList->HEAD;

		while (--nodenum > 0)
			pNode = pNode->next;
	}

	else
	{
		nodenum -= pList->count;
		pNode = pList->TAIL;

		while (nodenum++ < 0)
			pNode = pNode->previous;
	}

	return (pNode);
}
/************************************************************************
*
* lstPrevious - find the previous node in a list
*
* This routine locates the node immediately preceding the node pointed to
* by <pNode>.
*
* RETURNS:
* A pointer to the previous node in the list, or
* NULL if there is no previous node.
*/

NODE *lstPrevious(NODE *pNode)
{
	return (pNode->previous);
}
/************************************************************************
*
* lstNStep - find a list node <nStep> steps away from a specified node
*
* This routine locates the node <nStep> steps away in either direction from
* a specified node.  If <nStep> is positive, it steps toward the tail.  If
* <nStep> is negative, it steps toward the head.  If the number of steps is
* out of range, NULL is returned.
*
* RETURNS:
* A pointer to the node <nStep> steps away, or
* NULL if the node is out of range.
*/

NODE *lstNStep(NODE *pNode, int nStep)
{
	int i;

	for (i = 0; i < abs(nStep); i++)
	{
		if (nStep < 0)
			pNode = pNode->previous;
		else if (nStep > 0)
			pNode = pNode->next;
		if (pNode == NULL)
			break;
	}
	return (pNode);
}

/************************************************************************
*
* lstFind - find a node in a list
*
* This routine returns the node number of a specified node (the
* first node is 1).
*
* RETURNS:
* The node number, or
* ERROR if the node is not found.
*/

int lstFind(LIST *pList, NODE *pNode)
{

	NODE *pNextNode;
	int index = 1;

	pNextNode = lstFirst(pList);

	while ((pNextNode != NULL) && (pNextNode != pNode))
	{
		index++;
		pNextNode = lstNext(pNextNode);
	}

	if (pNextNode == NULL)
		return (ERROR);
	else
		return (index);
}

/************************************************************************
*
* lstFree2 - free up a list
*
* This routine turns the list pointerd by <pList> into an empty list.
* It also frees up memory used for nodes, by using the specified free
* function <freeFunc>.
*
* RETURNS: N/A
*
* SEE ALSO: lstFree()
*
* NOMANUAL
*/

typedef void(*VOIDFUNPTR)();
void lstFree2(LIST *pList, VOIDFUNPTR freeFunc)
{
	NODE *p1, *p2;
	if (pList->count > 0)
	{
		p1 = pList->HEAD;
		while (p1 != NULL)
		{
			p2 = p1->next;
			freeFunc((char *)p1);
			p1 = p2;
		}
		pList->count = 0;
		pList->HEAD = pList->TAIL = NULL;
	}
}

/************************************************************************
*
* lstFree - free up a list
*
* This routine turns any list into an empty list.
* It also frees up memory used for nodes.
*
* RETURNS: N/A
*
* SEE ALSO: free()
*/
/* list for which to free all nodes */
void lstFree(LIST *pList)
{
	lstFree2(pList, free);
}

2、一个简单的例子

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

/*******************************************************/
typedef struct  tag_student
{
	int id;
	char name[20];
	char sex;
	int age;
}Student;

typedef struct tag_list_element
{
	NODE * next;
	NODE * prev;
	//LIST的元素必须有前面两行代码
	Student stu;
} list_element;
/*******************************************************/
static LIST list1,list2;
/*******************************************************/

//显示list
void Display(LIST *_list)
{
	list_element *p = NULL;
	p = (list_element*)lstFirst(_list);
	if (p)
	{
		printf("id = %d, name = %s, age = %d\n", p->stu.id, p->stu.name, p->stu.age);
		while (p=lstNext(p))
		{
			printf("id = %d, name = %s, age = %d\n", p->stu.id, p->stu.name, p->stu.age);
		}
	}
}



void TestList()
{
	list_element *p = NULL,*p8 = NULL;
	NODE  *q = NULL;
	int i,j,len;
	lstLibInit();
	///1
	lstInit(&list1);
	for (i = 0; i < 10; i++)
	{
		p = (list_element*)malloc(sizeof(list_element));
		if (p)
		{
			p->stu.id = i+100;
			sprintf(p->stu.name, "student%d", i+100);
			p->stu.age = 10 + i / 3;
			p->stu.sex = (i % 2==0) ? 'F' : 'M';
			lstAdd(&list1, (NODE*)p);//list1添加元素
		}
	}
	printf("%d\n\n", lstCount(&list1));
	Display(&list1);
	///2
	lstInit(&list2);
	for (j= 0; j < 5; j++) 
	{
		p = (list_element*)malloc(sizeof(list_element));
		if (p)
		{
			p->stu.id = j + 200;
			sprintf(p->stu.name, "student%d", j+200);
			p->stu.age = 10 + j / 3;
			p->stu.sex = (j % 2 == 0) ? 'F' : 'M';
			lstAdd(&list2, (NODE*)p);//list2添加元素
		}
	}
	lstConcat(&list1,&list2);
	printf("%d\n\n", lstCount(&list1));

	///3
	p = (list_element*)lstLast(&list1);//得到list1的最后一个元素,与lstFirst不同
	if (p)
	{
		printf("id = %d, name = %s, age = %d\n\n", p->stu.id, p->stu.name, p->stu.age);
	}
	///4
	p = (list_element*)lstGet(&list1);//得到第一个元素,并从链表中删除,与lstFirst不同
	if (p)
	{
		printf("id = %d, name = %s, age = %d\n\n", p->stu.id, p->stu.name, p->stu.age);
		free(p);//需要手动free
	}
	///5
	p = (list_element*)lstFirst(&list1);//得到list1的第一个元素
	if (p)
	{
		printf("id = %d, name = %s, age = %d\n\n", p->stu.id, p->stu.name, p->stu.age);
	}
	///6
	p = (list_element*)lstNStep((NODE*)p, 2);//得到P后面第2个元素
	if (p)
	{
		printf("id = %d, name = %s, age = %d\n\n", p->stu.id, p->stu.name, p->stu.age);
	}
	///7得到第N个元素
	p = (list_element*)lstNth(&list1, 3);
	if (p)
	{
		printf("id = %d, name = %s, age = %d\n\n", p->stu.id, p->stu.name, p->stu.age);
	}
	///8
	printf("%d\n",lstFind(&list1, (NODE*)p));//lstlib计数从1开始

	printf("********************************************************\n");
	///9插入
	p8 = (list_element*)malloc(sizeof(list_element));
	if (p8) {
		p8->stu.id = 900;
		sprintf(p8->stu.name, "student%d", 900);
		p8->stu.age = 20;
		p8->stu.sex = 'M';
	}
	lstInsert(&list1, (NODE*)p, (NODE*)p8);
	printf("%d\n", lstCount(&list1));
	printf("********************************************************\n");
	///10删除某一个元素
	lstDelete(&list1, (NODE*)p8);
	free(p8);
	printf("%d\n", lstCount(&list1));
	printf("********************************************************\n");
	///11清空数据链表
	lstFree(&list1);
	printf("%d\n", lstCount(&list1));
}

int main()
{
	TestList();
	return 1;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值