一種基於雙向鏈表設計的map數據存儲操作接口(加入類迭代器設計)

源碼的下載地址:https://download.csdn.net/download/xiyuan255/12372494

/*
 * File name	: xy_list_code.c
 *
 * Created on	: 2019年8月29日10:39:35
 * Author		  : Firmware of xiyuan255
 * Version		: 2.0
 * Language		: C
 * Copyright	: Copyright (C) 2019, xiyuan255 Inc.
 *
 */
#include <stdio.h>
#include <malloc.h>
#include "xy_cmap_source.h"

typedef struct s_map_list
{
	PCPAIR_T ptr_data;
	struct s_map_list *ptr_prev;
	struct s_map_list *ptr_next;
	
} map_list_t, *map_list_p;

typedef struct _s_cmap_
{
	map_list_p	ptr_head;	/**< map_list_p鏈表的頭指針 */
	map_list_p	ptr_tail;	/**< map_list_p鏈表的尾指針 */
	c_compare_t	compare;	/**< map容器的比較函數指針 */
	
} cmap_t, *cmap_p;

#define CMAP_HEAD(cmap)		( ((cmap_p)cmap)->ptr_head )
#define CMAP_TAIL(cmap)		( ((cmap_p)cmap)->ptr_tail )
#define CMAP_COMPARE(cmap)	( ((cmap_p)cmap)->compare )

/** 
 * \brief 通過迭代器指針解析數據指針
 * \param ptr_iterator	[in] 參數名稱,迭代器指針
 * \return
 *			!NULL 	: 數據指針			\n
 *			NULL	: 不存在	\n
 */
__STATIC PDATA_T c_map_data(PITERATOR_T iterator)
{
	return ( (NULL != iterator)? (((map_list_p)iterator)->ptr_data) : NULL );
}

/** 
 * \brief 獲取迭代器的前一個指針
 * \param ptr_iterator	[in] 參數名稱,迭代器指針
 * \return
 *			!NULL 	: 迭代器指針			\n
 *			NULL	: 不存在	\n
 */
__STATIC void c_map_prev(PITERATOR_T ptr_iterator)
{		
	if (NULL != ptr_iterator)
	{
		ptr_iterator->_value = ((map_list_p)ptr_iterator->_value)->ptr_prev;
	}
}

/** 
 * \brief 獲取迭代器的後一個指針
 * \param ptr_iterator	[in] 參數名稱,迭代器指針
 * \return
 *			!NULL 	: 迭代器指針			\n
 *			NULL	: 不存在	\n
 */
__STATIC void c_map_next(PITERATOR_T ptr_iterator)
{	
	if (NULL != ptr_iterator)
	{
		ptr_iterator->_value = ((map_list_p)ptr_iterator->_value)->ptr_next;
	}
}

/** 
 * \brief 判斷兩個迭代器指針是否相等
 * \param ptr_iter1	[in] 參數名稱,迭代器指針1 
 * \param ptr_iter2	[in] 參數名稱,迭代器指針2
 * \return
 *			true 	: 相等	\n
 *			false	: 不相等	\n
 */
__STATIC boolean c_map_equal(PITERATOR_T ptr_iter1, PITERATOR_T ptr_iter2)
{	
	return (  (ptr_iter1 && ptr_iter2) && (ptr_iter1->_value == ptr_iter2->_value) );
}

__STATIC iterator_ft sg_map_iterator = 
{
		c_map_data,
		c_map_prev,
		c_map_next,
		c_map_equal,
};

/** 
 * \brief 初始化CMAP對象 
 * \param compare	[in] 參數名稱,比較函數
 * \return
 *		!NULL	: 成功返回句柄		\n
 *	   	NULL	: 初始化失敗			\n
 */
PUBLIC CMAP c_map_init(c_compare_t compare)
{
	cmap_t *cmap = NULL;

	cmap = (cmap_t *)calloc(sizeof(char), sizeof(cmap_t)); 
	if (NULL == cmap) {
		return NULL;
	}
	cmap->ptr_head = (map_list_p)cmap;
	cmap->ptr_tail = (map_list_p)cmap;
	cmap->compare  = compare;

	return (CMAP)cmap;
}

/** 
 * \brief 清空CMAP對象 
 * \param cmap	[in] 參數名稱,CMAP對象
 * \return
 */
PUBLIC void c_map_clear(CMAP cmap)
{	
	map_list_p ptr_node1 = NULL;
	map_list_p ptr_node2 = CMAP_HEAD(cmap);

	while (ptr_node2 != NULL)
	{
		ptr_node1 = ptr_node2->ptr_next;
		free(ptr_node2);
		ptr_node2 = ptr_node1;
	}

	CMAP_TAIL(cmap) = cmap;
	CMAP_HEAD(cmap)	= cmap;
}

/** 
 * \brief 銷燬CMAP對象 
 * \param ptr_cmap	[in] 參數名稱,CMAP對象指針
 * \return
 */
PUBLIC void c_map_destroy(CMAP *ptr_cmap)
{
	if (NULL != ptr_cmap)
	{		
		c_map_clear(*ptr_cmap);
		
		free(*ptr_cmap);
		*ptr_cmap = NULL;
	}
}

/** 
 * \brief 計算CMAP對象的長度 
 * \param cmap	[in] 參數名稱,CMAP對象
 * \return
 * 		返回對象長度
 */
PUBLIC int c_map_size(CMAP cmap)
{	
	int count = 0;
	map_list_p ptr_node = CMAP_HEAD(cmap);

	while (ptr_node != cmap)
	{
		count++;
		ptr_node = ptr_node->ptr_next;
	}
	
	return count;
}

/** 
 * \brief 判斷CMAP對象的是否爲空 
 * \param cmap	[in] 參數名稱,CMAP對象
 * \return
 *		   true    : 爲空    \n
 *		   false   : 不爲空 \n
 */
PUBLIC boolean c_map_empty(CMAP cmap)
{	
	return ( (NULL == cmap || cmap == CMAP_HEAD(cmap)) ? true : false );
}

/** 
 * \brief 獲取CMAP對象的頭迭代器 
 * \param cmap	[in] 參數名稱,CMAP對象
 * \return
 * 		返回對象的頭迭代器
 */
PUBLIC ITERATOR_T c_map_begin(CMAP cmap)
{
	ITERATOR_T iterator = {NULL, cmap};
	
	if (NULL != cmap)
	{
		iterator._pft = &sg_map_iterator;
		iterator._value = CMAP_HEAD(cmap);
	}

	return iterator;
}

/** 
 * \brief 獲取CMAP對象的尾迭代器 
 * \param cmap	[in] 參數名稱,CMAP對象
 * \return
 * 		返回對象的尾迭代器
 */
PUBLIC ITERATOR_T c_map_tail(CMAP cmap)
{
	ITERATOR_T iterator = {NULL, cmap};
	
	if (NULL != cmap)
	{
		iterator._pft = &sg_map_iterator;
		iterator._value = CMAP_TAIL(cmap);
	}

	return iterator;
}

/** 
 * \brief 獲取CMAP對象的結束迭代器 
 * \param cmap	[in] 參數名稱,CMAP對象
 * \return
 * 		返回對象的結束迭代器
 */
PUBLIC ITERATOR_T c_map_end(CMAP cmap)
{	
	ITERATOR_T iterator = {NULL, cmap};

	return iterator;
}

/** 
 * \brief 向CMAP對象插入數據
 * \param cmap		[in] 參數名稱,CMAP對象
 * \param ptr_data	[in] 參數名稱,數據指針
 * \return
 * 		-1	: 動態內存分配失敗
 * 		 0	: 插入成功
 */
PUBLIC int c_map_insert(CMAP cmap, const PCPAIR_T ptr_data)
{
	map_list_p ptr_node = CMAP_HEAD(cmap); // 取頭結點指針
	map_list_p ptr_new  = (map_list_p)calloc(sizeof(char), sizeof(map_list_t));
	if (NULL == ptr_new) {
		c_error("[%s, %s, %d] memory allocation failed.\n", __FILE__, __FUNCTION__, __LINE__);
		return -1;
	}
	
	ptr_new->ptr_data = ptr_data;

	if (cmap == CMAP_HEAD(cmap))
	{
		ptr_new->ptr_next = (map_list_p)cmap;
		ptr_new->ptr_prev = (map_list_p)cmap;
		CMAP_HEAD(cmap) = ptr_new;
		CMAP_TAIL(cmap) = ptr_new;
	}
	else
	{
		while (ptr_node->ptr_next != cmap) {
			ptr_node = ptr_node->ptr_next;
		}
		ptr_new->ptr_prev  = ptr_node;
		ptr_new->ptr_next  = (map_list_p)cmap;
		ptr_node->ptr_next = ptr_new;
	}
		
	return 0;
}

/** 
 * \brief 擦除CMAP對象的數據
 * \param cmap		[in] 參數名稱,CMAP對象
 * \param position	[in] 參數名稱,迭代器指針 
 * \return
 */
PUBLIC void c_map_erase(CMAP cmap, PITERATOR_T position)
{
	map_list_p ptr_node = NULL;
	
	if (NULL != cmap && ptr_node != cmap)
	{		
		ptr_node = (map_list_p)(position->_value); 	
		if (ptr_node == CMAP_HEAD(cmap))
		{
			if (CMAP_HEAD(cmap) == CMAP_TAIL(cmap))
			{
				CMAP_HEAD(cmap) = (map_list_p)cmap;
				CMAP_TAIL(cmap) = (map_list_p)cmap;
			}
			else
			{
				ptr_node->ptr_next->ptr_prev = (map_list_p)cmap;
				CMAP_HEAD(cmap) = ptr_node->ptr_next;
			}			
		}
		else if (ptr_node == CMAP_TAIL(cmap))
		{
			ptr_node->ptr_prev->ptr_next = cmap;
			CMAP_TAIL(cmap) = ptr_node->ptr_prev;
		}
		else
		{
			ptr_node->ptr_prev->ptr_next = ptr_node->ptr_next;
		}
		
		free(ptr_node);
	}
}

/** 
 * \brief 查找與ptr_key相同的數據指針
 * \param cmap		[in] 參數名稱,CMAP對象
 * \param ptr_key	[in] 參數名稱,KEY值 
 * \param keylen	[in] 參數名稱,KEY值的長度
 * \return 
 *			!NULL	: 存在		\n
 *		    NULL	: 不存在	\n
 */
PUBLIC PCPAIR_T c_map_find(CMAP cmap, PKEY_T ptr_key, int keylen)
{
	map_list_p ptr_node = NULL;
	
	CHECK_PARAM_IS_NULL_RET(cmap, NULL);		
	CHECK_PARAM_IS_NULL_RET(CMAP_COMPARE(cmap), NULL);

	for (ptr_node = CMAP_HEAD(cmap); ptr_node != cmap; ptr_node = ptr_node->ptr_next)
	{
		if (0 == CMAP_COMPARE(cmap)(ptr_key, ptr_node->ptr_data->first, keylen))
		{
			return ptr_node->ptr_data;
		}
	}	
	return NULL;
}

/** 
 * \brief 刪除與ptr_key相同的數據指針
 * \param cmap		[in] 參數名稱,CMAP對象
 * \param ptr_key	[in] 參數名稱,KEY值 
 * \param keylen	[in] 參數名稱,KEY值的長度
 * \return 
 *		cmap對象剩餘的長度	\n
 */
PUBLIC int c_map_delete(CMAP cmap, PKEY_T ptr_key, int keylen)
{
	map_list_p ptr_node = NULL;
	ITERATOR_T iterator = {NULL, cmap};
	
	CHECK_PARAM_IS_NULL_RET(cmap, 0);		
	CHECK_PARAM_IS_NULL_RET(CMAP_COMPARE(cmap), 0);

	for (ptr_node = CMAP_HEAD(cmap); ptr_node != cmap; ptr_node = ptr_node->ptr_next)
	{
		if (0 == CMAP_COMPARE(cmap)(ptr_key, ptr_node->ptr_data->first, keylen)) {
			break;
		}
	}	
	iterator._value = ptr_node;
	c_map_erase(cmap, &iterator);
	
	return c_map_size(cmap);
}

/** 
 * \brief 遍歷CMAP對象的數據
 * \param cmap		[in] 參數名稱,CMAP對象
 * \param print_data   [in] 參數名稱,數據對應的打印函數 
 * \return
 */
PUBLIC void c_map_traverse(CMAP cmap, c_print_data_t print_data)
{
	map_list_p ptr_node = NULL;

	if (NULL != cmap)
	{
		for (ptr_node = CMAP_HEAD(cmap); ptr_node != cmap; ptr_node = ptr_node->ptr_next)
		{
			if (print_data)
			{
				print_data(ptr_node->ptr_data);
			}
		}	
	}
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章