当前位置:   article > 正文

嵌入式学习第三十天!(单向链表练习)

嵌入式学习第三十天!(单向链表练习)

1. 单向链表的逆序:

  1. int Is_Empty_Link(LINK_LIST *plist)
  2. {
  3. return plist->phead == NULL;
  4. }
  5. void Reverse_Link(LINK_LIST *plist)
  6. {
  7. LINK_NODE *ptmp = plist->phead;
  8. LINK_NODE *pinsert = NULL;
  9. plist->phead = NULL;
  10. if(Is_Empty_Link(plist))
  11. {
  12. return;
  13. }
  14. else
  15. {
  16. while(ptmp != NULL)
  17. {
  18. pinsert = ptmp;
  19. ptmp = ptmp->pnext;
  20. pinsert->pnext = plist->phead;
  21. plist->phead = pinsert;
  22. }
  23. }
  24. return;
  25. }

        在这里的逆序,利用了头插法的思想,因为利用头插法插入数据,数据是逆序插入的,最后插入的数据在最前面,最先插入的数据在最后面,那么逆序也可以使用这个思想。

2. 找到单向链表中的中间结点

  1. LINK_NODE *Find_Center_Link(LINK_LIST *plist)
  2. {
  3. LINK_NODE *pfast = plist->phead;
  4. LINK_NODE *pslow = plist->phead;
  5. while(pfast != NULL)
  6. {
  7. pfast = pfast->pnext;
  8. if(pfast == NULL)
  9. {
  10. break;
  11. }
  12. pfast = pfast->pnext;
  13. pslow = pslow->pnext;
  14. }
  15. return pslow;
  16. }

        采用链表中比较常用的快慢指针法,那么快指针每次走两步,慢指针每次走一步,当快指针走到等于NULL的时候,慢指针刚好走到了中间结点,但是在这个地方,如果遇到偶数个结点的单向链表,那么得到的中间结点为中间的后一个结点。如果想要中间结点的前一个结点的话,那么需要修改一下判断条件:

  1. LINK_NODE *Find_Center_Link(LINK_LIST *plist)
  2. {
  3. LINK_NODE *pfast = plist->phead;
  4. LINK_NODE *pslow = plist->phead;
  5. while(1)
  6. {
  7. pfast = pfast->pnext;
  8. if(pfast == NULL)
  9. {
  10. break;
  11. }
  12. pfast = pfast->pnext;
  13. if(pfast == NULL)
  14. {
  15. break;
  16. }
  17. pslow = pslow->pnext;
  18. }
  19. return pslow;
  20. }

3. 找到单向链表的倒数第K个结点

  1. LINK_NODE *Find_Last_K_Node(LINK_LIST *plist, int K)
  2. {
  3. LINK_NODE *pfast = plist->phead;
  4. LINK_NODE *pslow = plist->phead;
  5. for(int i = 0; i < K; i++)
  6. {
  7. if(pfast == NULL)
  8. {
  9. return NULL;
  10. }
  11. pfast = pfast->pnext;
  12. }
  13. while(pfast != NULL)
  14. {
  15. pfast = pfast->pnext;
  16. pslow = pslow->pnext;
  17. }
  18. return pslow;
  19. }

        同样可以使用快慢指针法的思想,让快指针先走K步,然后再让快指针和慢指针同时一起走,当快指针走到等于NULL的时候,那么慢指针刚好比慢指针少K步,也就是倒数第K个结点

4. 删除单向链表的某个结点

  1. int Delete_Link_Node(LINK_LIST *plist, DATA_TYPE data)
  2. {
  3. if(Is_Empty_Link(plist))
  4. {
  5. return 0;
  6. }
  7. LINK_NODE *pfree = plist->phead;
  8. LINK_NODE *ppre = NULL;
  9. int del_cnt = 0;
  10. while(pfree != NULL)
  11. {
  12. if(pfree->data == data)
  13. {
  14. if(pfree == plist->phead)
  15. {
  16. plist->phead = pfree->pnext;
  17. free(pfree);
  18. pfree = plist->phead;
  19. }
  20. else
  21. {
  22. ppre->pnext = pfree->pnext;
  23. free(pfree);
  24. pfree = ppre->pnext;
  25. }
  26. plist->curlen--;
  27. del_cnt++;
  28. }
  29. else
  30. {
  31. ppre = pfree;
  32. pfree = pfree->pnext;
  33. }
  34. }
  35. return del_cnt;
  36. }

        可以发现这段代码可以将所有数据为data的链表结点都删除了,如果只想删除第一个的话,那就在找到第一个数据为data的结点以后,将结点free掉,然后直接return,那么程序就实现了只删除第一个。

5. 实现单向链表的升序排序(插入排序的思想)

  1. int Insert_Sort_Link(LINK_LIST *plist)
  2. {
  3. LINK_NODE *pinsert = NULL;
  4. LINK_NODE *ptmp = plist->phead;
  5. plist->phead->pnext = NULL;
  6. while(ptmp != NULL)
  7. {
  8. pinsert = ptmp;
  9. ptmp = ptmp->pnext;
  10. if(pinsert->data <= plist->phead->data)
  11. {
  12. pinsert->pnext = plist->phead;
  13. plist->phead = pinsert;
  14. }
  15. else
  16. {
  17. LINK_NODE *perg = plist->phead;
  18. while(perg->pnext != NULL && pinsert->data >= perg->pnext->data)
  19. {
  20. perg = perg->pnext;
  21. }
  22. pinsert->pnext = perg->pnext;
  23. perg->pnext = pinsert;
  24. }
  25. }
  26. return 0;
  27. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/295395
推荐阅读
相关标签
  

闽ICP备14008679号