数据结构链表总结一

来源:互联网 发布:中国软件国际地址 编辑:程序博客网 时间:2024/05/16 01:46

数据结构链表总结一

 

        最近一直在学数据结构,刚开始学习的,觉得链表还是比较难的,今天将自己写的代码贴上来
#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循环找到最后一个元素的位置,当然这种做法效率并不高,可以在链表头结点中保存尾结点的地址
0 0
原创粉丝点击