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

快速排序的链表实现

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

代码实现:

     //快速排序
public static void quickSort(ListNode begin, ListNode end){
if(begin == null || begin == end)
return; ListNode index = paration(begin, end);
quickSort(begin, index);
quickSort(index.next, end);
} /**
* 划分函数,以头结点值为基准元素进行划分
* @param begin
* @param end
* @return
*/
public static ListNode paration(ListNode begin, ListNode end){
if(begin == null || begin == end)
return begin; int val = begin.val; //基准元素
ListNode index = begin, cur = begin.next; while(cur != end){
if(cur.val < val){ //交换
index = index.next;
int tmp = cur.val;
cur.val = index.val;
index.val = tmp;
}
cur = cur.next;
} begin.val = index.val;
index.val = val; return index;
}

归并排序的链表实现

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

代码实现:

     //归并排序
public static ListNode mergeSort(ListNode head){
if(head == null || head.next == null) //空链表或者只有单个结点
return head;
ListNode slow = head, fast = head.next; while(fast != null && fast.next != null){ //使用快慢指针寻找中间 结点
slow = slow.next; fast = fast.next;
if(fast.next != null)
fast = fast.next;
} ListNode ptr1 = slow.next;
slow.next = null; ListNode tmp1 = mergeSort(head);
ListNode tmp2 = mergeSort(ptr1);
return merge(tmp1, tmp2);
} public static ListNode merge(ListNode start1, ListNode start2){
ListNode header = new ListNode(-1);
ListNode pre = header; ListNode ptr1 = start1, ptr2 = start2;
while(ptr1 != null && ptr2 != null){
if(ptr1.val <= ptr2.val){
pre.next = ptr1;
pre = ptr1;
ptr1 = ptr1.next;
}else{
pre.next = ptr2;
pre = ptr2;
ptr2 = ptr2.next;
}
}
while(ptr1 != null){
pre.next = ptr1;
pre = ptr1;
ptr1 = ptr1.next;
} while(ptr2 != null){
pre.next = ptr2;
pre = ptr2;
ptr2 = ptr2.next;
} return header.next; }

冒泡排序的链表实现

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

代码实现:

     //冒泡排序
public static ListNode bubbleSort(ListNode head){
if(head == null || head.next == null) //链表为空或者仅有单个结点
return head; ListNode cur = null, tail = null; cur = head; while(cur.next != tail){
while(cur.next != tail){
if(cur.val > cur.next.val){
int tmp = cur.val;
cur.val = cur.next.val;
cur.next.val = tmp;
}
cur = cur.next;
} tail = cur; //下一次遍历的尾结点是当前结点(仔细琢磨一下里面的道道)
cur = head; //遍历起始结点重置为头结点
} return head; }

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

 

常见的链表排序(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. DirectDraw用到的DDSURFACEDESC2

    DDSURFACEDESC2 结构定义一个需求的平面.下面的例子演示了结构的定义和标志位的设定: // Create the primary surface with one back buffer. ...

  2. R语言︱函数使用技巧(循环、if族/for、switch、repeat、ifelse、stopifnot)

    每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- 后续加更内容: 应用一:if族有哪些成员呢?- ...

  3. Java中字符串的一些常见方法

    1.Java中字符串的一些常见方法 /** * */ package com.you.model; /** * @author Administrator * @date 2014-02-24 */ ...

  4. 做一个合格的Team Leader -- 基本概念

    1.领导和管理 人们乐于被领导:他们不喜欢被管理,不喜欢像牛一样被驱赶或指挥. 管理者强迫人们服从他们的命令,而领导者则会带领他们一起工作. 管理是客观的,没有个人感情因素,它假定被管理者没有思想和感 ...

  5. tcp为什么要三次握手,而不能二次握手?

    谢希仁版<计算机网络>中的例子是这样的,"已失效的连接请求报文段"的产生在这样一种情况下:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞 ...

  6. freemarker中的left_pad和right_pad(十五)

    freemarker中的left_pad和right_pad 1.简易说明 (1)left_pad 距左边 (2)right_pad 距右边 (3)当仅仅只有一个参数时,插入的是空白:当有两个参数时, ...

  7. freemarker之list遍历(八)

    1.设置数据源 /** * * @Title:student * @Description: * @param:@param name * @return: void * @throws */ pri ...

  8. MFC,ADO方式实现数据库操作

    参考: MSDN数据访问编程 (MFC/ATL): https://msdn.microsoft.com/zh-cn/library/kd4ck1tt.aspx?f=255&MSPPError ...

  9. AC自动机模板2(【CJOJ1435】)

    题面 Description 对,这就是裸的AC自动机. 要求:在规定时间内统计出模版字符串在文本中出现的次数. Input 第一行:模版字符串的个数N. 第2->N+1行:N个字符串.(每个模 ...

  10. [HDU5765]Bonds

    题面 题意 给出一张\(n\)点\(m\)边无向连通图,求每条边出现在多少个割集中. \(n\le20,m\le\frac{n(n-1)}{2}\) sol 所谓割集,就是指把\(n\)个点分成两个集 ...