#ifndef _LIST_H_ #define _LIST_H_ #include <stdio.h> #define _ASSERT_RET(cond, ret) if (!(cond)){printf("file: %s,line: %d/n", __FILE__, __LINE__);return ret;}else{} typedef struct _VALUE_{ void *pvData; unsigned long udwLength; }_VALUE_; typedef struct _ListNode{ struct _VALUE_ tData; struct _ListNode *prevPtr; struct _ListNode *nextPtr; }*_PLISTNODE, _LISTNODE; typedef struct _List{ _PLISTNODE ptrNodeHead; _PLISTNODE ptrNodeEnd; size_t iSize; }*PLIST, LIST; PLIST InitList(PLIST ptList); _PLISTNODE FindNode(PLIST ptList, _VALUE_ *ptToFind); _PLISTNODE InsertPos(PLIST ptList, unsigned long udwPos, _VALUE_ *pToInsert); void For_each(PLIST ptNode, void (*DoSome)(_VALUE_ *pvalue)); PLIST SortList(PLIST ptList, int(*compare)(_VALUE_ *LeftValPtr, _VALUE_ *RightValPtr)); _PLISTNODE DeleteNode(_PLISTNODE ptToDelete); void ReleaseAll(PLIST ptrList); _PLISTNODE InsertNode(_PLISTNODE ptInsertBack, _VALUE_ *pToInsert); #endif #include <stdio.h> #include <stdlib.h> #include <memory.h> #include <time.h> #include "list.h" PLIST InitList(PLIST ptList) { ptList->ptrNodeHead = NULL; ptList->ptrNodeEnd = NULL; ptList->iSize = 0; return ptList; } _PLISTNODE InsertNode(_PLISTNODE ptInsertBack, _VALUE_ *pToInsert) { _PLISTNODE ptNew; if (NULL == ptInsertBack){ return NULL; } ptNew = (_PLISTNODE)malloc(sizeof(_LISTNODE)); ptNew->prevPtr = ptInsertBack; ptNew->nextPtr = ptInsertBack->nextPtr; ptNew->tData.pvData = malloc(pToInsert->udwLength); memcpy(ptNew->tData.pvData, pToInsert->pvData, pToInsert->udwLength); ptNew->tData.udwLength = pToInsert->udwLength; ptInsertBack->nextPtr = ptNew; if (NULL != ptNew->nextPtr){ ptNew->nextPtr->prevPtr = ptNew; } return ptNew; } _PLISTNODE InsertPos(PLIST ptList, unsigned long udwPos, _VALUE_ *pToInsert) { _PLISTNODE ptrNew; _ASSERT_RET(ptList != NULL, NULL); if (-1 == udwPos) { _PLISTNODE ptNode = (_PLISTNODE)malloc(sizeof(_LISTNODE)); ptNode->prevPtr = NULL; ptNode->nextPtr = ptList->ptrNodeHead; ptNode->tData.pvData = malloc(pToInsert->udwLength); memcpy(ptNode->tData.pvData, pToInsert->pvData, pToInsert->udwLength); ptNode->tData.udwLength = pToInsert->udwLength; if (NULL != ptList->ptrNodeHead) { ptList->ptrNodeHead->prevPtr = ptNode; } ptList->ptrNodeHead = ptNode; if (1 == ++ptList->iSize){ ptList->ptrNodeEnd = ptNode; } return ptList->ptrNodeHead; } _ASSERT_RET(udwPos < ptList->iSize, NULL); if (udwPos * 2 >= ptList->iSize || (0 == udwPos && 1 == ptList->iSize)){ unsigned long udwrPos = ptList->iSize - udwPos - 1; _PLISTNODE ptrNode = ptList->ptrNodeEnd; unsigned long udwDes = 0; for (; ptrNode != NULL; ptrNode = ptrNode->prevPtr){ if (udwDes++ == udwrPos){ ptrNew = InsertNode(ptrNode, pToInsert); if (ptList->iSize - 1 == udwPos){ ptList->ptrNodeEnd = ptrNew; } ++ptList->iSize; } } }else{ _PLISTNODE ptrNode = ptList->ptrNodeHead; unsigned long udwDes = 0; for (; ptrNode != NULL; ptrNode = ptrNode->nextPtr){ if (udwDes++ == udwPos){ ptrNew = InsertNode(ptrNode, pToInsert); ++ptList->iSize; } } } return ptrNew; } _PLISTNODE DeleteNode(_PLISTNODE ptToDelete) { _PLISTNODE toRet; ptToDelete->prevPtr->nextPtr = ptToDelete->nextPtr; ptToDelete->nextPtr->prevPtr = ptToDelete->prevPtr; toRet = ptToDelete->nextPtr; free(ptToDelete->tData.pvData); free(ptToDelete); return toRet; } _PLISTNODE FindNode(PLIST ptList, _VALUE_ *ptToFind) { _PLISTNODE ptFirst = ptList->ptrNodeHead; for (; ptFirst != NULL; ptFirst = ptFirst->nextPtr){ if (ptFirst->tData.udwLength == ptToFind->udwLength && !memcmp(ptFirst->tData.pvData, ptToFind->pvData, ptToFind->udwLength)){ return ptFirst; } } return NULL; } void For_each(PLIST ptNode, void (*DoSome)(_VALUE_ *pvalue)) { _PLISTNODE ptFirst = ptNode->ptrNodeHead; for (; ptFirst != NULL; ptFirst = ptFirst->nextPtr){ DoSome(&ptFirst->tData); } } PLIST SortList(PLIST ptList, int(*compare)(_VALUE_ *LeftValPtr, _VALUE_ *RightValPtr)) { _PLISTNODE ptEnd = ptList->ptrNodeEnd; _PLISTNODE ptCurEnd = ptEnd; _PLISTNODE ptTemp1 = ptList->ptrNodeHead, ptTemp2; for (; ptTemp1 != ptEnd; ptTemp1 = ptTemp1->nextPtr){ for (ptTemp2 = ptList->ptrNodeHead; ptTemp2 != ptCurEnd; ptTemp2 = ptTemp2->nextPtr){ if (compare(&ptTemp2->tData, &ptTemp2->nextPtr->tData)){ _VALUE_ vaTmp; memcpy(&vaTmp, &ptTemp2->tData, sizeof(_VALUE_)); memcpy(&ptTemp2->tData, &ptTemp2->nextPtr->tData, sizeof(_VALUE_)); memcpy(&ptTemp2->nextPtr->tData, &vaTmp, sizeof(_VALUE_)); } } ptCurEnd = ptCurEnd->prevPtr; } return ptList; } void ReleaseAll(PLIST ptrList) { _PLISTNODE ptTemp; _PLISTNODE ptFirst = ptrList->ptrNodeHead; for (; ptFirst != NULL; ){ ptTemp = ptFirst->nextPtr; free(ptFirst->tData.pvData); free(ptFirst); ptFirst = ptTemp; } } int Greater(_VALUE_ *LeftValPtr, _VALUE_ *RightValPtr) { return (int)(*(long*)LeftValPtr->pvData > *(long*)RightValPtr->pvData); } void Print(_VALUE_ *pvalue) { printf("%d ", *(long*)(pvalue->pvData)); } int main() { LIST list; long dwVa = 0; long c = -1; _VALUE_ value; _PLISTNODE ptFind; InitList(&list); srand((unsigned int)time(NULL)); value.udwLength = sizeof(dwVa); for (; c != 26; ++c){ dwVa = rand()%99; value.pvData = &dwVa; InsertPos(&list, c, &value); } dwVa = 110; value.pvData = &dwVa; InsertPos(&list, -1, &value); For_each(&list, Print); printf("/n"); SortList(&list, Greater); For_each(&list, Print); printf("/n"); dwVa = 19; value.pvData = &dwVa; ptFind = FindNode(&list, &value); if (NULL != ptFind){ printf("%d/n", *(long*)(ptFind->tData.pvData)); } else { printf("can not find: %d/n", dwVa); } ReleaseAll(&list); system("pause"); return 0; } 开发环境为dev-cpp,这个双向链表可以存储任意长度的数据,算是自己对基本功的练习吧。。。