当前位置:   article > 正文

单链表的排序(快速排序与插入排序)_单链表从小到大排序插入

单链表从小到大排序插入

目录

单链表的快速排序

单链表的插入排序

单链表的快速排序

单链表的快速排序和数组的快排基本思想相同,同样是不断划分。(以从小到大排序为例)取一个结点设其为关键结点,将所有结点的数字与其比较,比关键结点数字大的放在结点的右边,比关键结点数字小的放在关键结点的左边。

单个排序为例(privot指针指向的为关键结点,p为与其比较的数字的结点,i指针指向所比较数字的上一个结点):

head435NULL
pr、ip
head345NUp
ppr、i

此链表设4为关键节点,3比4小因此应该放在4的左边,因此交换两节点的位置。交换结点的代码如下:

  1. if(privot->val > p->val)
  2. {
  3. i->next = p->next;
  4. p->next = head->next;
  5. head->next = p;
  6. }

交换后则p应该向前移一位,此时p与pr结点相同,不符合以上交换条件,则指针位置并不改变,但由于循环会使p向后移一位,因此在不交换结点时,应该让i指针向后移一位。

以此类推,当此次循环结束可知关键结点左边都比它小,右边都比它大,即关键结点的位置确定了。因此使关键结点左边与右边分成两半,分别以同样的方式排序,即进入递归。通过递归排序完成。

单链表的快速排序代码如下:

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. struct stu
  4. {
  5. int val;
  6. struct stu *next;
  7. };
  8. struct stu *partition(struct stu *head, struct stu *tail)
  9. {
  10. struct stu *p, *i, *privot;
  11. privot = head->next;
  12. for(i = privot, p = privot->next; p && p != tail; p = i->next)
  13. {
  14. if(privot->val > p->val)
  15. {
  16. i->next = p->next;
  17. p->next = head->next;
  18. head->next = p;
  19. }
  20. else
  21. {
  22. i = i->next;
  23. }
  24. }
  25. return privot;
  26. }
  27. void Quick_Sort(struct stu *head, struct stu *tail)
  28. {
  29. if(!head || head->next == tail || head->next->next == tail)
  30. {
  31. return ;
  32. }
  33. struct stu *privot = partition(head, tail);
  34. Quick_Sort(head, privot);
  35. Quick_Sort(privot, tail);
  36. }
  37. int main()
  38. {
  39. int n, i;
  40. scanf("%d",&n);
  41. struct stu *head = (struct stu *)malloc(sizeof(struct stu));
  42. struct stu *tail, *s;
  43. tail = head;
  44. for(i = 0; i < n; i++)
  45. {
  46. struct stu *p = (struct stu *)malloc(sizeof(struct stu));
  47. scanf("%d",&p->val);
  48. tail->next = p;
  49. tail = p;
  50. }
  51. tail->next = NULL;
  52. tail = NULL;
  53. Quick_Sort(head, tail);
  54. s = head->next;
  55. for(i = 0; i < n; i++)
  56. {
  57. printf("%d ",s->val);
  58. s = s->next;
  59. }
  60. }

单链表的插入排序

(以从小到大为例)插入排序为以第二个数字开始,将每一个数字插入到比它小的数字之前,curr指针所指向的为被插入的结点位置,与前一个结点进行比较,如果它比前一个结点数字小即代表它需要插入。进入内层循环,prev所指向的结点为插入位置的前一个结点,当prev的下一个结点的数字大于我们所要插入的结点数字时,进行插入操作。

刚开始head432NULL
指针位置prevlcurr
交换后head342NULL
currl

因为3比4小因此将3进行插入操作。插入时应先时prev位于头结点位置,进行循环,找到插入点。

插入操作代码如下:

  1. struct stu *prev = head;
  2. while(prev->next->val <= curr->val)
  3. {
  4. prev = prev->next;
  5. }
  6. l->next = curr->next;
  7. curr->next = prev->next;
  8. prev->next = curr;

如果curr指向的数字比l指向的数字大,无需插入,则使两个指针都向后移,若出现了插入操作只需使curr放在l的后一个结点。

单链表的插入排序代码如下:

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. struct stu
  4. {
  5. int val;
  6. struct stu *next;
  7. };
  8. int main()
  9. {
  10. int n, i;
  11. scanf("%d",&n);
  12. struct stu *head = (struct stu *)malloc(sizeof(struct stu));
  13. struct stu *tail, *s;
  14. tail = head;
  15. for(i = 0; i < n; i++)
  16. {
  17. struct stu *p = (struct stu *)malloc(sizeof(struct stu));
  18. scanf("%d",&p->val);
  19. tail->next = p;
  20. tail = p;
  21. }
  22. tail->next = NULL;
  23. tail = NULL;
  24. struct stu *l = head->next;
  25. struct stu *curr = head->next->next;
  26. while(curr != NULL)
  27. {
  28. if(l->val <= curr->val)
  29. {
  30. l = l->next;
  31. }
  32. else
  33. {
  34. struct stu *prev = head;
  35. while(prev->next->val <= curr->val)
  36. {
  37. prev = prev->next;
  38. }
  39. l->next = curr->next;
  40. curr->next = prev->next;
  41. prev->next = curr;
  42. }
  43. curr = l->next;
  44. }
  45. s = head->next;
  46. for(i = 0; i < n; i++)
  47. {
  48. printf("%d ",s->val);
  49. s = s->next;
  50. }
  51. }

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

闽ICP备14008679号