1. 程式人生 > >c語言List標頭檔案和應用

c語言List標頭檔案和應用

util_list.h
#ifndef __UTIL_LIST__
#define __UTIL_LIST__


/*雙鏈節點*/
typedef struct list_node
{
	list_node * prev;
	list_node * next;
} LIST_NODE;

/*單鏈節點*/
typedef struct slist_node
{
	slist_node * next;
} SLIST_NODE;


#define lst_offsetof( type, member )  ( unsigned int )( &((type*)0)->member )

/* 初始化雙鏈節點*/
#define lst_init( list )       { (list)->next = (list)->prev = list; }

/* 判斷雙鏈是否為空,1:為空,0:不為空 */
#define lst_empty( list )      ( ( (list) == (list)->next ) ? 1 : 0 )

/* 在連結串列list頭部增加節點 */
#define lst_add(list, node)    { (list)->next->prev = (node); (node)->next = (list)->next; (list)->next = (node); (node)->prev = (list); }

/* 在連結串列list尾部增加節點 */
#define lst_insert(list, node) { (list)->prev->next = (node); (node)->prev = (list)->prev; (list)->prev = (node); (node)->next = (list); }

/* 刪除雙鏈節點 */
#define lst_del(node)          { (node)->prev->next = (node)->next; (node)->next->prev = (node)->prev; }

/* 從雙鏈節點得到例項節點 */
#define lst_entity(node, type, member) ((type*)((char *)(node) - lst_offsetof( type, member )))

/* 初始化雙鏈節點*/
#define slst_init(list)              { (list)->next =  (list); }

/* 判斷單鏈是否為空,1:為空,0:不為空 */
#define slst_empty(list)             (((list) == (list)->next ) ? 1 : 0 )

/* 在連結串列list頭部增加節點 */
#define slst_add(list, node)         { (node)->next = (list)->next; (list)->next = (node); }

/* 刪除單鏈節點,prev是node的前節點,由呼叫者保證 */
#define slst_del_prev( prev, node )  { (prev)->next = (node)->next; }

/* 刪除單鏈節點 */
#define slst_del( node ) \
{ \
	slist_node * p    = (node)->next; \
	slist_node * prev = (node); \
    while (( node ) != p)\
		{ prev = p; p = p->next; }\
	slst_del_prev( prev, node );\
}

/* 從單鏈節點得到例項節點 */
#define slst_entity(node, type, member) ((type*)((char *)(node) - lst_offsetof(type, member)))

#endif  /* __UTIL_LIST__ */

實際應用

TestList2.cpp

// TestList2.cpp : 定義控制檯應用程式的入口點。
//

#include "stdafx.h"
#include "stdlib.h"
#include "util_list.h"

LIST_NODE   g_TestNodeList     = { 0 };
SLIST_NODE  g_slstTestNodeList = { 0 };

typedef struct test_node
{
	LIST_NODE  ltNeigbor;
	SLIST_NODE sltNeigbor;

	int test_number;
} TEST_NODE;


int _tmain(int argc, _TCHAR* argv[]) 
{
	lst_init(&g_TestNodeList);
	slst_init(&g_slstTestNodeList);

	TEST_NODE * pstTestNode1 = (TEST_NODE *)malloc(sizeof(TEST_NODE));
	pstTestNode1->test_number = 100;	
	lst_add( &g_TestNodeList, &(pstTestNode1->ltNeigbor));
	//lst_insert(&g_TestNodeList, &(pstTestNode1->ltNeigbor));
	slst_add(&g_slstTestNodeList, &(pstTestNode1->sltNeigbor));

	TEST_NODE * pstTestNode2 = (TEST_NODE *)malloc(sizeof(TEST_NODE));
	pstTestNode2->test_number = 101;
	//lst_add( &g_TestNodeList, &(pstTestNode2->ltNeigbor));
	lst_insert(&g_TestNodeList, &(pstTestNode2->ltNeigbor));
	slst_add(&g_slstTestNodeList, &(pstTestNode2->sltNeigbor));

	TEST_NODE * pstTestNode3 = (TEST_NODE *)malloc(sizeof(TEST_NODE));
	pstTestNode3->test_number = 102;
	lst_add(&g_TestNodeList, &(pstTestNode3->ltNeigbor));
	//lst_insert(&g_TestNodeList, &(pstTestNode3->ltNeigbor));
	slst_add(&g_slstTestNodeList, &(pstTestNode3->sltNeigbor));

	LIST_NODE * pHead = &g_TestNodeList;
	LIST_NODE * pNext = pHead->next;

	while ( pNext != pHead )
	{
		TEST_NODE * pstTestNode100 = lst_entity( pNext, TEST_NODE, ltNeigbor );	
		lst_del(&( pstTestNode100->ltNeigbor ));
		pNext = pNext->next;
	}

	if (lst_empty( &g_TestNodeList ))
	{
		printf( "test ok" );
	}

	SLIST_NODE * psltHead = &g_slstTestNodeList;
	SLIST_NODE * psltNext = psltHead->next;
	SLIST_NODE * psltPrev = psltHead;

	while ( psltNext != psltHead )
	{
		TEST_NODE * pstTestNode101 = slst_entity( psltNext, TEST_NODE, sltNeigbor);

		if ( pstTestNode101->test_number == 102 )
		{
			slst_del_prev(psltPrev, &(pstTestNode101->sltNeigbor));
		}
		else
		{
			psltPrev = psltNext;
		}

		psltNext = psltNext->next;
	}

	slst_del( &( pstTestNode1->sltNeigbor ));
	slst_del( &( pstTestNode2->sltNeigbor ));

	if (slst_empty( &g_slstTestNodeList ))
	{
		printf("test2 ok");
	}

	free( pstTestNode1 );
	free( pstTestNode2 );
	free( pstTestNode3 );
	return 0;
}