package com.qiusongde.linkedlist;

import java.util.Iterator;
import java.util.NoSuchElementException; public class LinkedList<Item> implements Iterable<Item> { private Node<Item> first; //Node should be public static in this class
//When it comes to LinkedList, Node should be accessed outside
public static class Node<E> {
public E item;
public Node<E> next;
}
/**
* initialize LinkedList
*/
public LinkedList() {
first = null;
} public LinkedList(Node<Item> first) {
this.first = first;
} /**
* insert item at the beginning of the list
* @param item the item to be inserted
*/
public void insertAtBeginning(Item item) { Node<Item> oldfirst = first; first = new Node<Item>();
first.item = item;
first.next = oldfirst; } /**
* remove the item at the beginning of the list
* @return return the item at the beginning of the list
* @throws NoSuchElementException if this Linked List is empty
*/
public Item removeFromBeginning() { if(isEmpty())
throw new NoSuchElementException("LinkedList is empty"); Item item = first.item;
first = first.next; return item;
} //1.3.19
/**
* remove the last node in the linked list whose first node is first
*
* @return return the item of the last node
* @throws NoSuchElementException if this Linked List is empty
*/
public Item removeTheLast() { Node<Item> precurrent;
Item item = null; precurrent = findPreLastNode(); //has not found
if(precurrent.next == null) {
throw new NoSuchElementException("LinkedList is empty");
} item = precurrent.next.item;
//some implementation will add one empty node as head, and head.next = first
//if so, it's not necessary to have if condition here
if(precurrent.next == first)
first = first.next;
else
precurrent.next = precurrent.next.next; return item;
} /**
* return the previous last node
*
* @return return the previous last node.
* If the last node is the first node, the previous last node is a virtual one
*/
private Node<Item> findPreLastNode() { Node<Item> precurrent = new Node<Item>();
precurrent.next = first; //find the previous last node
//precurrent.next is the same as current
while(precurrent.next != null && precurrent.next.next != null) {
precurrent = precurrent.next;
} return precurrent;
} //1.3.20
/**
* delete the kth element in a linked list, if it exists.
*
* @param k the kth element, it should larger than 1
* @throws IllegalArgumentException if k < 1
* @throws NoSuchElementException if the size of the list is less than k
*/
public Item delete(int k) { if(k < 1)
throw new IllegalArgumentException("k must larger than 1"); Node<Item> precurrent = new Node<Item>();
precurrent.next = first;
Item item; while(precurrent.next != null && k > 1) {
precurrent = precurrent.next;
k--;
} if(precurrent.next == null)
throw new NoSuchElementException("LinkedList hasn't so many elements"); item = precurrent.next.item;
if(precurrent.next == first)
first = precurrent.next.next;
else
precurrent.next = precurrent.next.next; return item;
} //1.3.21
/**
* find if some node in the list has key as its item field
*
* @param list the linked list of T
* @param key the T key
*
* @return {@code true} some node exists.
* {@code false} no node exist
*/
public static <T> boolean find(LinkedList<T> list, T key) { for(T s : list) {
if(s.equals(key))
return true;
} return false;
} //1.3.24
/**
* remove the node following the node x
* (and does nothing if the argument or the next field in the argument node is null)
*
* @param x the given node
*/
public static <T> void removeAfter(Node<T> x) { if(x == null || x.next == null)
return; Node<T> current = x.next;
x.next = null; while(current != null) {
Node<T> temp = current.next;
current.next = null;
current = temp;
} } //1.3.25
/**
* insert the second node after the first on its list.
* and does nothing if either argument is null.
*
* @param first the first node
* @param second the second node to be inserted after the first
*/
public static <T> void insertAfter(Node<T> first, Node<T> second) { if(first == null || second == null)
return; second.next = first.next;
first.next = second; } //1.3.26
/**
* remove all of the nodes in the list that have key as its item field
*
* @param list the linked list of T
* @param key the T key
*
* @return void
*
*/
public static <T> void remove(LinkedList<T> list, T key) {
Node<T> precurrent;
precurrent = findPreNode(list, key); //remove all of the nodes
while(precurrent.next != null) { if(precurrent.next == list.first)
list.first = list.first.next;
else
precurrent.next = precurrent.next.next; precurrent = findPreNode(list, key);
} } //1.3.26
/**
* find the node in the list whose item equals key
*
* @param key the T key
*
* @return return the previous node whose item equals key
*/
private static <T> Node<T> findPreNode(LinkedList<T> list, T key) {
Node<T> precurrent = new Node<T>();
precurrent.next = list.first; while(precurrent.next != null && !precurrent.next.item.equals(key)) {
precurrent = precurrent.next;
} return precurrent;
} //1.3.27
/**
* return the value of the maximum key in the list
*
* @param list the linked list of Integer
*
* @return return the maximum key in the list
*/
public static int max(LinkedList<Integer> list) { if(list.first == null)
return 0; int max = 0;
for(int val : list) {
if(val > max)
max = val;
} return max;
} //1.3.28
/**
* return the value of the maximum key in the list by recursion
*
* @param list the linked list of Integer
*
* @return return the maximum key in the list
*/
public static int maxByRecursion(LinkedList<Integer> list) { if(list.first == null)
return 0; int first = list.first.item;//first item
list.first = list.first.next;//remove first item in the list
int max = maxByRecursion(list);//calculate the maximum value of the new list if(first > max)
return first;
else
return max;
} /**
*
* see if the list is empty
*
* @return true if the list is empty.
* false if the list isn't empty
*/
public boolean isEmpty() {
return first == null;
} @Override
public String toString() {
String s = ""; Node<Item> temp = first; while(temp != null) {
Item item = temp.item;
s += item + " ";
temp = temp.next;
} return s;
} @Override
public Iterator<Item> iterator() {
return new ListIterator();
} private class ListIterator implements Iterator<Item> { private Node<Item> current = first; @Override
public boolean hasNext() {
return current != null;
} @Override
public Item next() {
if(!hasNext())
throw new NoSuchElementException(); Item item = current.item;
current = current.next; return item;
} @Override
public void remove() {
throw new UnsupportedOperationException();
} } }

算法(Algorithms)第4版 练习 链表类 1.3.19~1.3.29的更多相关文章

  1. 1.2 Data Abstraction(算法 Algorithms 第4版)

    1.2.1 package com.qiusongde; import edu.princeton.cs.algs4.Point2D; import edu.princeton.cs.algs4.St ...

  2. 1.1 BASIC PROGRAMMING MODEL(算法 Algorithms 第4版)

    1.1.1 private static void exercise111() { StdOut.println("1.1.1:"); StdOut.println((0+15)/ ...

  3. LeetCode算法题-链表类

    1.将两个有序链表合并为一个新的有序链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. (可以参照第2的merge2List实现) 示例: 输入:1->2->4, 1->3 ...

  4. 数据结构与算法之PHP实现链表类(单链表/双链表/循环链表)

    链表是由一组节点组成的集合.每个节点都使用一个对象的引用指向它的后继.指向另一个节点的引用叫做链表. 链表分为单链表.双链表.循环链表.   一.单链表 插入:链表中插入一个节点的效率很高.向链表中插 ...

  5. ubuntu命令行下java工程编辑与算法(第四版)环境配置

    ubuntu命令行下java工程编辑与算法(第四版)环境配置 java 命令行 javac java 在学习算法(第四版)中的实例时,因需要安装配套的java编译环境,可是在编译java文件的时候总是 ...

  6. 在Eclipse下配置算法(第四版)运行环境

    第一步:配置Eclipse运行环境 Eclipse运行环境配置过程是很简单的,用过Eclipse进行java开发或学习的同学应该都很熟悉这个过程了. 配置过程: (1)系统环境:Windows7 64 ...

  7. 配置算法(第4版)的Java编译环境

    1. 下载 1.1 JDK http://www.oracle.com/technetwork/java/javase/downloads/index.html选择“Windows x64 180.5 ...

  8. 算法(第四版)C#题解——2.1

    算法(第四版)C#题解——2.1   写在前面 整个项目都托管在了 Github 上:https://github.com/ikesnowy/Algorithms-4th-Edition-in-Csh ...

  9. 常见排序算法题(java版)

    常见排序算法题(java版) //插入排序:   package org.rut.util.algorithm.support;   import org.rut.util.algorithm.Sor ...

随机推荐

  1. 「工具」Dubbo可视化测试工具的设计和实现

    「工具」Dubbo可视化测试工具的设计和实现 学习了:https://blog.csdn.net/qq355667166/article/details/78914453

  2. netty实现长连接心跳检

    主要逻辑: 使用netty实现长连接,主要靠心跳来维持服务器端及客户端连接. 实现的逻辑主要是: 服务器端方面: 1, 服务器在网络空闲操作一定时间后,服务端失败心跳计数器加1. 2, 如果收到客户端 ...

  3. TextView划线 android

    TextView  加下划线 . 中划线 下过如图: // 中划线 textView.getPaint().setFlags(Paint.STRIKE_THRU_TEXT_FLAG | Paint.A ...

  4. Android 百度地图开发(二)

    这一篇文章主要解说的是百度地图的定位功能,然后还有MyLocationOverlay和PopupOverlay两个地图覆盖物的使用.Overlay是"图层"或"覆盖物&q ...

  5. TCP/IP详解 卷一(第七、八章 Ping、Traceroute程序)

    Ping程序 Ping程序由Mike Muuss编写,目的是为了测试另一台主机是否可达. 该程序发送一份ICMP回显请求报文给主机,并等待返回ICMP回显应答. ping程序还能测出到这台主机的往返时 ...

  6. HTML5移动开发实战必备知识——本地存储(2)

    了解了一些主要的本地存储使用方法和思想后.我们来系统的介绍一下本地存储. 本地存储分为三大类:localStorage/sessionStorage/本地数据库 localStorage和sessio ...

  7. 设计模式之Protocol实现代理模式

    使用场合 使用步骤 不使用protocol实现代理 使用protocol实现代理 一.使用场合 A想让B帮忙,就让B代理 A想通知B发生了一些事情,或者传一些数据给B 观察者模式 二.使用步骤 定义一 ...

  8. VueJS锚定

    锚定函数 指令定义函数提供了几个钩子函数(可选): bind: 只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作. inserted: 被绑定元素插入父节 ...

  9. Linux在中国正在走向没落

    在中国,Linux正在走向没落,一片萧条景象. 在这样的大背景下.居然有人愿意接手中科红旗,令人佩服! 在中国,没有一个关于国际Linux的官方刊物(或站点)反映国际Linux运动的真实声音.Linu ...

  10. CentOS 5.5安装SVN(Subversion)

    检查已安装版本 #检查是否安装了低版本的SVN[root@localhost /]# rpm -qa subversion #卸载旧版本SVN[root@localhost modules]# yum ...