1. 程式人生 > >資料結構體模版---迴圈單鏈表

資料結構體模版---迴圈單鏈表

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>

//#define DEBUG				// 除錯插樁資訊巨集

///*////////////////////////////////////////////////////////////////////////////
///
///	帶頭結點的單鏈表結構體
///
///*////////////////////////////////////////////////////////////////////////////
typedef int ElemType;		// 自定義資料型別

//typedef struct CirLinkListNode*	PCirLinkListNode;			// 連結串列結點指標域

// 連結串列結點資料域
typedef struct CirLinkListNode
{
	ElemType				m_data;			// 資料域
	struct CirLinkListNode	*m_next;		// 指標域
}CirLinkListNode;

// 帶頭結點的單項鍊表
typedef struct CirLinkList
{
	CirLinkListNode	*m_head;				// 連結串列頭結點
	CirLinkListNode *m_tail;				// 迴圈連結串列尾部
	int				m_length;				// 單鏈表資料結點個數指標域
//  this->m_head == this->m_tail->m_next;	// 如果只設尾結點要理解此等價關係
}CirLinkList;



///*////////////////////////////////////////////////////////////////////////////
///
///	建立和初始化單鏈表
///
///	開闢一個單鏈表資料結構,並初始化頭結點,然後將建立好的單鏈表指標返回
///	CirLinkList* CreatCirLinkList(void)
///
///	初始化單鏈表
///	void InitCirLinkList(CirLinkList *list)
///*///////////////////////////////////////////////////////////////////////////

/**
CirLinkList* CreatCirLinkList(void)
引數
	list	:	指向一個連結串列指標,此處傳入表頭地址
返回值
	若成功返回建立好的單鏈表的指標
功能
	開闢一個單鏈表資料結構,並初始化頭結點,然後將建立好的單鏈表指標返回
注意
	使用CreateCirLinkList建立的單鏈表,需要用DestroyCirLinkList來銷燬
	以免發生記憶體洩漏
*/
CirLinkList* CreateCirLinkList(void)
{
	CirLinkList *list = NULL;
	if((list = (CirLinkList *)malloc(sizeof(CirLinkList))) == NULL)		// 開闢單鏈表的空間
	{	// 開闢失敗
        fprintf(stderr, "not enough memory when CREATE LIST...\n");
        exit(EXIT_FAILURE);
	}

	InitCirLinkList(list);				// 初始化單鏈表

	return list;
}



/**
void InitCirLinkList(CirLinkList *list)
引數
	list	:	指向一個連結串列指標,此處傳入表頭地址
返回值
	無
功能
	初始化單鏈表, 執行以下操作
	①開闢頭結點的空間 ②進行必要的初始化[頭結點的初始化和單鏈表結點數目的初始化]
注意
	使用InitCirLinkList初始化的單鏈表(初始化時malloc了頭結點m_head的空間)
	而使用用FinitCirLinkList來進行後處理(後處理時free了頭結點的m_head空間)
	以免發生記憶體洩漏
*/
void InitCirLinkList(CirLinkList *list)
{
	if((list->m_head = malloc(sizeof(CirLinkListNode))) == NULL)		// 為頭結點開闢空間
	{	// 開闢失敗
        fprintf(stderr, "not enough memory when MALLOC HEAD...");
        exit(EXIT_FAILURE);
	}

	// 初始化頭結點資訊
	list->m_head->m_next = list->m_head;	// 初始化只有頭結點[空迴圈連結串列的特徵]
	list->m_head->m_data = 0;				// 資料元素個數為0
	list->m_length = 0;						// 資料元素個數為0
	list->m_tail = list->m_head;			// 尾指標指向頭結點
}

///*////////////////////////////////////////////////////////////////////////////
///
///	銷燬以及後處理單鏈表
///
///	銷燬用CreateCirLinkList建立的單鏈表
///	void DestroyCirLinkList(CirLinkList *list)
///
///	後處理單鏈表,
///	void FinitCirLinkList(CirLinkList *list)
///
/// 清空單鏈表中的所有元素
///	void ClearCirLinkList(CirLinkList *list)
///*////////////////////////////////////////////////////////////////////////////

/**
void DestroyCirLinkList(CirLinkList *list)
引數
	list	:	指向一個連結串列指標,此處傳入表頭地址
返回值
	無
功能
	銷燬用CreateCirLinkList建立的單鏈表,執行以下操作
	①清空單鏈表	②釋放頭結點	③釋放單鏈表
注意
	使用CreateCirLinkList建立的單鏈表,需要用DestroyCirLinkList來銷燬
	以免發生記憶體洩漏
*/
CirLinkList* DestroyCirLinkList(CirLinkList *list)
{
	ClearCirLinkList(list);			// 清空連結串列
	FinitCirLinkList(list);			// 銷燬頭結點
	if(list != NULL)				// 銷燬連結串列的空間
	{
		free(list);
		list = NULL;
	}
}





/**
void FinitCirLinkList(CirLinkList *list)
引數
	list	:	指向一個連結串列指標,此處傳入表頭地址
返回值
	無
功能
	後處理單鏈表, 執行以下操作
	①開闢頭結點的空間 ②進行必要的初始化[頭結點的初始化和單鏈表結點數目的初始化]
注意
	使用InitCirLinkList初始化的單鏈表(初始化時malloc了頭結點m_head的空間)
	而使用用FinitCirLinkList來進行後處理(後處理時free了頭結點的m_head空間)
	以免發生記憶體洩漏
*/
void FinitCirLinkList(CirLinkList *list)
{
	assert(list->m_head->m_next == list->m_head);		// 後處理指標針對空連結串列
	// assert(list->m_length == 0);
	if(list->m_head != NULL)			// 如果此時頭結點空間未被銷燬
	{
		free(list->m_head);

		list->m_head = NULL;
		list->m_length = -1;			// 未經初始化的單鏈表元素個數記為-1
	}
}



/**
void ClearCirLinkList(CirLinkList *list)
引數
	list	:	指向一個連結串列指標,此處傳入表頭地址
返回值
	無
功能
	清空單鏈表中的所有元素
*/
void ClearCirLinkList(CirLinkList *list)
{
	while(list->m_head->m_next != list->m_head)
	{
        DeleteNode(list, 0);
	}
}

///*////////////////////////////////////////////////////////////////////////////
///
///	查詢函式
///
///	查詢到連結串列list中第position個結點
///	CirLinkListNode* FindPosNode(CirLinkList *list, int position)
///
///	在連結串列list中找到currNode的前一個結點
///	CirLinkListNode *FindPrevNode(CirLinkList *list, CirLinkListNode *currNode)
///
/// 判斷結點node指向的區域是不是連結串列中的結點
///	int IsNodeInList(CirLinkList *list, CirLinkListNode *node)
///
///	找到資料域為data的結點首次出現的位置並返回結點資訊
///	CirLinkListNode* FindDataNode(CirLinkList *list, ElemType data, int *position)
///*////////////////////////////////////////////////////////////////////////////
/**
CirLinkListNode* FindPosNode(CirLinkList *list, int position)

引數
	list	:	指向一個連結串列指標,此處傳入表頭地址
	positon	:	帶查詢的連結串列指標的位置
返回值
	若成功返回指向待查詢結點的指標
	若失敗返回NULL
功能
	該函式的功能是:	查詢到連結串列list中第position個結點
*/
CirLinkListNode* FindPosNode(CirLinkList *list, int position)
{
	assert(list != NULL);									// 連結串列不能為空
	assert(position >= -1 && position < list->m_length);	// 插入的w位置只能在[-1~length]

	CirLinkListNode 	*pNode	= list->m_head->m_next;
//	CirLinkListNode *pNode = list->m_tail->m_next;			// 當迴圈連結串列只設尾指標時採用此程式碼

	if(position == -1)											// -1表示尋找頭指標的前驅
	{
		return list->m_head;								// 直接返回前驅
	}

    int 			pos 	= 0;

    while(pNode != list->m_head && pos < position)		// 遍歷單鏈表,找到第position個結點的位置
	{
		pNode = pNode->m_next;
		pos++;
	}

	if(pos < position)		// 如果找到連結串列尾部還沒有找到
	{
		return NULL;
	}
	else
	{
#ifdef DEBUG
		printf("Find the %d point SUCCESS...[%p]\n", position, pNode);
#endif // DEBUG
		return pNode;
	}
}

/**
CirLinkListNode *FindPrevNode(CirLinkList *list, CirLinkListNode *currNode);

引數
	list		:	指向一個連結串列指標,此處傳入表頭地址
	currNode	:	待查詢的連結串列指標的位置
返回值
	若成功返回指向待查詢結點的指標
	若失敗返回NULL
功能
	在連結串列list中找到currNode的前一個結點
*/

CirLinkListNode *FindPrevNode(CirLinkList *list, CirLinkListNode *currNode)
{
	assert(list != 	NULL);
	assert(currNode != NULL);

	CirLinkListNode *pNode = list->m_head;
//	CirLinkListNode *pNode = list->m_tail->m_next;			// 當迴圈連結串列只設尾指標時採用此程式碼

	while(pNode->m_next != list->m_head && pNode->m_next != currNode)
	{
		pNode = pNode->m_next;
	}

	if(pNode->m_next == currNode)				// 查詢成功
	{
		return pNode;
	}
	else										// 查詢失敗
	{
		return NULL;
	}
}



/**
int IsNodeInList(CirLinkList *list, CirLinkListNode *node)

引數
	list	:	指向一個連結串列指標,此處傳入表頭地址
	node	:	指向待查詢的結點的指標
返回值
	若成功 返回結點node在連結串列中的位置
	若失敗 返回-1
功能
	判斷結點node指向的區域是不是連結串列中的結點
*/
int IsNodeInList(CirLinkList *list, CirLinkListNode *node)
{
	assert(list != NULL);									// 連結串列不能為空	assert(Node != NULL);									// 待查詢的指標不能為空

	CirLinkListNode 	*pNode	= list->m_head->m_next;
//	CirLinkListNode *pNode = list->m_tail->m_next;			// 當迴圈連結串列只設尾指標時採用此程式碼
    int 			pos 	= 0;

    while(pNode != list->m_head && pNode != node)		// 遍歷單鏈表,找到第position個結點的位置
	{
		pNode = pNode->m_next;
		pos++;
	}

	if(pNode != node)
	{	// 查詢成功
		return -1;
	}
	else
	{	// 查詢失敗
#ifdef DEBUG
		printf("Find the [%p] point in the first %d pointer of the list...\n", fNode, pos);
#endif // DEBUG
		return pos;
	}
}


/**
CirLinkListNode* FindDataNode(CirLinkList *list, ElemType data, int *position

引數
	list	:	指向一個連結串列指標,此處傳入表頭地址
	data	:	待查詢的結點的資料資訊
返回值
	若成功 返回結點node在連結串列中的位置
	若失敗 返回-1
功能
	找到資料域為data的結點首次出現的位置並返回結點資訊
*/
CirLinkListNode* FindDataNode(CirLinkList *list, ElemType data, int *position)
{
	CirLinkListNode *node = list->m_head->m_next;
//	CirLinkListNode *pNode = list->m_tail->m_next;			// 當迴圈連結串列只設尾指標時採用此程式碼

	int pos = 0;
	while(node != list->m_head && node->m_data != data)
	{
		node = node->m_next;
		pos++;
	}
	*position = pos;				// 將出現的位置傳遞回去

	return node;					// 返回結點的資訊
}


///*////////////////////////////////////////////////////////////////////////////
///
///	插入函式
///
///	將資料data插入連結串列的prevNode結點的下一個位置個位置
///	CirLinkListNode *AddNode(CirLinkList *list, CirLinkListNode *prevNode, ElemType data)
///
///	將資料data插入連結串列的第position個位置
///	CirLinkListNode *InsertNode(CirLinkList *list, int position, ElemType data)
///*////////////////////////////////////////////////////////////////////////////


/**
CirLinkListNode* AddNode(CirLinkList *list, CirLinkListNode *prevNode, ElemType data);
引數
	list		:	指向一個連結串列指標,此處傳入表頭地址
	prevNode	:	待插入位置的前一個結點
	data		:	待插入結點的資料
返回值
	無
功能
	該函式的功能是:	將資料data插入連結串列的prevNode結點的下一個位置個位置
*/
CirLinkListNode* AddNode(CirLinkList *list, CirLinkListNode *prevNode, ElemType data)
{
	assert(prevNode != NULL);						// 插入點不能是空指標

	CirLinkListNode *newNode = NULL;

	if((newNode = (CirLinkListNode *)malloc(sizeof(CirLinkListNode))) == NULL)	// 為新結點開闢空間
	{	// 開闢新結點失敗
		fprintf(stderr, "not enough memeory\n");
        exit(EXIT_FAILURE);
	}
	else
	{
		// 開闢新結點成功
		newNode->m_data = data;
		newNode->m_next = NULL;
	}

	// 將指標newNode連線在pNode的後面
	newNode->m_next = prevNode->m_next;
	prevNode->m_next = newNode;

	list->m_length++;				// 結點數目增加一個
	list->m_head->m_data++;			// 頭結點的資料域同樣儲存著結點總數
	//}
#ifdef DEBUG
	printf("The new node is inserted after point pointer[%p]\n", pNode);
#endif // DEBUG
	return newNode;
}


/**
void InsertNode(CirLinkList *list, int position, ElemType data)
引數
	list	:	指向一個連結串列指標,此處傳入表頭地址
	positon	:	待插入結點的位置
	data	:	待插入結點的資料
返回值
	無
功能
	該函式的功能是:	將資料data插入連結串列的第position個位置
*/
CirLinkListNode* InsertNode(CirLinkList *list, int position, ElemType data)
{
	assert(list != NULL);
	assert(position >=0 && position < list->m_length + 1);

	CirLinkListNode *prevNode = FindPosNode(list, position - 1);			// 找到待插入位置的前一個結點
	CirLinkListNode *newNode = NULL;

	// 下面呼叫InsertPointNode直接將結點插入到pNode結點後面
	if((newNode = AddNode(list, prevNode, data)) != NULL)	// 將新的結點插入到待插入前一個指標的後面
	{	// 插入成功
		return newNode;								// 返回新插入的結點
#ifdef DEBUG
		printf("Insert the value %d into list at position %d...\n", data, position);
#endif // DEBUG
	}
	else
	{
		return NULL;								// 插入失敗返回NULL
	}

//	//	以可以使用下面的程式碼
//	if((newNode = (CirLinkListNode *)malloc(sizeof(CirLinkListNode))) == NULL)	// 為新結點開闢空間
//	{	// 開闢新結點失敗
//		fprintf(stderr, "not enough memeory\n");
//        exit(EXIT_FAILURE);
//	}
//	else
//	{	// 開闢新結點成功
//	newNode->m_data = data;
//	newNode->m_next = NULL;
//
//	// 將指標newNode連線在pNode的後面
//	newNode->m_next = prevNode->m_next;
//	prevNode->m_next = newNode;
//
//	list->m_length++;				// 結點數目增加一個
//	list->m_head->m_data++;			// 頭結點的資料域同樣儲存著結點總數
//	}
}


///*////////////////////////////////////////////////////////////////////////////
///
///	刪除函式
///
///	刪除連結串列list中prevNode結點之後的指標個指標
///	void DeleteNode(CirLinkList *list, int position)
///
///	刪除連結串列list中prevNode結點之後的指標個指標
///	ElemType SubNode(CirLinkList *list, CirLinkListNode *prevNode)
///
///	刪除連結串列list中prevNode結點之後的指標個指標
///	ElemType DeleteCurrNode(CirLinkList *list, CirLinkListNode *currNode)
///*////////////////////////////////////////////////////////////////////////////

/**
void DeleteNode(CirLinkList *list, int position)
引數
	list	:	指向一個連結串列指標,此處傳入表頭地址
	positon	:	待刪除結點的位置
返回值
	返回待刪除結點的資料域
功能
	將單鏈表的第position個結點刪除
*/
ElemType DeleteNode(CirLinkList *list, int position)
{
	assert(list != NULL);
	assert(position >=0 && position < list->m_length);
	CirLinkListNode *prevNode = FindPosNode(list, position - 1);			// 找到第position - 1個結點

	// 刪除pNode的後一個結點
	CirLinkListNode *delNode = prevNode->m_next;
	ElemType delElem = delNode->m_data;
	prevNode->m_next = delNode->m_next;
	free(delNode);

	list->m_length--;				// 結點數目減少一個
	list->m_head->m_data--;			// 頭結點的資料域同樣儲存著結點總數

	return delElem;
}


/**
ElemType SubNode(CirLinkList *list, CirLinkListNode *prevNode)
引數
	list	:	指向一個連結串列指標,此處傳入表頭地址
	positon	:	待刪除結點的位置
返回值
	返回待刪除結點的資料域
功能
	刪除連結串列list中prevNode結點之後的指標個指標
*/
ElemType SubNode(CirLinkList *list, CirLinkListNode *prevNode)
{
	assert(list != NULL);						// 連結串列不能為空
	assert(prevNode != NULL);						// 待刪除結點的前一個位置不能為空
	assert(IsNodeInList(list, prevNode) != -1);	// 待刪除位置的前一個結點必須在連結串列中

	// 刪除pNode的後一個結點
	CirLinkListNode *delNode = prevNode->m_next;
	ElemType delElem = delNode->m_data;
	prevNode->m_next = delNode->m_next;
	free(delNode);

	list->m_length--;				// 結點數目減少一個
	list->m_head->m_data--;			// 頭結點的資料域同樣儲存著結點總數

	return delElem;
}



/**
ElemType DeleteCurrNode(CirLinkList *list, CirLinkListNode *currNode);
引數
	list	:	指向一個連結串列指標,此處傳入表頭地址
	positon	:	待刪除結點的位置
返回值
	返回待刪除結點的資料域
功能
	刪除連結串列list中prevNode結點之後的指標個指標
*/
ElemType DeleteCurrNode(CirLinkList *list, CirLinkListNode *currNode)
{
	assert(list != NULL);							// 連結串列不能為空
	assert(currNode != NULL);							// 待刪除結點的前一個位置不能為空
	assert(IsNodeInList(list, currNode) != -1);	// 待刪除的結點必須在連結串列中

	ElemType 			delElem = -1;							// 待刪除結點的資料域
	CirLinkListNode 	*delNode = NULL;					// 指向將要刪除的結點的指標

//	if(list->m_length == 0)
//	{
//
//		return -1;
//	}
//	printf("length = %d\n", list->m_length);
	if(currNode->m_next != list->m_head)					// 如果待刪除結點不是最後一個結點
	{
		// 將currNode的後一個結點delNode作為刪除結點,
		delNode = currNode->m_next;
		currNode->m_next = delNode->m_next;			//從連結串列中刪除delNode

		// 並將delNode的資料域儲存到delNode中
		delElem = currNode->m_data;					// delElem儲存currNode的資料域
		currNode->m_data = delNode->m_data;			// 真正刪除的結點其實是currNode下一個結點, 因此用currNode儲存下一個結點的資料域
	}
	else											// 否則待刪除結點是最後一個結點
	{
		// 直接將最後一個結點刪除即可, 應該把其前一個結點的指標域賦值為空
		delNode = currNode;
		// 下面應該將currnNode的前一個結點的指標域賦值為空[時間複雜度O(n)]
		CirLinkListNode *prevNode = FindPrevNode(list, currNode);
		prevNode->m_next = list->m_head;			/// BUG1  最後一個結點的後一個結點
	}
	free(delNode);
	list->m_length--;				// 結點數目減少一個
	list->m_head->m_data--;			// 頭結點的資料域同樣儲存著結點總數

	return delElem;
}




///*////////////////////////////////////////////////////////////////////////////
///
///	其他函式
///
///	顯示單鏈表的資訊
///	void ShowList(CirLinkList *list
///
///	刪除連結串列list中prevNode結點之後的指標個指標
///	void SetNode(CirLinkList *list, int position, ElemType data)
///
///	獲取單鏈表list第position個結點的資料域
/// ElemType GetNode(CirLinkList *list, int position)
///
///	獲取單鏈表list的長度[即元素個數]
///	int LengthCirLinkList(CirLinkList *list)
///
///	判斷當前連結串列是否是空連結串列
///	bool IsEmptyCirLinkList(CirLinkList *list)
///*////////////////////////////////////////////////////////////////////////////

/**
void ShowCirLinkList(CirLinkList *list)
引數
	list	:	指向一個連結串列指標,此處傳入表頭地址
返回值
	無
功能
	顯示單鏈表的資訊
*/
void ShowList(CirLinkList *list)
{
// assert(list->m_head != NULL)
	if(list->m_head ==  NULL)			//  單鏈表可能沒有被初始化
	{
		fprintf(stderr, "you can't SHOW the list without the list INITLINKLIST...\n");
		return ;
	}


	printf("there are %d data in list\n", list->m_length);
	if(list->m_length == 0)
	{
		return ;
	}

	CirLinkListNode *pNode = list->m_head->m_next;			// 從頭指標開始遍歷

	while(pNode != list->m_head)								//開始遍歷單鏈表
	{
		printf("%d  ", pNode->m_data);
        pNode = pNode->m_next;
	}
	printf("\n");

//	ElemType data;
//	for(int pos = 0; pos < list->m_length; pos++)
//	{
//		data = GetNode(list, pos);
//		printf("%d  ", data);
//	}
//	printf("\n");
}

/**
void SetNode(CirLinkList *list, int position, ElemType data)
引數
	list	:	指向一個連結串列指標,此處傳入表頭地址
	positon :	待修改的結點的資料
	data	:	待更正的新資料域
返回值
	無
功能
	修改單鏈表list第position個結點的資料域為data
*/
void SetNode(CirLinkList *list, int position, ElemType data)
{
	CirLinkListNode *pNode = FindPosNode(list, position);		// 找到單鏈表的第position個結點

	pNode->m_data = data;
}

/**
ElemType GetNode(CirLinkList *list, int position
引數
	list	:	指向一個連結串列指標,此處傳入表頭地址
	positon :	待查詢的結點的位置
返回值
	獲取到的結點資料
功能
	獲取單鏈表list第position個結點的資料域
*/
ElemType GetNode(CirLinkList *list, int position)
{
	CirLinkListNode *pNode = FindPosNode(list, position);		// 找到單鏈表的第position個結點

	return pNode->m_data;
}


/**
int LengthCirLinkList(CirLinkList *list)
引數
	list	:	指向一個連結串列指標,此處傳入表頭地址
返回值
	單鏈表的長度
功能
	獲取單鏈表的長度
*/
int LengthCirLinkList(CirLinkList *list)
{
	return list->m_length;
}


/**
bool IsEmptyCirLinkList(CirLinkList *list)
引數
	list	:	指向一個連結串列指標,此處傳入表頭地址
返回值
	如果單鏈表是空表,返回true
	否則返回false
功能
	獲取單鏈表的長度
*/
bool IsEmptyCirLinkList(CirLinkList *list)
{
    return (list->m_head->m_next == list->m_head);
//	return (list->m_tail == this->m_head);
}


/**
CirLinkListNode* GetFisrtNode(CirLinkList *list)
引數
	list	:	指向一個連結串列指標,此處傳入表頭地址
返回值
	返回頭指標
功能
	獲取迴圈連結串列的頭指標
*/
CirLinkListNode* GetFisrtNode(CirLinkList *list)
{
	return list->m_head->m_next;
//	return list->m_tail->m_next->m_next;			// 只設尾指標的時候使用此程式碼
}


/**
CirLinkListNode* GetHeadNode(CirLinkList *list)
引數
	list	:	指向一個連結串列指標,此處傳入表頭地址
返回值
	返回頭結點的地址
功能
	獲取指向頭結點的指標
*/
CirLinkListNode* GetHeadNode(CirLinkList *list)
{
	return list->m_head;
//	return list->m_tail->m_next;			// 只設尾指標的時候使用此程式碼
}






#define LIST_SIZE 7
// 主函式
int main(void)
{
	int pos;

	printf("TEST 1...\n");
	CirLinkList *plist = CreateCirLinkList( );				// 建立單鏈表
	for(int pos = 0; pos < LIST_SIZE; pos++)			// 迴圈向單鏈表中插入資料
	{
		InsertNode(plist, pos, pos + 1);
	}
	ShowList(plist);									// 插入結束後顯示單鏈表的資訊

	DeleteNode(plist, 0);								// 刪除第一個元素
	ShowList(plist);
	DeleteNode(plist, 1);								// 刪除第二個元素
	ShowList(plist);

	ClearCirLinkList(plist);								// 將單鏈表清空
	ShowList(plist);
	DestroyCirLinkList(plist);								// 將單鏈表銷燬
	plist = NULL;

	printf("\n\nTEST 2...\n");
	CirLinkList list;
	InitCirLinkList(&list);								// 初始化單鏈表
	for(int pos = 0; pos < LIST_SIZE; pos++)			// 訓話向單鏈表中插入資料
	{
		InsertNode(&list, pos, pos + 1);
	}
	ShowList(&list);									// 顯示單鏈表
	ClearCirLinkList(&list);								// 清空單鏈表
//	FinitLinkList(&list);		// ERROR== list->m_head->m_next == NULL
	ShowList(&list);

	printf("\n\nTEST 3...\n");
	CirLinkListNode *prevNode = list.m_head;
	CirLinkListNode *addNode = NULL;
	for(int pos = 0; pos < LIST_SIZE; pos++)
	{
		if((addNode = AddNode(&list, prevNode, pos + 1)) != NULL)
		{
            prevNode = addNode;
		}
	}
	ShowList(&list);
	while(IsEmptyCirLinkList(&list) != true)			// 迴圈刪除單鏈表中的資料
	{
		//printf("%p == %p\n", list.m_head->m_next, list.m_head);
		DeleteCurrNode(&list, list.m_head->m_next);
	}
	ShowList(&list);									// 顯示單鏈表

	return 	EXIT_SUCCESS;
}