单向链表

来源:互联网 发布:淘宝女装上下架时间 编辑:程序博客网 时间:2024/06/03 13:02

单链表介绍

        单链表(通常简称链表)由各个元素之间通过一个指针彼此链接起来而组成。每个元素包含两部分:数据成员和一个称为next指针。通过采用这种二成员结构,将每个元素的next指针设置为指向其后面的元素。最后一个元素的next指针设置为NULL,简单地表示链表的尾端。链表开始处的元素是“头”,链表末尾的元素称为“尾”。

        待补图

        要访问链表中的某个元素,从链表头开始,通过next指针从一个元素到另一个元素连续的遍历直到找到所需要的那个元素为止。


单链表实现

// List.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include <malloc.h>/*链表元素结构体定义*/typedef struct ListElmt_{void *pdata;struct ListElmt_ *pNext;}ListElmt;/*链表结构体定义*/typedef struct List_{int iSize;void (*destory)(void *data);ListElmt *ListElmtHead;ListElmt *ListElmtTail;}List;/*链表操作宏定义*/#define LIST_SIZE(list) ((list)->iSize)#define LIST_HEAD(list) ((list)->ListElmtHead)#define LIST_TAIL(list) ((list)->ListElmtTail)#define LIST_IS_HEAD(list, element) ((element == (list)->ListElmtHead) ? 1:0)#define LIST_IS_TAIL(list, element) ((element == (list)->ListElmtTail) ? 1:0)#define LIST_DATA(element) ((element)->pdata)#define LIST_NEXT(element) ((element)->pNext)/**函数名:List_Init*参数:list  链表*      destory  释放链表节点内存的函数*功能:单链表初始化*返回值:无*作者:AlbertoNo1*日期:2016-04-14*/void List_Init(List *list, void (*destory)(void *data)){/*入参合法性由调用者保证*/list->iSize = 0;list->destory = destory;list->ListElmtHead = NULL;list->ListElmtTail = NULL;return ;}/**函数名:List_Ins_Next*参数:list  链表*      Element  待插入元素的前一个节点元素*      data     待插入元素数据*功能:单链表添加节点函数*返回值:0 成功  -1 失败*作者:AlbertoNo1*日期:2016-04-14*/int List_Ins_Next(List *list, ListElmt *Element, void *data){ListElmt *Lelmt = NULL;if ((NULL == list) || (NULL == data)){return -1;}/*申请链表节点内存*/Lelmt = (ListElmt*)malloc(sizeof(ListElmt));if (NULL == Lelmt){return -1;}Lelmt->pdata = data;if (NULL == Element){/*在链表头插入元素*/Lelmt->pNext = list->ListElmtHead;list->ListElmtHead = Lelmt;if (0 == LIST_SIZE(list)){list->ListElmtTail = Lelmt;}}else{/*在非链表头插入元素*/Lelmt->pNext = Element->pNext;Element->pNext = Lelmt;if (NULL == Lelmt->pNext){list->ListElmtTail = Lelmt;}}/*链表大小加1*/list->iSize++;return 0;}/**函数名:List_Rem_Next*参数:list  链表*      Element  待删除元素的前一个节点元素*      data     返回删除元素的数据域*功能:单链表删除节点函数*返回值:0 成功  -1 失败*作者:AlbertoNo1*日期:2016-04-14*/int List_Rem_Next(List *list, ListElmt *Element, void **data){ListElmt *Old_Lelmt = NULL;if ((NULL == list) || (NULL == data)){return -1;}if (0 == LIST_SIZE(list)){return -1;}if (NULL == Element){/*删除链表头元素*/*data = list->ListElmtHead->pdata;Old_Lelmt = list->ListElmtHead;list->ListElmtHead = list->ListElmtHead->pNext;if (1 == LIST_SIZE(list)){list->ListElmtTail = NULL;}}else{/*删除非链表头元素*/if (1 == LIST_SIZE(list)){return -1;}else{*data = Element->pNext->pdata;Old_Lelmt = Element->pNext;Element->pNext = Element->pNext->pNext;if (NULL == Element->pNext){list->ListElmtTail = Element;}}}/*释放删除节点的内存*/free(Old_Lelmt);/*链表大小减一*/list->iSize--;return 0;}/**函数名:List_Destory*参数:list  链表*功能:单链表销毁*返回值:无*作者:AlbertoNo1*日期:2016-04-14*/void List_Destory(List *list){void *data = NULL;/*入参合法性由调用者保证*/while (LIST_SIZE(list) > 0){if ((0 == List_Rem_Next(list, NULL, &data))&&(NULL != list->destory)){list->destory(data);}}memset(list, 0, sizeof(List));return ;}/**函数名:destory*参数:data  动态申请内存的地址*功能:释放动态申请内存函数*返回值:无*作者:AlbertoNo1*日期:2016-04-14*/void destory(void *data){free(data);}int _tmain(int argc, _TCHAR* argv[]){int iRet = 0;int iLoop = 0;int *piData = NULL;List stList = {0};ListElmt *element = NULL;List_Init(&stList, destory);for (iLoop = 0; iLoop < 10; iLoop++){piData = (int*)malloc(sizeof(int));*piData = iLoop;iRet |= List_Ins_Next(&stList,NULL, (void*)piData);}if (0 != iRet){return -1;}element = stList.ListElmtHead;while(NULL != element){printf("%d ", *((int*)(element->pdata)));element = element->pNext;}List_Destory(&stList);getchar();return 0;}


单链表实现(二)

// List.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include <malloc.h>/*单链表元素结构体定义*/typedef struct  ListElmt_{unsigned int uiValueA;   /*数据域 数据成员*/unsigned int *puiValueB; /*数据域 数据成员,需要动态申请内存*/struct ListElmt_ *pNext;  /*指针域 指向后一个元素结点的指针*/}ListElmt;/*单链表结构体定义*/typedef struct List_{int  iSize;   /*链表大小*/void (*destory)(void *data);  /*用于释放元素结点内动态申请的内存*/int (*compare)(void *key1, void *key2); /*比较函数 返回值 0 相等 1 大于 -1 小于*/ListElmt  *pListElmtHead;  /*指向链表头结点的指针*/ListElmt  *pListElmtTail;  /*指向链表尾结点的指针*/}List;/*单链表操作宏定义*/#define LIST_SIZE(list)   ((list)->iSize)#define LIST_HEAD(list)   ((list)->pListElmtHead)#define LIST_TAIL(list)   ((list)->pListElmtTail)#define LIST_IS_HEAD(list, element) (((element) == (list)->pListElmtHead) ? 1:0)#define LIST_IS_TAIL(list, element) (((element) == (list)->pListElmtTail) ? 1:0)/*函数声明*/void MemoryFree(void *data);int DataCompare(void *key1, void *key2);void List_Init(List *list, void (*destory)(void *data), int (*compare)(void *key1, void *key2));int List_Insert_Next(List *list, ListElmt *Lelement, unsigned int uiDataA, unsigned int *puiDataB);int List_Remove_Next(List *list, ListElmt *Lelement, unsigned int *puiDataA, unsigned int **puiDataB);void List_Sort(List *list);void List_Destory(List *list);void List_Swap(ListElmt *LelementKey1, ListElmt *LelementKey2);/**函数名:MemoryFree*参数:data  待释放的内存*功能:释放动态申请的内存*返回值:无*作者:AlbertoNo1*日期:2016-04-20*/void MemoryFree(void *data){free(data);}/**函数名:DataCompare*参数:key1  待比较的元素1*      key2  待比较的元素2*功能:比较两个元素的大小(无符号整型)*返回值:0 key1 等于 key2  1 key1 大于 key2  -1 key1 小于 key2 *作者:AlbertoNo1*日期:2016-04-20*/int DataCompare(void *key1, void *key2){unsigned int uiKey1 = 0;unsigned int uiKey2 = 0;uiKey1 = *((unsigned int*)key1);uiKey2 = *((unsigned int*)key2);if (uiKey1 < uiKey2){return -1;}else if (uiKey1 > uiKey2){return 1;}else{return 0;}}/**函数名:List_Init*参数:list  待初始化的链表*      destory  数据域动态内存释放函数*      compare  比较函数*功能:单链表初始化函数*返回值:无 *作者:AlbertoNo1*日期:2016-04-20*/void List_Init(List *list, void (*destory)(void *data), int (*compare)(void *key1, void *key2)){list->iSize = 0;list->destory = destory;list->compare = compare;list->pListElmtHead = NULL;list->pListElmtTail = NULL;}/**函数名:List_Insert_Next*参数:list  链表*      Lelment  待插入元素的前一个元素指针*      uiDataA  数据成员值*      puiDataB 数据成员值(动态申请内存)*功能:单链表插入元素函数*返回值:0 成功 -1 失败 *作者:AlbertoNo1*日期:2016-04-20*/int List_Insert_Next(List *list, ListElmt *Lelement, unsigned int uiDataA, unsigned int *puiDataB){ListElmt  *pElment = NULL;/*入参合法值由调用者保证*//*申请内存*/pElment = (ListElmt*)malloc(sizeof(ListElmt));if (NULL == pElment){return -1;}/*数据域赋值*/pElment->uiValueA = uiDataA;pElment->puiValueB = puiDataB;if (0 == LIST_SIZE(list)){/*空链表插入元素*/pElment->pNext = NULL;/*更新链表头尾结点指针*/list->pListElmtHead = pElment;list->pListElmtTail = pElment;}else{if (NULL == Lelement){/*插入链表头*/pElment->pNext = list->pListElmtHead;list->pListElmtHead = pElment;}else if (LIST_IS_TAIL(list, Lelement)){/*插入链表尾*/            pElment->pNext = NULL;list->pListElmtTail->pNext = pElment;list->pListElmtTail = pElment;}else{pElment->pNext = Lelement->pNext;Lelement->pNext = pElment;}}list->iSize++;return 0;}/**函数名:List_Remove_Next*参数:list  链表*      Lelment  待删除元素的前一个元素指针*      puiDataA  返回数据成员值*      puiDataB  返回数据成员值(动态申请内存)*功能:单链表删除元素函数*返回值:0 成功 -1 失败 *作者:AlbertoNo1*日期:2016-04-20*/int List_Remove_Next(List *list, ListElmt *Lelement, unsigned int *puiDataA, unsigned int **puiDataB){ListElmt  *pElment = NULL;/*入参合法值由调用者保证*/if (0 == LIST_SIZE(list)){/*空链表删除元素*/return -1;}if (NULL == Lelement){/*删除链表头*/pElment = list->pListElmtHead;/*数据域返回*/*puiDataA = pElment->uiValueA;*puiDataB = pElment->puiValueB;list->pListElmtHead = list->pListElmtHead->pNext;if (1 == LIST_SIZE(list)){list->pListElmtTail = NULL;}}else{/*删除非链表头元素*/if (1 == LIST_SIZE(list)){return - 1;}else{pElment = Lelement->pNext;/*数据域返回*/*puiDataA = pElment->uiValueA;*puiDataB = pElment->puiValueB;Lelement->pNext = Lelement->pNext->pNext;if (NULL == Lelement->pNext){list->pListElmtTail = Lelement;}}}/*释放链表结点内存*/free(pElment);list->iSize--;return 0;}/**函数名:List_Sort*参数:list  链表*功能:单链表排序(交换结点的数据域)*返回值:无 *作者:AlbertoNo1*日期:2016-04-20*/void List_Sort(List *list){ListElmt  *pElmentPos = NULL;ListElmt  *pElmentA = NULL;ListElmt  *pElmentB = NULL;if (0 == LIST_SIZE(list)){return ;}for (pElmentA = list->pListElmtHead; NULL != pElmentA; pElmentA = pElmentA->pNext){pElmentPos = pElmentA;for (pElmentB = pElmentA->pNext; NULL != pElmentB; pElmentB = pElmentB->pNext){if (list->compare(&(pElmentB->uiValueA), &(pElmentPos->uiValueA)) < 0){pElmentPos = pElmentB;}}if (pElmentPos != pElmentA){List_Swap(pElmentPos, pElmentA);}}}/**函数名:List_Swap*参数:list  链表*功能:单链表交换两个结点的数据域*返回值:无 *作者:AlbertoNo1*日期:2016-04-20*/void List_Swap(ListElmt *LelementKey1, ListElmt *LelementKey2){unsigned int uiValueA = 0;   unsigned int *puiValueB = NULL; uiValueA = LelementKey1->uiValueA;puiValueB = LelementKey1->puiValueB;LelementKey1->uiValueA = LelementKey2->uiValueA;LelementKey1->puiValueB = LelementKey2->puiValueB;LelementKey2->uiValueA = uiValueA;LelementKey2->puiValueB = puiValueB;}/**函数名:List_Destory*参数:list  链表*功能:单链表销毁函数*返回值:无 *作者:AlbertoNo1*日期:2016-04-20*/void List_Destory(List *list){unsigned int uiDataA = 0;unsigned int *puiDataB = NULL;while (LIST_SIZE(list) > 0){if ((0 == List_Remove_Next(list, NULL, &uiDataA, &puiDataB)) && (NULL != list->destory)){list->destory(puiDataB);}}}/*空链表插入*/void test_func1(List *list){int iRet = 0;unsigned int uiDataA = 0;unsigned int *puiDataB = NULL;ListElmt *element = NULL;/*测试*/uiDataA = 11;puiDataB = (unsigned int*)malloc(sizeof(unsigned int));if (NULL == puiDataB){return;}*puiDataB = 99;iRet = List_Insert_Next(list, NULL, uiDataA, puiDataB);if (-1 == iRet){return;}printf("预期结果\n");printf("数据:11 99 \n");    printf("链表大小:1 \n");    printf("\n实际结果\n");printf("数据:");for(element = LIST_HEAD(list); NULL != element; element = element->pNext){printf("%u %u", element->uiValueA, *(element->puiValueB));}printf("\n链表大小:%d \n", LIST_SIZE(list));}/*非空链表插入头结点*/void test_func2(List *list){int iRet = 0;unsigned int uiDataA = 0;unsigned int *puiDataB = NULL;ListElmt *element = NULL;/*测试*/uiDataA = 12;puiDataB = (unsigned int*)malloc(sizeof(unsigned int));if (NULL == puiDataB){return;}*puiDataB = 98;iRet = List_Insert_Next(list, NULL, uiDataA, puiDataB);if (-1 == iRet){return;}printf("预期结果\n");printf("数据:12 98 11 99 \n");printf("链表大小:2 \n");printf("\n实际结果\n");printf("数据:");for(element = LIST_HEAD(list); NULL != element; element = element->pNext){printf("%u %u ", element->uiValueA, *(element->puiValueB));}printf("\n链表大小:%d \n", LIST_SIZE(list));}/*非空链表插入尾结点*/void test_func3(List *list){int iRet = 0;unsigned int uiDataA = 0;unsigned int *puiDataB = NULL;ListElmt *element = NULL;/*测试*/uiDataA = 13;puiDataB = (unsigned int*)malloc(sizeof(unsigned int));if (NULL == puiDataB){return;}*puiDataB = 97;iRet = List_Insert_Next(list, LIST_TAIL(list), uiDataA, puiDataB);if (-1 == iRet){return;}printf("预期结果\n");printf("数据:12 98 11 99 13 97\n");printf("链表大小:3 \n");printf("\n实际结果\n");printf("数据:");for(element = LIST_HEAD(list); NULL != element; element = element->pNext){printf("%u %u ", element->uiValueA, *(element->puiValueB));}printf("\n链表大小:%d \n", LIST_SIZE(list));}/*非空链表插入非头尾结点*/void test_func4(List *list){int iRet = 0;unsigned int uiDataA = 0;unsigned int *puiDataB = NULL;ListElmt *element = NULL;/*测试*/uiDataA = 14;puiDataB = (unsigned int*)malloc(sizeof(unsigned int));if (NULL == puiDataB){return;}*puiDataB = 96;iRet = List_Insert_Next(list, list->pListElmtHead->pNext, uiDataA, puiDataB);if (-1 == iRet){return;}printf("预期结果\n");printf("数据:12 98 11 99 14 96 13 97\n");printf("链表大小:4 \n");printf("\n实际结果\n");printf("数据:");for(element = LIST_HEAD(list); NULL != element; element = element->pNext){printf("%u %u ", element->uiValueA, *(element->puiValueB));}printf("\n链表大小:%d \n", LIST_SIZE(list));}/*删除链表头结点*/void test_func5(List *list){int iRet = 0;unsigned int uiDataA = 0;unsigned int *puiDataB = NULL;ListElmt *element = NULL;iRet = List_Remove_Next(list, NULL, &uiDataA, &puiDataB);if (-1 == iRet){return;}printf("预期结果\n");printf("数据:11 99 14 96 13 97\n");printf("链表大小:3 \n");printf("\n实际结果\n");printf("数据:");for(element = LIST_HEAD(list); NULL != element; element = element->pNext){printf("%u %u ", element->uiValueA, *(element->puiValueB));}printf("\n链表大小:%d \n", LIST_SIZE(list));}/*删除链表结点*/void test_func6(List *list){int iRet = 0;unsigned int uiDataA = 0;unsigned int *puiDataB = NULL;ListElmt *element = NULL;iRet = List_Remove_Next(list, list->pListElmtHead, &uiDataA, &puiDataB);if (-1 == iRet){return;}printf("预期结果\n");printf("数据:11 99 13 97\n");printf("链表大小:2 \n");printf("\n实际结果\n");printf("数据:");for(element = LIST_HEAD(list); NULL != element; element = element->pNext){printf("%u %u ", element->uiValueA, *(element->puiValueB));}printf("\n链表大小:%d \n", LIST_SIZE(list));}/*销毁链表*/void test_func7(List *list){ListElmt *element = NULL;List_Destory(list);printf("预期结果\n");printf("链表大小:0 \n");printf("\n实际结果\n");for(element = LIST_HEAD(list); NULL != element; element = element->pNext){printf("%u %u ", element->uiValueA, *(element->puiValueB));}printf("\n链表大小:%d \n", LIST_SIZE(list));}/*链表排序*/void test_func8(List *list){ListElmt *element = NULL;List_Sort(list);printf("预期结果\n");printf("数据:11 99 12 98 13 97 14 96 \n");printf("链表大小:4 \n");printf("\n实际结果\n");printf("数据:");for(element = LIST_HEAD(list); NULL != element; element = element->pNext){printf("%u %u ", element->uiValueA, *(element->puiValueB));}printf("\n链表大小:%d \n", LIST_SIZE(list));}int _tmain(int argc, _TCHAR* argv[]){int iRet = 0;int iLoop = 0;List stList = {0};ListElmt *element = NULL;/*链表初始化*/List_Init(&stList, MemoryFree, DataCompare);/*测试1*/test_func1(&stList);printf("\n\n");/*测试2*/test_func2(&stList);printf("\n\n");/*测试3*/test_func3(&stList);printf("\n\n");/*测试4*/test_func4(&stList);printf("\n\n");///*测试5*///test_func5(&stList);//printf("\n\n");/*测试6*///test_func6(&stList);//printf("\n\n");/*测试7*///test_func7(&stList);    /*测试8*/test_func8(&stList);/*链表销毁*/List_Destory(&stList);getchar();return 0;}


1 0