Java模拟有序链表数据结构的示例

有序链表:
按关键值排序。删除链头时,就删除最小(/最大)的值,插入时,搜索插入的位置。
插入时需要比较O(N),平均O(N/2),删除最小(/最大)的在链头的数据时效率为O(1),
如果一个应用需要频繁的存取(插入/查找/删除)最小(/最大)的数据项,那么有序链表是一个不错的选择
优先级队列 可以使用有序链表来实现
有序链表的插入排序:
对一个无序数组,用有序链表来排序,比较的时间级还是O(N^2)
复制时间级为O(2*N),因为复制的次数较少,第一次放进链表数据移动N次,再从链表复制到数组,又是N次
每插入一个新的链结点,不需要复制移动数据,只需要改变一两个链结点的链域

import java.util.Arrays;
import java.util.Random; 

/**
 * 有序链表 对数组进行插入排序
 * @author stone
 */
public class LinkedListInsertSort<T extends Comparable<T>> { 

  private Link<T> first;    //首结点
  public LinkedListInsertSort() { 

  } 

  public boolean isEmpty() {
    return first == null;
  } 

  public void sortList(T[] ary) {
    if (ary == null) {
      return;
    }
    //将数组元素插入进链表,以有序链表进行排序
    for (T data : ary) {
      insert(data);
    }
    // 

  } 

  public void insert(T data) {// 插入 到 链头, 以从小到大排序
    Link<T> newLink = new Link<T>(data);
    Link<T> current = first, previous = null;
    while (current != null && data.compareTo(current.data) > 0) {
      previous = current;
      current = current.next;
    }
    if (previous == null) {
      first = newLink;
    } else {
      previous.next = newLink;
    }
    newLink.next = current;
  } 

  public Link<T> deleteFirst() {//删除 链头
    Link<T> temp = first;
    first = first.next; //变更首结点,为下一结点
    return temp;
  } 

  public Link<T> find(T t) {
    Link<T> find = first;
    while (find != null) {
      if (!find.data.equals(t)) {
        find = find.next;
      } else {
        break;
      }
    }
    return find;
  } 

  public Link<T> delete(T t) {
    if (isEmpty()) {
      return null;
    } else {
      if (first.data.equals(t)) {
        Link<T> temp = first;
        first = first.next; //变更首结点,为下一结点
        return temp;
      }
    }
    Link<T> p = first;
    Link<T> q = first;
    while (!p.data.equals(t)) {
      if (p.next == null) {//表示到链尾还没找到
        return null;
      } else {
        q = p;
        p = p.next;
      }
    } 

    q.next = p.next;
    return p;
  } 

  public void displayList() {//遍历
    System.out.println("List (first-->last):");
    Link<T> current = first;
    while (current != null) {
      current.displayLink();
      current = current.next;
    }
  } 

  public void displayListReverse() {//反序遍历
    Link<T> p = first, q = first.next, t;
    while (q != null) {//指针反向,遍历的数据顺序向后
      t = q.next; //no3
      if (p == first) {// 当为原来的头时,头的.next应该置空
        p.next = null;
      }
      q.next = p;// no3 -> no1 pointer reverse
      p = q; //start is reverse
      q = t; //no3 start
    }
    //上面循环中的if里,把first.next 置空了, 而当q为null不执行循环时,p就为原来的最且一个数据项,反转后把p赋给first
    first = p;
    displayList();
  } 

  class Link<T> {//链结点
    T data;   //数据域
    Link<T> next; //后继指针,结点    链域
    Link(T data) {
      this.data = data;
    }
    void displayLink() {
      System.out.println("the data is " + data.toString());
    }
  } 

  public static void main(String[] args) {
    LinkedListInsertSort<Integer> list = new LinkedListInsertSort<Integer>();
    Random random = new Random();
    int len = 5;
    Integer[] ary = new Integer[len];
    for (int i = 0; i < len; i++) {
      ary[i] = random.nextInt(1000);
    }
    System.out.println("----排序前----");
    System.out.println(Arrays.toString(ary));
    System.out.println("----链表排序后----");
    list.sortList(ary);
    list.displayList();
  }
}

打印

----排序前----
[595, 725, 310, 702, 444]
----链表排序后----
List (first-->last):
the data is 310
the data is 444
the data is 595
the data is 702
the data is 725

单链表反序:

public class SingleLinkedListReverse { 

  public static void main(String[] args) {
    Node head = new Node(0);
    Node temp = null;
    Node cur = null; 

    for (int i = 1; i <= 10; i++) {
      temp = new Node(i);
      if (i == 1) {
        head.setNext(temp);
      } else {
        cur.setNext(temp);
      }
      cur = temp;
    }//10.next = null; 

    Node h = head;
    while (h != null) {
      System.out.print(h.getData() + "\t");
      h = h.getNext();
    }
    System.out.println(); 

    //反转1
//   h = Node.reverse1(head);
//   while (h != null) {
//     System.out.print(h.getData() + "\t");
//     h = h.getNext();
//   } 

    //反转2
    h = Node.reverse1(head);
    while (h != null) {
      System.out.print(h.getData() + "\t");
      h = h.getNext();
    } 

  }
} 

/*
 * 单链表的每个节点都含有指向下一个节点属性
 */
class Node {
  Object data;//数据对象
  Node next; //下一节点 

  Node(Object d) {
    this.data = d;
  }
  Node(Object d, Node n) {
    this.data = d;
    this.next = n;
  }
  public Object getData() {
    return data;
  }
  public void setData(Object data) {
    this.data = data;
  }
  public Node getNext() {
    return next;
  }
  public void setNext(Node next) {
    this.next = next;
  }
  //方法1 head被重置
  static Node reverse1(Node head) { 

    Node p = null; //反转后新的 头
    Node q = head;
    //轮换结果:012,123,234,.... 10 null null
    while (head.next != null) {
      p = head.next;   // 第1个 换成第2个 这时p表示原始序列头中的next
      head.next = p.next; // 第2个 换成第3个
      p.next = q;     //已经跑到第1位置的原第2个的下一个 就要变成 原第1个
      q = p;       //新的第1个 要变成 当前第一个
    }
    return p; 

  }
  //方法2 head没重置
  static Node reverse2(Node head) {
    //将中间节点的指针指向前一个节点之后仍然可以继续向后遍历链表
    Node p1 = head, p2 = head.next, p3; // 前 中 后
    //轮换结果 :012, 123, 234, 345, 456.... 9 10 null
    while (p2 != null) {
      p3 = p2.next;
      p2.next = p1; //指向后 变 指向前
      p1 = p2;   //2、3向前挪
      p2 = p3;
    }
    head.next = null;//head没变,当输出到0时,再请求0.next 为1
    return p1;
  }
} 
(0)

相关推荐

  • Java模拟单链表和双端链表数据结构的实例讲解

    模拟单链表 线性表: 线性表(亦作顺序表)是最基本.最简单.也是最常用的一种数据结构. 线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的. 线性表的逻辑结构简单,便于实现和操作. 在实际应用中,线性表都是以栈.队列.字符串等特殊线性表的形式来使用的. 线性结构的基本特征为: 1.集合中必存在唯一的一个"第一元素": 2.集合中必存在唯一的一个 "最后元素" : 3.除最后一个元素之外,均有 唯一的后继(后件):

  • java 数据结构之删除链表中的元素实例代码

    java 删除链表中的元素 以下实例演示了使用 Clear() 方法来删除链表中的元素: import java.util.*; public class Main { public static void main(String[] args) { LinkedList<String> lList = new LinkedList<String>(); lList.add("1"); lList.add("8"); lList.add(&q

  • java数据结构之实现双向链表的示例

    复制代码 代码如下: /** * 双向链表的实现 * @author Skip * @version 1.0 */public class DoubleNodeList<T> { //节点类 private static class Node<T>{  Node<T> perv;  //前节点  Node<T> next;  //后节点  T data;    //数据 public Node(T t){   this.data = t;  } } priv

  • Java数据结构之双端链表原理与实现方法

    本文实例讲述了Java数据结构之双端链表原理与实现方法.分享给大家供大家参考,具体如下: 一.概述: 1.什么时双端链表: 链表中保持这对最后一个连点引用的链表 2.从头部插入 要对链表进行判断,如果为空则设置尾节点为新添加的节点 3.从尾部进行插入 如果链表为空,则直接设置头节点为新添加的节点,否则设置尾节点的后一个节点为新添加的节点 4.从头部删除 判断节点是否有下个节点,如果没有则设置节点为null 二.具体实现 /** * @描述 头尾相接的链表 * @项目名称 Java_DataStr

  • Java 数据结构链表操作实现代码

    链表是一种复杂的数据结构,其数据之间的相互关系使链表分成三种:单链表.循环链表.双向链表,下面将逐一介绍.链表在数据结构中是基础,也是重要的知识点,这里讲下Java 中链表的实现, JAVA 链表操作:单链表和双链表 主要讲述几点: 一.链表的简介 二.链表实现原理和必要性 三.单链表示例 四.双链表示例 一.链表的简介 链表是一种比较常用的数据结构,链表虽然保存比较复杂,但是在查询时候比较便捷,在多种计算机语言都相应的应用,链表有多种类别,文章针对单链表和双链表进行分析.链表中数据就像被一个链

  • 详解java数据结构与算法之双链表设计与实现

    在单链表分析中,我们可以知道每个结点只有一个指向后继结点的next域,倘若此时已知当前结点p,需要查找其前驱结点,那么就必须从head头指针遍历至p的前驱结点,操作的效率很低,因此如果p有一个指向前驱结点的next域,那效率就高多了,对于这种一个结点中分别包含了前驱结点域pre和后继结点域next的链表,称之为双链表.本篇我们将从以下结点来分析双链表 双链表的设计与实现 双链表的主要优点是对于任意给的结点,都可以很轻易的获取其前驱结点或者后继结点,而主要缺点是每个结点需要添加额外的next域,因

  • JAVA 数据结构链表操作循环链表

    JAVA 链表操作:循环链表 主要分析示例: 一.单链表循环链表 二.双链表循环链表 其中单链表节点和双链表节点类和接口ICommOperate<T>与上篇一致,这里不在赘述.参考:JAVA链表操作:单链表和双链表http://www.jb51.net/article/95113.htm 一.单链表循环链表 package LinkListTest; import java.util.HashMap; import java.util.Map; public class SingleCycle

  • Java数据结构之链表(动力节点之Java学院整理)

    单链表: insertFirst:在表头插入一个新的链接点,时间复杂度为O(1) deleteFirst:删除表头的链接点,时间复杂度为O(1) find:查找包含指定关键字的链接点,由于需要遍历查找,平均需要查找N/2次,即O(N) remove:删除包含指定关键字的链接点,由于需要遍历查找,平均需要查找N/2次,即O(N) public class LinkedList { private class Data{ private Object obj; private Data next =

  • java 数据结构单链表的实现

    java 数据结构单链表的实现 单链表实现链表的打印及元素删除操作,链表的实现主要是next属性的定义,将一堆节点关联起来的.实现简单的链表如下: public class LinkNode { private int value; private LinkNode next; public LinkNode(int x) { value = x; } public LinkNode getNext(){ return next; } public void setNext(LinkNode n

  • Java数据结构之简单链表的定义与实现方法示例

    本文实例讲述了Java数据结构之简单链表的定义与实现方法.分享给大家供大家参考,具体如下: 一.概述: 1.原理: 只有一个数据项(链接点Link),每个数据插入时都是对第一个数据的引用. 2.插入数据说明: 当链表没有数据时,插入的值就是第一个数据,如果链表里有数据,就把当前的数据的next指针指向第一个数据. 3.插入数据图: 4.特点:先进后出 5.实现功能: 数据插入,指定位置插入,显示,查询,删除等 6.删除原理 7.插入头节点原理 二.实现: 1.创建节点 /** * @描述 节点

  • java实现数据结构单链表示例(java单链表)

    复制代码 代码如下: /** * 单向链表 * */public class NodeList<E> { private static class Node<E> { // 节点类  E data; // 节点上的数据  Node<E> next; // 指向下一个节点 Node(E e) {   this.data = e;   this.next = null;  } } private Node<E> head; // 链表的头节点 private N

随机推荐