數據結構鏈表總結一

數據結構鏈表總結一

 

        最近一直在學數據結構,剛開始學習的,覺得鏈表還是比較難的,今天將自己寫的代碼貼上來
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "list.h"

struct List
{
	data_t data;										//typedef int data_t;	
	struct List *pNext;
};

List *CreateList()
{
	List *pHeader = NULL;
	pHeader = (List *) malloc (sizeof(struct List));
	if (NULL != pHeader)
	{
		memset(pHeader, 0, sizeof(struct List));
	}
	return pHeader;
}

int DestoryList(List *pList)
{
	if (NULL == pList)
	{
		return LIST_ERROR;
	}
	while(pList->pNext)
	{
		List *p = pList->pNext;
		if (NULL != p)
		{
			pList->pNext = p->pNext;
			free(p);
			p = NULL;
		}
	}
	free(pList);
	return LIST_OK;
}

int InsertList(List *pList, data_t tData, int iOffset)
{
	if (NULL == pList)
	{
		return LIST_ERROR;
	}
	
	List *pData = (List *) malloc (sizeof(List));
	if (NULL == pData)
	{
		return LIST_ERROR;
	}
	memset(pData, 0, sizeof(struct List));
	pData->data = tData;
	pData->pNext = NULL;

	//insert
/*********************************************************************************/
	if(NULL == pList->pNext)
	{
		pList->data = (data_t)pData;		//data_t爲四字節,可以存儲四字節地址
	}
/*********************************************************************************/
	List *pTmp = pList;
	switch(iOffset)
	{
		case HEADER :		//在第一次插入數據的時候,尾結點的地址已保存到了頭節點
		{					//後面的插入的數據不會改變尾結點的地址
			pData->pNext = pList->pNext;
			pList->pNext = pData;
		}
		break;
		case TAIL :
		{
			/*while(pTmp->pNext)				//方式1
			{
				pTmp = pTmp->pNext;
			}
			pTmp->pNext = pData;*/
/****************************************************************************************/
			List *pTmp1 = (List *)pList->data;	//直接通過頭結點的data域,強制轉換得到尾地址
			pTmp1->pNext = pData;
			pList->data = (data_t)pData;		
/****************************************************************************************/
		}
		break;
		default:
		{
			if (iOffset > 0)
			{
				while(iOffset--)
				{
					if (NULL == pTmp->pNext)	//防止索引超出範圍
					{
						return LIST_ERROR;
					}
					pTmp = pTmp->pNext;
		
				}
/****************************************************************************************/
				if(NULL == pTmp->pNext)			//索引正好指向最後一個結點,新節點成爲尾結點
				{
					pList->data = (data_t)pData;
				}
/****************************************************************************************/
				pData->pNext = pTmp->pNext;
				pTmp->pNext = pData;
			}
		}
	}
	return LIST_OK;
}

int DeleteFromList(List *pList, data_t *pData, int iOffset)
{
	if (NULL == pList || iOffset < 0)
	{
		return LIST_ERROR;
	}
	if (HEADER == iOffset)
	{
		List *pTmp = pList->pNext;
		*pData = pTmp->data;
		pList->pNext = pTmp->pNext;
		if (NULL != pTmp)
		{
			free(pTmp);
		}
		pTmp = NULL;
/****************************************************************************/
		if(NULL == pList->pNext)			//刪除最後一個節點後,尾地址爲NULL
		{
			pList->data = 0;
		}
/****************************************************************************/
		return LIST_OK;
	}
	List *pTmp1 = pList;
	if (iOffset > 0)
	{
		while(iOffset--)
		{
			if (NULL == pTmp1->pNext)
			{
				return LIST_ERROR;
			}
			pTmp1 = pTmp1->pNext;
		}
		
		List *pDel = pTmp1->pNext;
		if (NULL != pDel)
		{
			pTmp1->pNext = pDel->pNext;
			*pData = pDel->data;
			free(pDel);
			pDel = NULL;
			if(NULL == pTmp1->pNext)	//刪除的正好是最後一個結點,則更新尾結點地址
			{
				pList->data = (data_t)pTmp1;
			}
		}
		else
		{
			return LIST_ERROR;
		}	
	}
	return LIST_OK;
}

int UpdateData(List *pList, data_t tOldData, data_t tNewData)
{
	if (NULL == pList)
	{
		return LIST_ERROR;
	}
	List *pTmp = pList;
	while(pTmp->pNext)
	{
		List *p = pTmp->pNext;
		if (p->data == tOldData)
		{
			p->data = tNewData;
			return LIST_OK;
		}
		pTmp = p;
	}
	return LIST_ERROR;
}

int SearchData(List *pList, data_t tData)
{
	if (NULL == pList)
	{
		return LIST_ERROR;
	}
	List *pTmp = pList;
	while(pTmp->pNext)
	{
		List *p = pTmp->pNext;
		if (p->data == tData)
		{
			return LIST_OK;
		}
		pTmp = p;
	}
	return LIST_ERROR;
}

int ShowList(List *pList)
{
	if (NULL == pList)
	{
		return LIST_ERROR;
	}
	List *pTmp = pList;
	while(pTmp->pNext)
	{
		printf("%d  ", pTmp->pNext->data);
		pTmp = pTmp->pNext;
	}
	printf("\r\n");
	return LIST_OK;
}
       鏈表並不像數組那樣,可以由下標隨機訪問數組中的元素,他有自己的好處,他一般從堆內存中分配,而且不需要連續的存儲空間,要訪問鏈表中的結點必須通過指針去訪問,插入和刪除是鏈表操作中較複雜的操作,一般要在鏈表中插入或刪除某個元素,可以給函數傳遞一個相對鏈表第一個有效結點的偏移量,用這個偏移量來確定循環次數,如果是單向鏈表,必須要找到被刪除結點的前一個結點的位置(地址),才能正確刪除,當然如果在頭部和尾部,情況會特殊一些,進一步的,如果在尾部操作,一種方法是通過每次通過while循環找到最後一個元素的位置,當然這種做法效率並不高,可以在鏈表頭結點中保存尾結點的地址
發佈了22 篇原創文章 · 獲贊 5 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章