数据结构链表总结一

数据结构链表总结一

 

        最近一直在学数据结构,刚开始学习的,觉得链表还是比较难的,今天将自己写的代码贴上来
#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万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章