c语言List头文件和应用

c语言List头文件和应用util_list.h#ifndef__UTIL_LIST__#define__UTIL_LIST__/*双链节点*/typedefstructlist_node{ list_node*prev; list_node*next;}LIST_NODE;/*单链节点*/typedefstructslist_node{ slist_node*ne

大家好,又见面了,我是你们的朋友全栈君。

util_list.h

#ifndef __UTIL_LIST__
#define __UTIL_LIST__


/*双链节点*/
typedef struct list_node
{
	struct list_node * prev;
	struct list_node * next;
} LIST_NODE;

/*单链节点*/
typedef struct slist_node
{
	struct 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;
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/157946.html原文链接:https://javaforall.net

(0)
上一篇 2022年7月12日 下午3:46
下一篇 2022年7月12日 下午3:46


相关推荐

  • Java常见的8种数据结构「建议收藏」

    Java常见的8种数据结构「建议收藏」数据结构是指数据在计算机内存空间中或磁盘中的组织形式算法是完成特定任务的过程二分法查找r=2^ss:查找步数r查找范围幂函数s=log2®已知范围获取需要的次数对数算法复杂度使用O(N)函数进行标示主要是去除常数看运行时间受数据项个数的影响常见排序参考地址https://blog.csdn.net/muranfei/article/details/80923996栈对列优先级对列栈按照“后进先出”、“先进后出”的原则来存储数据,先插入的数…

    2022年7月7日
    24
  • arcgis不闭合线转面_ArcGIS线转面的方法

    arcgis不闭合线转面_ArcGIS线转面的方法ArcGIS 作为 GIS 软件中的龙头老大 其功能是非常强大的 但是如果作为一个初学者 其部分常用的重要功能不容易掌握 今天就讲一讲在矢量化时非常重要的功能 线转面 ArcGIS 在进行大范围的矢量化时一般很少直接画多边形 这是因为 shape 文件不具备拓扑 在处理多个相邻多边形时不方便 因此 一般是先用线把地类图斑勾绘出来 然后将线转为多边形 在 ArcGIS 中 将线转为多边形有三种方法 1 Featu

    2026年3月19日
    7
  • npm使用淘宝镜像(npm切换淘宝镜像)

    1.通过cnpm使用淘宝镜像:npminstall-gcnpm–registry=https://registry.npm.taobao.org2.将npm设置为淘宝镜像:npmconfigsetregistryhttps://registry.npm.taobao.org3.查看cnpm镜像设置:cnpmconfiggetregistry

    2022年4月10日
    362
  • 什么是双线双IP和双线单IP

    什么是双线双IP和双线单IP一般我们比较推荐的双线接入 不是说简单的将电信 网通两根线路直接接到服务器上 而是通过相关的网络设备和技术手段来实现的 首先 通过网通和电信节点接入双线到机房 再接入相关网络设备 并进行相关设置 通过网络设备来实现智能路由 在服务器上只需要一个 IP 一根线接入 即可实现一个 IP 上

    2026年3月19日
    2
  • js生成二维码小工具图片_二维码生成规则

    js生成二维码小工具图片_二维码生成规则js完整代码,引用了qrcode.min.js,jquery.min.js效果图连接别忘记加上http://哦代码中引用的qrcode.min.js,jquery.min.js可以去网上百度下载<!DOCTYPEhtml><htmllang=”en”><head><metacharset=”UTF-8″><metahttp-equiv=”X-UA-Compatible”content=”IE=edge”>

    2022年10月18日
    2
  • VXLAN基本概述

    VXLAN基本概述

    2021年4月16日
    162

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号