在做Coursera上的Algorithms第三周测验练习的时候有一道链表随机排序问题,刚开始没有什么思路,就想着先把单向链表归并排序实现了,再此基础上进行随机排序的改造。于是就结合归并排序算法,实现了单向链表的归并排序。

 import java.util.Iterator;
/**
* 对单向链表的由小到大归并排序
* @author evasean www.cnblogs.com/evasean/
* @param <T>
*/
public class MergeSortLinkedList <T extends Comparable<T>> implements Iterable<T>{
private Node first = null;
private Node last = null;
private int n;
private class Node{
T element;
Node next;
}
private boolean less(Comparable v, Comparable w) {
return v.compareTo(w) < 0;
}
@Override
public Iterator<T> iterator() {
// TODO Auto-generated method stub
return new ListIterator();
}
private class ListIterator implements Iterator<T>{
private Node current = first;
@Override
public boolean hasNext() {
// TODO Auto-generated method stub
return current != null;
} @Override
public T next() {
// TODO Auto-generated method stub
T t = current.element;
current = current.next;
return t;
}
}
public void add(T t){
Node node = new Node();
node.element = t;
node.next = null;
if(first == null && last == null){
first = node;
last = node;
}else if(first != null && first == last){
first.next = node;
last = node;
}else{
last.next = node;
last = node;
}
n++;
}
@Override
public String toString(){
Iterator<T> iter = iterator();
String ret = iter.next().toString();
while(iter.hasNext()){
ret += ", "+ iter.next().toString() ;
}
return ret;
}
public void mergeSort(){
first = sort(first);
} private Node sort(Node head){
if(head == null || head.next == null) return head;
Node slow = head;
Node fast = head;
//取中间节点
while(fast.next != null && fast.next.next != null){
slow = slow.next;
fast = fast.next.next;
}
Node left = head;
Node right = slow.next;
slow.next = null; //将左右链表分开
left = sort(left);
right = sort(right);
return merge(left,right);
}
private Node merge(Node left, Node right){
//System.out.println("left="+left.element+",right="+right.element);
Node aux = new Node(); //需要耗费logn的额外空间
Node l= left;
Node r = right;
Node current = aux;
while(l != null && r!=null){
if(less(r.element,l.element)) {
current.next = r;
current = current.next;
r = r.next;
}
else {
current.next = l;
current = current.next;
l= l.next;
}
}
if(l!=null) current.next = l; // 如果左侧没遍历完,将其连接至current后
else if(r != null) current.next = r; //如果右侧没遍历完,将其连接至current后
return aux.next; //返回归并好的链表
}
public static void main(String[] args){
ShuffleLinkedList<Integer> sll = new ShuffleLinkedList<Integer>();
sll.add(1);
sll.add(2);
sll.add(11);
sll.add(9);
sll.add(10);
sll.add(4);
sll.add(7);
System.out.println(sll);
sll.mergeSort();
System.out.println(sll);
} }

单向链表的归并排序——java实现的更多相关文章

  1. 单向链表的简单Java实现-sunziren

    写在前面,csdn的那篇同名博客就是我写的,我把它现在在这边重新发布,因为我实在不想用csdn了,那边的广告太多了,还有就是那个恶心人的“阅读更多”按钮,惹不起我躲得起. 最近面试的过程中,发现有的公 ...

  2. leetcode23 多个拍好序的链表进行归并排序 (java版本)

    题目: Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexit ...

  3. Java实现单向链表基本功能

    一.前言 最近在回顾数据结构与算法,有部分的算法题用到了栈的思想,说起栈又不得不说链表了.数组和链表都是线性存储结构的基础,栈和队列都是线性存储结构的应用- 本文主要讲解单链表的基础知识点,做一个简单 ...

  4. [Java算法分析与设计]--单向链表(List)的实现和应用

    单向链表与顺序表的区别在于单向链表的底层数据结构是节点块,而顺序表的底层数据结构是数组.节点块中除了保存该节点对应的数据之外,还保存这下一个节点的对象地址.这样整个结构就像一条链子,称之为" ...

  5. JAVA单向链表实现

    JAVA单向链表实现 单向链表 链表和数组一样是一种最常用的线性数据结构,两者各有优缺点.数组我们知道是在内存上的一块连续的空间构成,所以其元素访问可以通过下标进行,随机访问速度很快,但数组也有其缺点 ...

  6. 线性表的Java实现--链式存储(单向链表)

    单向链表(单链表)是链表的一种,其特点是链表的链接方向是单向的,对链表的访问要通过顺序读取从头部开始. 链式存储结构的线性表将采用一组任意的存储单元存放线性表中的数据元素.由于不需要按顺序存储,链表在 ...

  7. JAVA 单向链表

    package com.session.link; /** * 单向链表 */public class LinkedList<T> { private Node head;//指向链表头节 ...

  8. Java 单向链表学习

    Java 单向链表学习 链表等同于动态的数组:可以不同设定固定的空间,根据需要的内容动态的改变链表的占用空间和动态的数组同一形式:链表的使用可以更加便于操作. 链表的基本结构包括:链表工具类和节点类, ...

  9. java对单向单向链表的操作

    概述:众所周知,数据对于数据的存储时连续的,也就是说在计算机的内存中是一个整体的.连续的.不间断的ADT数据结构.伴随的问题也会随之出现,这样其实对于内存的动态分配是不灵活的.而链表具备这个优点.因此 ...

随机推荐

  1. HDU_1698_Just a Hook_线段树区间更新

    Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  2. 通过offset值的设置使html元素对齐

    今天是我第一次写这个随笔,为了记录我发现的一个jquery的offset的值的问题. 这个offset的值会因为页面标签是否处于隐藏状态而表现出不同的值,隐藏状态时,offset的值是相对于直接父亲的 ...

  3. Android获取SD卡路径/内存的几种方法

    Android获取SD卡路径 本篇将会带领大家学习如何获取android路径的几种常见用法,但在我开始bb之前需要大家清楚android中内存和外存之间的区别,下面进行简短介绍:android中的内存 ...

  4. 网络编程_socketserver

    一.socketserver 网络编程 1.socketserver支持多用户并发处理:2.socketserver是对socket的再封装;处理步骤:1.创建一个socketserver类2.继承B ...

  5. CentOS 7.2安装配置Vsftp服务器

    一.配置防火墙,开启FTP服务器需要的端口 CentOS 7.2默认使用的是firewall作为防火墙,这里改为iptables防火墙. 1.关闭firewall: systemctl stop fi ...

  6. 5.terms搜索多个值以及多值搜索结果优化

    主要知识点 terms搜索多个值,并和term的比较     一.term和terms terms是在这个字段中搜索多个值,相当于sql中的in语法 (select * from tbl where ...

  7. linux - 运维软件saltstack

    目录 运维软件saltstack 安装使用流程 运维软件saltstack 早期运维人员会根据自己的生产环境来写特定脚本完成大量重复性工作,这些脚本复杂且难以维护.系统管理员面临的问题主要是1.系统配 ...

  8. 6.3.1 使用 pickle 模块读写二进制文件

    Python 标准库 pickle 提供的 dump() 方法 用于将数据进行序列化并写入文件(dump() 方法的protocol 参数为True 时可以实现压缩的效果),而load() 用于读取二 ...

  9. crontab定时任务安装、使用方法

    本文介绍下,在linux中安装crontab的方法,以及crontab的具体用法,有需要的朋友参考下. 这里使用yum方式安装crontab:  复制代码代码示例: [root@CentOS ~]# ...

  10. 2.1.4、SparkEnv中创建BroadcastManager

    Broadcast是分布式的数据共享,由BroadcastManager负责管理其创建或销毁.Broadcast一般用于处理共享的配置文件.通用Dataset.常用数据结构 通过SparkContex ...