使您的列表双重链接。以下是我1999年的实施情况:
List * ListCreate(void)
{
List * pList;
pList = malloc(sizeof(List));
pList->pHead = malloc(sizeof(ListNode));
pList->pHead->pNext = pList->pHead->pPrev = pList->pHead;
pList->pNodeLast = NULL;
pList->count = 0;
return pList;
}
void ListDestroy(
List * pList)
{
ListNode * pNode;
assert(pList != NULL);
pNode = pList->pHead->pNext;
while (pNode != pList->pHead)
{
ListNode * pNext;
pNext = pNode->pNext;
free(pNode);
pNode = pNext;
}
free(pList->pHead);
free(pList);
}
void ListDestroyData(
List * pList)
{
ListNode * pNode;
assert(pList != NULL);
pNode = pList->pHead->pNext;
while (pNode != pList->pHead)
{
ListNode * pNext;
pNext = pNode->pNext;
free(pNode->pData);
free(pNode);
pNode = pNext;
}
free(pList->pHead);
free(pList);
}
void ListAddHead(
List * pList,
void * pData)
{
ListNode * pNode;
assert(pList != NULL);
pNode = malloc(sizeof(ListNode));
pNode->pData = pData;
(pNode->pNext = pList->pHead->pNext)->pPrev = pNode;
(pList->pHead->pNext = pNode)->pPrev = pList->pHead;
pList->pNodeLast = pNode;
pList->count++;
}
void ListAddTail(
List * pList,
void * pData)
{
ListNode * pNode;
assert(pList != NULL);
pNode = malloc(sizeof(ListNode));
pNode->pData = pData;
(pNode->pPrev = pList->pHead->pPrev)->pNext = pNode;
(pList->pHead->pPrev = pNode)->pNext = pList->pHead;
pList->pNodeLast = pNode;
pList->count++;
}
void ListAddBefore(
List * pList,
void * pData)
{
ListNode * pNode;
assert(pList != NULL);
validate(pList->pNodeLast != NULL, NOTHING);
pNode = malloc(sizeof(ListNode));
pNode->pData = pData;
(pNode->pPrev = pList->pNodeLast->pPrev)->pNext = pNode;
(pList->pNodeLast->pPrev = pNode)->pNext = pList->pNodeLast;
pList->pNodeLast = pNode;
pList->count++;
}
void ListAddAfter(
List * pList,
void * pData)
{
ListNode * pNode;
assert(pList != NULL);
validate(pList->pNodeLast != NULL, NOTHING);
pNode = malloc(sizeof(ListNode));
pNode->pData = pData;
(pNode->pNext = pList->pNodeLast->pNext)->pPrev = pNode;
(pList->pNodeLast->pNext = pNode)->pPrev = pList->pNodeLast;
pList->pNodeLast = pNode;
pList->count++;
}
void * ListRemoveHead(
List * pList)
{
void * pData;
ListNode * pNode;
assert(pList != NULL);
validate(pList->count > 0, NULL);
pNode = pList->pHead->pNext;
pData = pNode->pData;
(pList->pHead->pNext = pNode->pNext)->pPrev = pList->pHead;
free(pNode);
pList->pNodeLast = NULL;
pList->count--;
return pData;
}
void * ListRemoveTail(
List * pList)
{
void * pData;
ListNode * pNode;
assert(pList != NULL);
validate(pList->count > 0, NULL);
pNode = pList->pHead->pPrev;
pData = pNode->pData;
(pList->pHead->pPrev = pNode->pPrev)->pNext = pList->pHead;
free(pNode);
pList->pNodeLast = NULL;
pList->count--;
return pData;
}
void * ListRemove(
List * pList,
void * pData)
{
ListNode * pNode;
assert(pList != NULL);
validate(pList->count > 0, NULL);
pNode = pList->pHead->pNext;
while (pNode != pList->pHead && pNode->pData != pData)
pNode = pNode->pNext;
validate(pNode->pData == pData, NULL);
pNode->pNext->pPrev = pNode->pPrev;
pNode->pPrev->pNext = pNode->pNext;
free(pNode);
pList->pNodeLast = NULL;
pList->count--;
return pData;
}
void * ListRemoveLast(
List * pList)
{
void * pData;
ListNode * pNext;
assert(pList != NULL);
validate(pList->pNodeLast != NULL, NULL);
pData = pList->pNodeLast->pData;
pNext = pList->pNodeLast->pNext;
pList->pNodeLast->pNext->pPrev = pList->pNodeLast->pPrev;
pList->pNodeLast->pPrev->pNext = pList->pNodeLast->pNext;
free(pList->pNodeLast);
pList->pNodeLast = pNext;
pList->count--;
return pData;
}
void * ListHead(
List * pList)
{
assert(pList != NULL);
if (pList->count == 0)
return NULL;
else
return 0, (pList->pNodeLast = pList->pHead->pNext)->pData;
}
void * ListTail(
List * pList)
{
assert(pList != NULL);
if (pList->count == 0)
return NULL;
else
return 0, (pList->pNodeLast = pList->pHead->pPrev)->pData;
}
void * ListLast(
List * pList)
{
assert(pList != NULL);
if (pList->pNodeLast == NULL)
return NULL;
else
return pList->pNodeLast->pData;
}
void * ListNext(
List * pList)
{
assert(pList != NULL);
validate(pList->pNodeLast != NULL, NULL);
if ((pList->pNodeLast = pList->pNodeLast->pNext) == pList->pHead)
{
pList->pNodeLast = NULL;
return NULL;
}
else
return pList->pNodeLast->pData;
}
void * ListPrev(
List * pList)
{
assert(pList != NULL);
validate(pList->pNodeLast != NULL, NULL);
if ((pList->pNodeLast = pList->pNodeLast->pPrev) == pList->pHead)
{
pList->pNodeLast = NULL;
return NULL;
}
else
return pList->pNodeLast->pData;
}
int ListCount(
List * pList)
{
assert(pList != NULL);
return pList->count;
}
void * ListFind(
List * pList,
void * pData)
{
ListNode * pNode;
assert(pList != NULL);
pNode = pList->pHead->pNext;
while (pNode != pList->pHead && pNode->pData != pData)
pNode = pNode->pNext;
if (pNode->pData == pData)
{
pList->pNodeLast = pNode;
return pData;
}
else
return NULL;
}
List * ListSplitBefore(
List * pListOrg)
{
List * pListNew;
ListNode * pNodeOrg;
assert(pListOrg != NULL);
validate(pListOrg->count > 0, NULL);
validate(pListOrg->pNodeLast != NULL, NULL);
pListNew = malloc(sizeof(List));
pListNew->pHead = malloc(sizeof(ListNode));
pListNew->pHead->pData = NULL;
pListNew->count = 0;
pNodeOrg = pListOrg->pHead->pNext;
while (pNodeOrg != pListOrg->pNodeLast)
{
pListOrg->count--;
pListNew->count++;
pNodeOrg = pNodeOrg->pNext;
}
if (pListNew->count == 0)
{
pListNew->pHead->pPrev = pListNew->pHead->pNext = pListNew->pHead;
}
else
{
pListNew->pHead->pNext = pListOrg->pHead->pNext;
pListNew->pHead->pNext->pPrev = pListNew->pHead;
pListNew->pHead->pPrev = pListOrg->pNodeLast->pPrev;
pListNew->pHead->pPrev->pNext = pListNew->pHead;
pListOrg->pHead->pNext = pListOrg->pNodeLast;
pListOrg->pNodeLast->pPrev = pListOrg->pHead;
}
pListNew->pNodeLast = NULL;
return pListNew;
}
List * ListSplitAfter(
List * pListOrg)
{
List * pListNew;
ListNode * pNodeOrg;
assert(pListOrg != NULL);
validate(pListOrg->count > 0, NULL);
validate(pListOrg->pNodeLast != NULL, NULL);
pListNew = malloc(sizeof(List));
pListNew->pHead = malloc(sizeof(ListNode));
pListNew->pHead->pData = NULL;
pListNew->count = 0;
pNodeOrg = pListOrg->pNodeLast->pNext;
while (pNodeOrg != pListOrg->pHead)
{
pListOrg->count--;
pListNew->count++;
pNodeOrg = pNodeOrg->pNext;
}
if (pListNew->count == 0)
{
pListNew->pHead->pPrev = pListNew->pHead->pNext = pListNew->pHead;
}
else
{
pListNew->pHead->pNext = pListOrg->pNodeLast->pNext;
pListNew->pHead->pNext->pPrev = pListNew->pHead;
pListNew->pHead->pPrev = pListOrg->pHead->pPrev;
pListNew->pHead->pPrev->pNext = pListNew->pHead;
pListOrg->pNodeLast->pNext = pListOrg->pHead;
pListOrg->pHead->pPrev = pListOrg->pNodeLast;
}
pListNew->pNodeLast = NULL;
return pListNew;
}
List * ListConcat(
List * pListDst,
List * pListAdd)
{
assert(pListDst != NULL);
assert(pListAdd != NULL);
switch (((pListAdd->count > 0) << 1) | (pListDst->count > 0))
{
case 0:
break;
case 1:
break;
case 2:
pListDst->pHead->pNext = pListAdd->pHead->pNext;
pListDst->pHead->pNext->pPrev = pListDst->pHead;
pListDst->pHead->pPrev = pListAdd->pHead->pPrev;
pListDst->pHead->pPrev->pNext = pListDst->pHead;
break;
case 3:
pListAdd->pHead->pPrev->pNext = pListDst->pHead;
pListDst->pHead->pPrev->pNext = pListAdd->pHead->pNext;
pListAdd->pHead->pNext->pPrev = pListDst->pHead->pPrev;
pListDst->pHead->pPrev = pListAdd->pHead->pPrev;
break;
}
pListDst->pNodeLast = NULL;
pListDst->count += pListAdd->count;
free(pListAdd->pHead);
free(pListAdd);
return pListDst;
}
以下是标题的基本部分:
#ifndef _LIST_H
#define _LIST_H
typedef struct _ListNode ListNode;
struct _ListNode
{
ListNode * pNext;
ListNode * pPrev;
void * pData;
};
typedef struct _List List;
struct _List
{
ListNode * pHead;
ListNode * pNodeLast;
int count;
};
我知道这是一个有点不标准的答案。但我认为看到另一种实现方式会有所帮助。