返回指定位置元素
- 函数功能:获取一个指定位置的元素
- 函数参数:list 双向链表句柄 pos 要获取的元素标号
- 函数返回:获取的结点元素
1. DoubleLinkedListNode* DoubleLinkedList_Get(DoubleLinkedList* list, int pos) 2. { 3. int i = 0; 4. DoubleLinkedListHead* pHead = NULL; 5. DoubleLinkedListNode* pCurrent = NULL; 6. if ((list == NULL) || (pos < 0)) 7. { 8. printf("err: (list == NULL) || (pos < 0)\n"); 9. return NULL; 10. } 11. pHead = (DoubleLinkedListHead*)list; 12. pCurrent = &(pHead->head); 13. for (i = 0; i < pos; i++) 14. { 15. pCurrent = pCurrent->next; 16. } 17. return pCurrent->next; 18. }
删除结点并返回被删除结点
- 函数功能:按位置删除一个结点并返回该结点
- 函数参数:list 双向链表句柄 pos 要删除的链表结点位置
- 函数返回:被删除的结点
1. DoubleLinkedListNode* DoubleLinkedList_Delete(DoubleLinkedList* list, int pos) 2. { 3. int i = 0; 4. DoubleLinkedListHead* pHead = NULL; 5. DoubleLinkedListNode* pCurrent = NULL; 6. DoubleLinkedListNode* pNext = NULL; 7. DoubleLinkedListNode* pTemp = NULL; 8. if ((list == NULL) || (pos < 0)) 9. { 10. printf("err: (list == NULL) || (pos < 0)\n"); 11. return NULL; 12. } 13. pHead = (DoubleLinkedListHead*)list; 14. pCurrent = &(pHead->head); 15. for (i = 0; i < pos; i++) 16. { 17. pCurrent = pCurrent->next; 18. } 19. pTemp = pCurrent->next; 20. pNext = pTemp->next; 21. pCurrent->next = pNext; 22. if (pNext != NULL) 23. { 24. //如果pNext是NULL,不进行pNext->previous的操作 25. pNext->previous = pCurrent; 26. if (pCurrent == (DoubleLinkedListNode*)list) //见分析示意图,删除0号结点 27. { 28. //在0号位置删除结点,要修正pNext->previous = pCurrent; 29. pNext->previous = NULL; 30. } 31. } 32. if (pTemp == pHead->slider) 33. { 34. pHead->slider = pNext; 35. } 36. pHead->length--; 37. return pTemp; 38. }
删除元素异常分析示意图
(1)普通位置删除
因为需要返回被删除结点,所以,在插入结点的基础上又多了一个辅助指针pTemp用于缓存被删除的结点。
(2)尾部删除
和在尾部插入元素一样,在删除尾部结点的时候,应去掉pNext->previous = pCurrent操作。
(3)头部删除
在头部删除时,和在头部插入一样,应加一步修正,pNext->previous = NULL。
(4)删除唯一结点
删除唯一结点的异常情况已被(2)(3)情况覆盖。
按元素删除结点
- 函数功能:按元素删除一个结点并返回该结点
- 函数参数:list 双向链表句柄 node要删除的链表结点元素
- 函数返回:被删除的结点
1. DoubleLinkedListNode* DoubleLinkedList_DeleteNode(DoubleLinkedList* list, DoubleLinkedListNode* node) 2. { 3. int i = 0; 4. DoubleLinkedListHead* pHead = NULL; 5. DoubleLinkedListNode* pTemp = NULL; 6. DoubleLinkedListNode* pCurrent = NULL; 7. if ((list == NULL) || (node == NULL)) 8. { 9. printf("err: (list == NULL) || (node == NULL)"); 10. return NULL; 11. } 12. pHead = (DoubleLinkedListHead*)list; 13. pCurrent = &(pHead->head); 14. for (i = 0; i < pHead->length; i++) 15. { 16. if (pCurrent == node) 17. { 18. pTemp = pCurrent; 19. break; 20. } 21. pCurrent = pCurrent->next; 22. } 23. if (pTemp != NULL) 24. { 25. if (NULL == DoubleLinkedList_Delete(list, i - 1)) 26. { 27. printf("DoubleLinkedList_DeleteNode err\n"); 28. return NULL; 29. } 30. } 31. return pTemp; 32. }
重置游标
- 函数功能:将游标指向第一个元素
- 函数参数:list 双向链表句柄
- 函数返回:游标位置
1. DoubleLinkedListNode* DoubleLinkedList_Reset(DoubleLinkedList* list) 2. { 3. DoubleLinkedListHead* pHead = NULL; 4. if (list == NULL) 5. { 6. printf("err: list == NULL\n"); 7. return NULL; 8. } 9. pHead = (DoubleLinkedListHead*)list; 10. pHead->slider = pHead->head.next; 11. return pHead->slider; 12. }
返回当前游标
- 函数功能:获取游标当前指向的结点
- 函数参数:list 双向链表句柄
- 函数返回:游标位置
1. DoubleLinkedListNode* DoubleLinkedList_Current(DoubleLinkedList* list) 2. { 3. DoubleLinkedListHead* pHead = NULL; 4. if (list == NULL) 5. { 6. printf("err: list == NULL\n"); 7. return NULL; 8. } 9. pHead = (DoubleLinkedListHead*)list; 10. return pHead->slider; 11. }
游标下移
- 函数功能:获取游标当前指向的结点,并将游标下移
- 函数参数:list 双向链表句柄
- 函数返回:下移前的游标位置
1. DoubleLinkedListNode* DoubleLinkedList_Next(DoubleLinkedList* list) 2. { 3. DoubleLinkedListHead* pHead = NULL; 4. DoubleLinkedListNode* pTemp = NULL; 5. if (list == NULL) 6. { 7. printf("err: list == NULL\n"); 8. return NULL; 9. } 10. pHead = (DoubleLinkedListHead*)list; 11. pTemp = pHead->slider; 12. pHead->slider = pHead->slider->next; 13. return pTemp; 14. }
游标上移
- 函数功能:获取游标当前指向的结点,并将游标上移
- 函数参数:list 双向链表句柄
- 函数返回:上移前的游标位置
1. DoubleLinkedListNode* DoubleLinkedList_Pre(DoubleLinkedList* list) 2. { 3. DoubleLinkedListHead* pHead = NULL; 4. DoubleLinkedListNode* pTemp = NULL; 5. if (list == NULL) 6. { 7. printf("err: list == NULL\n"); 8. return NULL; 9. } 10. pHead = (DoubleLinkedListHead*)list; 11. pTemp = pHead->slider; 12. pHead->slider = pHead->slider->previous; 13. return pTemp; 14. }
测试函数
1. #include "DoubleLinkedList.h" 2. 3. typedef struct MyData 4. { 5. DoubleLinkedListNode node; 6. int value; 7. }MyData; 8. 9. int main() 10. { 11. int i = 0; 12. MyData mVector[5]; 13. MyData* m = NULL; 14. DoubleLinkedList* mList = NULL; 15. mList = DoubleLinkedList_Create(); 16. if (mList == NULL) 17. { 18. printf("DoubleLinkedList_Create() err\n"); 19. return -1; 20. } 21. for (i = 0; i < 5; i++) 22. { 23. mVector[i].value = 3 + i; 24. DoubleLinkedList_Insert(mList, (DoubleLinkedListNode*)(&mVector[i]), DoubleLinkedList_Length(mList)); 25. } 26. 27. m = (MyData*)DoubleLinkedList_Current(mList); 28. printf("游标结点:%d\n", m->value); 29. 30. for (i = 0; i < DoubleLinkedList_Length(mList); i++) 31. { 32. if (i == 0) 33. { 34. printf("链表内容:"); 35. } 36. printf("%d ", ((MyData*)DoubleLinkedList_Get(mList, i))->value); 37. } 38. printf("\n"); 39. 40. DoubleLinkedList_DeleteNode(mList, (DoubleLinkedListNode*)(&mVector[2])); 41. 42. for (i = 0; i < DoubleLinkedList_Length(mList); i++) 43. { 44. if (i == 0) 45. { 46. printf("链表内容:"); 47. } 48. printf("%d ", ((MyData*)DoubleLinkedList_Get(mList, i))->value); 49. } 50. printf("\n"); 51. 52. for (i = 0; i < DoubleLinkedList_Length(mList); i++) 53. { 54. DoubleLinkedList_Delete(mList, i); 55. } 56. 57. DoubleLinkedList_Destroy(mList); 58. 59. system("pause"); 60. return 0; 61. }
代码资源已上传,链接如下: