删除结点并返回被删除结点
- 函数功能:按位置删除一个结点并返回该结点
- 函数参数:list 循环链表句柄 pos 要删除的链表结点位置
- 函数返回:被删除的结点
1. CircleListNode* CircleList_Delete(CircleList* list, int pos) 2. { 3. int i = 0; 4. CircleListHead* pHead = NULL; 5. CircleListNode* pCurrent = NULL; 6. CircleListNode* pLast = NULL; 7. CircleListNode* pTemp = NULL; 8. if ((list == NULL) || (pos < 0)) 9. { 10. printf("err: (list == NULL) || (pos < 0)\n"); 11. return NULL; 12. } 13. pHead = (CircleListHead*)list; 14. pCurrent = &(pHead->head); 15. for (i = 0; i < pos; i++) 16. { 17. pCurrent = pCurrent->next; 18. } 19. //如果删除0位置元素,需要获取尾部元素 20. if (pos == 0) 21. { 22. pLast = CircleList_Get(list, pHead->length - 1); //和插入相反,应该先获取尾部元素,再lenth-- 23. } 24. //先获取pLast,再进行删除操作,否则获取的就不是本来的尾部元素了 25. pTemp = pCurrent->next; 26. pCurrent = pTemp->next; 27. pHead->length--; 28. if (pLast != NULL) 29. { 30. //pLast == NULL说明本身链表为空,只有一个链表头,0号位置为NULL 31. //不为空,就把尾结点指针域指向现在的0号结点 32. pLast->next = pTemp->next; 33. } 34. if (pHead->length == 0) 35. { 36. //删除一个结点后,链表为空 37. pHead->head.next = NULL; 38. pHead->slider = NULL; 39. } 40. if (pTemp == pHead->slider) 41. { 42. //游标元素被删,游标下移 43. pHead->slider = pTemp->next; 44. } 45. return pTemp; 46. }
删除元素示意图
(1)普通位置删除
(2)尾部删除
(3)头部删除
对于前两种情况,删除结点需要借助两个辅助指针,一个pCurrent指示当前结点,其作用类似于插入节点中的pCurrent,另一个pTemp用于保存被删除结点,删除时,只需要pCurrent的指针域指向pTemp指针域的内容即可完成删除,和普通链表删除元素的操作一样。对于第三中情况,需要借助第三个辅助指针pLast,因为要形成环,所以删除0号结点后,要求出原来的尾部元素(删除元素前的尾部元素,而不是删除元素后的尾部元素,这是有本质区别的,详情可见代码中的注释),把原来的尾部元素,指向删除后的0号元素,也就是删除前的1号元素,所以需要一个辅助指针pLast来指向原来的尾部元素。
按结点删除元素
- 函数功能:按结点删除一个结点并返回该结点
- 函数参数:list 循环链表句柄 node要删除的链表结点元素
- 函数返回:被删除的结点
1. CircleListNode* CircleList_DeleteNode(CircleList* list, CircleListNode* node) 2. { 3. int i = 0; 4. CircleListHead* pHead = NULL; 5. CircleListNode* pCurrent = NULL; 6. CircleListNode* pTemp = NULL; 7. if ((list == NULL) || (node == NULL)) 8. { 9. printf("err: (list == NULL) || (node == NULL)\n"); 10. return NULL; 11. } 12. pHead = (CircleListHead*)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. CircleList_Delete(list, i - 1); 26. } 27. return pTemp; 28. }
重置游标
- 函数功能:将游标指向第一个元素
- 函数参数:list 循环链表句柄
- 函数返回:游标位置
1. CircleListNode* CircleList_Reset(CircleList* list) 2. { 3. CircleListHead* pHead = NULL; 4. if (list == NULL) 5. { 6. printf("list == NULL\n"); 7. return NULL; 8. } 9. pHead = (CircleListHead*)list; 10. pHead->slider = pHead->head.next; 11. return pHead->slider; 12. }
返回当前游标
- 函数功能:获取游标当前指向的结点
- 函数参数:list 循环链表句柄
- 函数返回:游标位置
1. CircleListNode* CircleList_Current(CircleList* list) 2. { 3. if (list == NULL) 4. { 5. printf("list == NULL\n"); 6. return NULL; 7. } 8. return ((CircleListHead*)list)->slider; 9. }
游标下移
- 函数功能:获取游标当前指向的结点,并将游标下移
- 函数参数:list 循环链表句柄
- 函数返回:下移前的游标位置
1. CircleListNode* CircleList_Next(CircleList* list) 2. { 3. CircleListNode* pTemp = NULL; 4. if (list == NULL) 5. { 6. printf("err: (list == NULL)\n"); 7. return NULL; 8. } 9. pTemp = ((CircleListHead*)list)->slider; 10. ((CircleListHead*)list)->slider = pTemp->next; 11. return pTemp; 12. }
测试函数
1. #include "CircleList.h" 2. 3. typedef struct MyData 4. { 5. CircleListNode* node; 6. int data; 7. }MyData; 8. 9. int main() 10. { 11. int i = 0; 12. int ret = 0; 13. MyData m[10]; 14. CircleList* mList = NULL; 15. 16. for (i = 0; i < 10; i++) 17. { 18. m[i].data = i + 1; 19. } 20. 21. mList = CircleList_Create(); 22. if (mList == NULL) 23. { 24. ret = -1; 25. printf("CircleList_Create() err: %d\n", ret); 26. return -1; 27. } 28. 29. printf("链表长度:"); 30. for (i = 0; i < 10; i++) 31. { 32. ret = CircleList_Insert(mList, (CircleListNode*)&m[i], 0); 33. if (ret != 0) 34. { 35. ret = -2; 36. printf("CircleList_Insert() err: %d\n", ret); 37. return ret; 38. } 39. printf("%d ", CircleList_Length(mList)); 40. } 41. printf("\n"); 42. 43. for (i = 0; i < 20; i++) 44. { 45. if ((i == 0) || (i == 10)) 46. { 47. printf("\n循环链表内容:"); 48. } 49. printf("%d ", ((MyData*)(CircleList_Get(mList, i)))->data); 50. } 51. 52. for (i = 0; i < 10; i++) 53. { 54. CircleList_Delete(mList, 0); 55. } 56. 57. printf("\n当前长度:%d \n", CircleList_Length(mList)); 58. CircleList_Destroy(mList); 59. 60. system("pause"); 61. return ret; 62. }
具体代码资源已上传,可在下面的链接免费下载