linkedlist--lecture-4

1、链表数据结构

内存利用率高;动态分配

2、链表类定义

单向链表节点

public calss ListNode {

  int val =0;

  ListNode next = null;

  public void Node(int val_) {

    this.val = val_;

    this.next = null;

  }

}

单向链表类:

public class LinkedList {

  private ListNode head = null;

  private ListNode tail = null;

  private int size = 0;

  public void LinkedList() {

    head = null;

    tail = null;

    size = 0;

  }

}

LinkedList构造函数用默认构造函数就可以,可以不实现。

3、链表的操作

1)添加add,2)按索引删除remove,3)取值get,4)修改set,5)按值删除removeByValue

public class LinkedList {

  private ListNode head = null;

  private ListNode tail = null;

  private int size = 0;

  /////////////////////////////getEntry//////////////////////////////

  public ListNode getEntry(int index) {

    if (index < 0 || index >= size) {

      return null;//或者抛出异常

    }

    ListNode cur = head;

    while (index-- != 0) {

      cur = cur.next;

    }

    return cur;

  }

  ///////////////////add////////////////////

  public void add(int index, int value) {

    if (index <0 || index > size) {

      return;//抛出异常

    }

    size++;

    LiseNode newNode  = new ListNode(value);

    if (index == 0) {

      newNode.next = head.next;

      head.next = newNode;

      return;

    }

    ListNode pre = getEntry(index - 1);

    newNode.next = pre.next;

    pre.next  = newNode;

  }

  //////////////////////remove////////////////////////

  public void remove(int index) {

    if (index  < 0 || index >= size) {

      return;///抛出异常

    }

    size--;

    if(index == 0) {

      head = head.next;

      return;

    }

    ListNode pre = getEntry(index - 1);

    pre.next = pre.next.next;

  }

  ////////////////////////get////////////////////

  public int get(int index) {

    if (index < 0 || index >= size) {

      return 0;///抛出异常

    }

    ListNode cur = getEntry(index);

    return cur.val;

  }

  /////////////////////set/////////////////////////////

  public void set(int index, int value) {

    if (index < 0 || index >= size) {

      return;//抛出异常

    }  

    ListNode cur = getEntry(index);

    cur.val = value;

  }

  /////////////////////////removeByValue/////////////////////////////

  public void removeByValue(int value) {

    ///暂时先不实现了。找到所有值相等的节点删除。

  }

}

可以使用dummy节点来消除head节点无前驱的问题。

public void add(int index, int value) {

  if (index < 0 || index >= size) {

    return;///抛出异常

  }

  size++;

  ListNode dummy = new ListNode();

  dummy.next = head;

  LiseNode pre = dummy;

  while (index-- != 0) {

    pre = pre.next;

  }

  ListNode newNode = new ListNode(value);

  newNode.next = pre.next;

  pre.next = newNode;

  head = dummy.next;

}

public void remove(int index) {

  if (index < 0 || index >= size) {

    return;//抛出异常

  }  

  size--;

  ListNode dummy = new ListNode(-1);

  dummy.next = head;

  ListNode pre = dummy;

  while (i-- != 0) {

    pre = pre.next;

  }

  pre.next = pre.next.next;

  head = dummy.next;

}

3、链表应用count related

1)linkedlist length

public int getLength(ListNode head) {

  ListNode cur = head;

  int length = 0;

  while(cur != null) {

    length++;

    cur = cur.next;

  }

  return length;

}

2)Kth node from the end

Given a linked list,  return the kth node from the end. Linked list will never beempty and k will always be valid.

Examples:

Input: 1->4->2->3, 2

Output: 2

Input: 3->5->9->6->8, 3

Output: 9

  k is counted from 0 or 1?

method 1:

public LinkedList getTargetNode(ListNode head, int k) {

  int length = 0;

  length = getLength(head);

  ListNode cur = head;

  for (int i = 0; i < length - k; i++) {

    cur = cur.next;

  }

  return cur;

}

时间复杂度:n + n - k = 2 * n - k

method 2:

public ListNode getTargetNode(ListNode head, int k) {

  ListNode curForward = head;

  ListNode curPost = head;

  int i = 0;

  while (i < k) {

    curForward = curForward.next;

    i++;

  }

/***

*while (k-- != 0) {curForward = curForward.next}

***/

  while (curForward != null) {

    curForward = curForward.next;

    curPost = curPost.next;

  }

  return curPost;

}

时间复杂度:k + 2 * (n-k) = 2 * n - k

3、middle node

Given a linked list,  return the middle node. Linked list will never be empty.

Examples:

Input: 1->4->2->3

Output: 4

Input: 3->5->9->6->8

Output: 9

method 1:

public ListNode getMiddleNode(ListNode head) {

  ListNode cur = head;

  int length = getLength(head);

  int i = (length - 1) / 2;

  while (i-- != 0) {

    cur = cur.next;

  }

  return cur;

}

method 2:

public ListNode getMiddleNode(ListNode head) {

  ListNode fast = head;

  ListNode slow = head;

  while (fast.next != null && fast.next.next != null) {

    fast = fast.next;

    slow = slow.next;

  }

  return slow;

}

4、Linked List Cycle

Given a linked list,  define if there is a cycle in it.

Examples:

Input: 1->4->2->3

Output: false.

Input: 3->5->9->3(original)

Output: true

public boolean findListCycle(ListNode head) {

  ListNode fast = head;

  ListNode slow = head;

  while (fast != null && fast.next != null) {

    if (fast.next == slow) {/******中间差一步时,下一个循环是slow走一步,fast走两步,相遇*******/

      return true;

    }

    slow = slow.next;

    fast = fast.next.next;

  }

  return false;

}

链表的环入口节点分析:http://blog.csdn.net/cyuyanenen/article/details/51712420

时间: 2024-10-10 23:24:50

linkedlist--lecture-4的相关文章

Java中ArrayList和LinkedList区别

一般大家都知道ArrayList和LinkedList的大致区别:      1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构.      2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针.      3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据. ArrayList和LinkedList是两个集合类,用于存储一系列的对象引用

ArrayList&amp;LinkedList&amp;Map&amp;Arrays

Java集合框架 1:集合接口 1.1:Collection接口 Collection接口是构造集合框架的基础.它声明所有类集合都将拥有的核心方法 Boolean add(Object obj) 将obj加入到调用类集合中,加入返回true 否则 返回 false Boolean addAll(Collection c) 将c中所有元素都加入到类集合中,都加入返回true否则 false Void clean() 从调用类集合中删除所有元素 Boolean contains(Object obj

Java集合类库 LinkedList 源码解析

基于JDK 1.7,和ArrayList进行比较分析 Java已经有了ArrayList,用来存放元素,对元素的操作都很方便.为什么还会有LinkedList呢?我们都知道ArrayList获取元素很快,但是插入一个元素很慢,因为ArrayList底层维护的是一个数组,往数组中的某个位置插入一个元素,是很消耗资源的. 而LinkedList插入元素很快,获取任意位置的元素却很慢.这是为什么呢?底层又是怎样实现的呢? 1.继承关系 LinkedList的继承关系图: LinkedList继承的是A

To Java程序员:切勿用普通for循环遍历LinkedList

ArrayList与LinkedList的普通for循环遍历 对于大部分Java程序员朋友们来说,可能平时使用得最多的List就是ArrayList,对于ArrayList的遍历,一般用如下写法: public static void main(String[] args) { List<Integer> arrayList = new ArrayList<Integer>(); for (int i = 0; i < 100; i++) arrayList.add(i);

从头认识java-9.7 LinkedList

这一章节我们来简单介绍一个LinkedList的一些方法与特性. 1.特性 在中间插入或者删除元素会比ArrayList的性能好,但是有不一定的情况,请点击(List的简介与性能),里面有一个简单的测试 2.方法演示 package com.ray.ch09; import java.util.Arrays; import java.util.LinkedList; public class Test { public static void main(String[] args) { Link

java的List接口的实现类 ArrayList,LinkedList,Vector 的区别

Java的List接口有3个实现类,分别是ArrayList.LinkedList.Vector,他们用于存放多个元素,维护元素的次序,而且允许元素重复. 3个具体实现类的区别如下: 1. ArrayList是最常用的List实现类,内部是通过数组实现的,它允许对元素进行快速随机访问.数组的缺点是每个元素之间不能有间隔,当数组大小不满足时需要增加存储能力,就要将已经有数组的数据复制到新的存储空间中.当从ArrayList的中间位置插入或者删除元素时,需要对数组进行复制.移动.代价比较高.因此,它

Java 集合之LinkedList源码分析

1.介绍 链表是数据结构中一种很重要的数据结构,一个链表含有一个或者多个节点,每个节点处理保存自己的信息之外还需要保存上一个节点以及下一个节点的指针信息.通过链表的表头就可以访问整个链表的信息.Java API中提供了链表的Java实现---LinkedList下.LinkedList是通过节点的连接实现链表的数据结构,向linkedList中插入或删除元素的速度是特别快,而随机访问的速度相对较慢,这个是由于链表本身的性质造成的,在链表中,每个节点都包含了前一个节点的引用,后一个节点的引用和节点

ArrayList和LinkedList的区别

从字面上大概可以猜出ArrayList是用数组实现的的一种数据结构:LinkedList采用链表实现.那么要剖析区别的话大概可以概括到数组和链表的区别.结合在数据结构课上所学,我大概可以猜出几点区别,无外乎数组采用连续的内存空间存储数据,链表中用到了引用,那么存储的内容可以不在连续的内存空间里.以上是假如不会ArrayList和LinkedList的前提下做的假设.实际上两者主要区别有三点. 1.ArrayList是使用动态数组实现的数据结构,LinkedList使用双链表实现   2.Arra

List、ArrayList、LinkedList的区别及使用

首先我们要知道List是java中的接口,而不是实现类,所以它是不能实例化的,例如以下代码: 1 public static void main(String[] args) { 2 List list=new List(); 3 4 } java中会报错,而ArrayList和LinkedList是实现了这个接口的实现类,可以进行实例化,其定义如下: 1 public static void main(String[] args) { 2 3 ArrayList list1=new Array

Java中arraylist和linkedlist源代码分析与性能比較

Java中arraylist和linkedlist源代码分析与性能比較 1,简单介绍 在java开发中比較经常使用的数据结构是arraylist和linkedlist,本文主要从源代码角度分析arraylist和linkedlist的性能. 2,arraylist源代码分析 Arraylist底层的数据结构是一个对象数组.有一个size的成员变量标记数组中元素的个数,例如以下图: * The array buffer into which the elements of the ArrayLis