上篇博客中讲解了九大内部排序算法,部分算法还提供了代码实现,但是那些代码实现都是基于数组进行排序的,本篇博客就以链表排序实现几种常见的排序算法,以飨读者。

快速排序的链表实现

算法思想:对于一个链表,以head节点的值作为key,然后遍历之后的节点,可以得到一个小于key的链表和大于等于key的链表;由此递归可以对两个链表分别进行快速。这里用到了快速排序的思想即经过一趟排序能够将小于key的元素放在一边,将大于等于key的元素放在另一边。

代码实现:

  1. //快速排序
  2. public static void quickSort(ListNode begin, ListNode end){
  3. if(begin == null || begin == end)
  4. return;
  5.  
  6. ListNode index = paration(begin, end);
  7. quickSort(begin, index);
  8. quickSort(index.next, end);
  9. }
  10.  
  11. /**
  12. * 划分函数,以头结点值为基准元素进行划分
  13. * @param begin
  14. * @param end
  15. * @return
  16. */
  17. public static ListNode paration(ListNode begin, ListNode end){
  18. if(begin == null || begin == end)
  19. return begin;
  20.  
  21. int val = begin.val; //基准元素
  22. ListNode index = begin, cur = begin.next;
  23.  
  24. while(cur != end){
  25. if(cur.val < val){ //交换
  26. index = index.next;
  27. int tmp = cur.val;
  28. cur.val = index.val;
  29. index.val = tmp;
  30. }
  31. cur = cur.next;
  32. }
  33.  
  34. begin.val = index.val;
  35. index.val = val;
  36.  
  37. return index;
  38. }

归并排序的链表实现

算法思想:单链表与数组相比只能顺序访问每个元素,因此在使用二路归并排序时关键在于找到链表的中间结点将链表一分为二:可以利用快慢指针同时遍历单链表,当步长为2的指针指向链表最后一个结点或者最后一个结点的下一个结点时,步长为1的指针即指向链表的中间结点。然后是两个有序单链表的合并问题。时间复杂度为O(N*logN),空间复杂度为O(1)。

代码实现:

  1. //归并排序
  2. public static ListNode mergeSort(ListNode head){
  3. if(head == null || head.next == null) //空链表或者只有单个结点
  4. return head;
  5. ListNode slow = head, fast = head.next;
  6.  
  7. while(fast != null && fast.next != null){ //使用快慢指针寻找中间 结点
  8. slow = slow.next;
  9.  
  10. fast = fast.next;
  11. if(fast.next != null)
  12. fast = fast.next;
  13. }
  14.  
  15. ListNode ptr1 = slow.next;
  16. slow.next = null;
  17.  
  18. ListNode tmp1 = mergeSort(head);
  19. ListNode tmp2 = mergeSort(ptr1);
  20. return merge(tmp1, tmp2);
  21. }
  22.  
  23. public static ListNode merge(ListNode start1, ListNode start2){
  24. ListNode header = new ListNode(-1);
  25. ListNode pre = header;
  26.  
  27. ListNode ptr1 = start1, ptr2 = start2;
  28. while(ptr1 != null && ptr2 != null){
  29. if(ptr1.val <= ptr2.val){
  30. pre.next = ptr1;
  31. pre = ptr1;
  32. ptr1 = ptr1.next;
  33. }else{
  34. pre.next = ptr2;
  35. pre = ptr2;
  36. ptr2 = ptr2.next;
  37. }
  38. }
  39. while(ptr1 != null){
  40. pre.next = ptr1;
  41. pre = ptr1;
  42. ptr1 = ptr1.next;
  43. }
  44.  
  45. while(ptr2 != null){
  46. pre.next = ptr2;
  47. pre = ptr2;
  48. ptr2 = ptr2.next;
  49. }
  50.  
  51. return header.next;
  52.  
  53. }

冒泡排序的链表实现

算法思想:依次比较相邻的结点,如果是逆序的就交换两个结点

代码实现:

  1. //冒泡排序
  2. public static ListNode bubbleSort(ListNode head){
  3. if(head == null || head.next == null) //链表为空或者仅有单个结点
  4. return head;
  5.  
  6. ListNode cur = null, tail = null;
  7.  
  8. cur = head;
  9.  
  10. while(cur.next != tail){
  11. while(cur.next != tail){
  12. if(cur.val > cur.next.val){
  13. int tmp = cur.val;
  14. cur.val = cur.next.val;
  15. cur.next.val = tmp;
  16. }
  17. cur = cur.next;
  18. }
  19.  
  20. tail = cur; //下一次遍历的尾结点是当前结点(仔细琢磨一下里面的道道)
  21. cur = head; //遍历起始结点重置为头结点
  22. }
  23.  
  24. return head;
  25.  
  26. }

先写这几种吧,想起来再更。。。

 

常见的链表排序(Java版)的更多相关文章

  1. c++复杂桶排序Java版

    c++复杂桶排序Java版 题目和我的前几个排序一样 这次是Java版的 代码 + 注释 package com.vdian.qatest.supertagbiz.test.niu; /** * Cr ...

  2. 算法练习5---快速排序Java版

    基本思想:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成 ...

  3. 常见机试题分析Java版

    1. 操作系统任务分为系统任务和用户任务两种.其中,系统任务的优先级<50,用户任务的优先级>=50且<=255.优先级大于255的为非法任务,应予以剔除.现有一任务队列task[] ...

  4. 选择排序Java版

    package dataStructureAlgorithmReview.day01; import java.util.Arrays; /** * * @author shundong * */ p ...

  5. 南阳ACM 题目8:一种排序 Java版

    一种排序 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述 现在有很多长方形,每一个长方形都有一个编号,这个编号可以重复:还知道这个长方形的宽和长,编号.长.宽都是整数:现 ...

  6. 算法练习4---冒泡排序java版

    冒泡排序的基本思想:在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒.即:每当两相邻的数比较后发现它们的排序与排序要求相反 ...

  7. 算法练习1---桶排序java版

    今天复习了桶排序. 例如现在有满分为10分的试卷,学生得分分别为2,8,5,3,5,7,现在要给这些分数按照从大到小输出,使用桶排序的思想:有11个桶,每个桶有一个编号,编号从0-10,每出现一个分数 ...

  8. 剑指offer第二版面试题5:从尾到头打印链表(JAVA版)

    题目描述: 输入一个链表,从尾到头打印链表每个节点的值.返回新链表. import java.util.Stack; //定义链表结构 class ListNode { int value; List ...

  9. 《剑指offer》面试题13 在O(1)时间删除链表节点 Java版

    这道题的关键是知道找到尾节点的前一个节点必须遍历,而且这样做了之后总的时间复杂度还是O(1),以及如何不破坏链表删除一个已知节点 public ListNode delete(ListNode hea ...

随机推荐

  1. 【php】PHP环境整合

    很久没装环境, 今天重新装了一次.遇到不少问题.记录下方便以后查看 修改apache的配置文件httpd.conf #apache 解析phpLoadFile "C:/phpeve/php5 ...

  2. 用DataRelation给多个DataTable建立关系并显示到TreeView

    DataRelation 对象执行两种功能: 它可使与正使用的记录相关的记录可用.如果在父记录 (GetChildRows) 中,则它提供子记录:如果正使用子记录 (GetParentRow),则它提 ...

  3. Caused by: java.io.FileNotFoundException

    1.错误描述 usage: java org.apache.catalina.startup.Catalina [ -config {pathname} ] [ -nonaming ] { -help ...

  4. 小实验3:实现haproxy的增、删、查

    # Author:Alano # -*- conding:utf-8 -*- # 这里有一个问题:为什么手动删除了haproxy_new中的内容,但是执行添加命令的时候依然显示数据已经存在? f = ...

  5. 原生态的ajax代码

    <script type="text/javascript"> var xmlhttprequest; function GetXmlHttpRequest() { i ...

  6. javax顶层接口分析

    1.Servlet接口分析 此接口是Servlet的最顶层接口,其中定义了Servlet生命周期相关的方法,所有Servlet都必须实现.此接口中的方法有以下几个: public void init( ...

  7. MyEclipse 2014专业版的破解--Windows系统的软件安装

    一.破解前的准备 MyEclipse2014破解包: 您可以到计算机相关专业所用软件---百度云链接下载中找到链接地址进行下载. 二.破解步骤 1.打开破解文件资源包 2.执行run.bat 3.输入 ...

  8. TensorLayer官方中文文档1.7.4:API – 强化学习

    API - 强化学习¶ 强化学习(增强学习)相关函数. discount_episode_rewards([rewards, gamma, mode]) Take 1D float array of ...

  9. [POI2007]ATR-Tourist Attractions [TPLY]

    [POI2007]ATR-Tourist Attractions 题目链接(https://www.luogu.org/problemnew/show/P3451) 这种稠密图还是建议你不要跑spfa ...

  10. HiHocoder1415 : 后缀数组三·重复旋律3 & Poj2774:Long Long Message

    题面 HiHocoder1415 Poj2774 Sol 都是求最长公共子串,\(hihocoder\)上讲的很清楚 把两个串拼在一起,中间用一个特殊字符隔开 那么答案就是排序后相邻两个不同串的后缀的 ...