算法Sedgewick第四版-第1章基础-016一list
import java.util.Iterator;
import java.util.NoSuchElementException; public class List<Item> implements Iterable<Item>
{
private int N;
private Node first;
private Node last; private class Node
{
private Item item;
private Node next;
} public List()
{
first = null;
last = null;
} public List(Item[] a)
{
for (Item t : a)
append(t);
} public List(Iterable<Item> coll)
{
for (Item t : coll)
append(t);
} public boolean isEmpty()
{
return first == null;
} public int size()
{
return N;
} public Item first()
{
if (isEmpty()) throw new RuntimeException("List is empty");
return first.item;
} public Item last()
{
if (isEmpty()) throw new RuntimeException("List is empty");
return last.item;
} public Item removeFirst()
{
if (isEmpty()) throw new RuntimeException("List is empty");
Item item = first.item;
first = first.next;
N--;
if (isEmpty()) last = null; // to avoid loitering
return item;
} public void prepend(Item item)
{
Node x = new Node();
x.item = item;
if (isEmpty()) { first = x; last = x; }
else { x.next = first; first = x; }
N++;
} public void append(Item item)
{
Node x = new Node();
x.item = item;
if (isEmpty()) { first = x; last = x; }
else { last.next = x; last = x; }
N++;
} public String toString()
{
StringBuilder s = new StringBuilder();
for (Item item : this)
s.append(item + " ");
return s.toString();
} public Iterator<Item> iterator()
{
return new ListIterator();
} private class ListIterator implements Iterator<Item>
{
private Node current = first; public boolean hasNext() { return current != null; }
public void remove() { throw new UnsupportedOperationException(); } public Item next()
{
if (!hasNext()) throw new NoSuchElementException();
Item item = current.item;
current = current.next;
return item;
}
} /*****************
* Exercise 1.3.19
*****************/
public Item removeLast()
{
if (isEmpty()) throw new RuntimeException("List is empty");
if (first == last) return removeFirst();
Item item = last.item; Node prev = null,
curr = first;
while (curr.next != null)
{
prev = curr;
curr = curr.next;
}
prev.next = null;
last = prev;
N--; return item;
} /*****************
* Exercise 1.3.20
*****************/
public Item delete(int k)
{
if (k < 1) return null; int i = 1;
Node prev = null,
curr = first; while (i < k && curr != null)
{
prev = curr;
curr = curr.next;
i++;
} if (curr != null)
{
if (prev == null)
first = curr.next;
else
prev.next = curr.next; if (curr.next == null)
last = prev; N--;
return curr.item;
}
else
return null;
} /*************************************
* Exercise 1.3.21
* (Renamed from find() to contains())
*************************************/
public boolean contains(Item item)
{
Node curr = first;
while (curr != null && !curr.item.equals(item))
curr = curr.next;
return curr != null;
} /*****************
* Exercise 1.3.26
*****************/
public void remove(Item item)
{
List<Integer> idx = new List<Integer>();
int i = 1; for (Item x : this)
{
if (x.equals(item))
idx.prepend(i);
i++;
} for (int k : idx)
delete(k);
} /***************************************
* Recursive solution to Exercise 1.3.26
***************************************/
public void removeRec(Item item)
{
first = remove_Node(first, item);
setLastAndN();
} private Node remove_Node(Node node, Item item)
{
if (node != null)
{
Node rest = remove_Node(node.next, item); if (node.item.equals(item))
return rest;
else
{
node.next = rest;
return node;
}
}
else
return null;
} private void setLastAndN()
{
last = first;
N = 0;
if (first != null)
{
N++;
while (last.next != null)
{
last = last.next;
N++;
}
}
} /*********************
* Operations on nodes
*********************/ public Node node(int k)
{
if (k < 1) return null; int i = 1;
Node curr = first; while (i < k && curr != null)
{
curr = curr.next;
i++;
} return curr;
} public Node createNode(Item item)
{
Node node = new Node();
node.item = item;
return node;
} /*****************
* Exercise 1.3.24
*****************/
public void removeAfter(Node node)
{
if (node != null && node.next != null)
{
if (node.next.next == null)
last = node;
node.next = node.next.next;
N--;
}
} /*****************
* Exercise 1.3.25
*****************/
public void insertAfter(Node a, Node b)
{
if (a != null && b != null)
{
if (last == a)
last = b;
b.next = a.next;
a.next = b;
N++;
}
} /*************************************************
* Exercise 1.3.27
* Type 'Item' must implement interface Comparable
*************************************************/
public Item max(Node node)
{
if (node == null) throw new RuntimeException("List is empty");
return max(node, null);
} public Item max(Node node, Item def)
{
if (node == null)
return def; Item max = node.item;
Node curr = node; while (curr.next != null)
{
curr = curr.next;
if (((Comparable)max).compareTo(curr.item) < 0)
max = curr.item;
} return max;
} /*************************************************
* Exercise 1.3.28
* (recursive variant of Exercise 1.3.27)
* Type 'Item' must implement interface Comparable
*************************************************/
public Item maxRec(Node node, Item def)
{
if (node == null)
return def;
else
return maxRec(node);
} public Item maxRec(Node node)
{
if (node == null) throw new RuntimeException("List is empty"); if (node.next == null)
return node.item;
else
{
Item maxTail = maxRec(node.next);
return ((Comparable)node.item).compareTo(maxTail) > 0 ? node.item : maxTail;
}
} /*****************
* Exercise 1.3.30
*****************/
public void reverse()
{
first = reverse(first);
setLastAndN();
} public Node reverse(Node node)
{
Node srcFirst = node,
destFirst = null;
while (srcFirst != null)
{
Node next = srcFirst.next;
srcFirst.next = destFirst;
destFirst = srcFirst;
srcFirst = next;
} return destFirst;
} /***************************************
* Recursive solution to Exercise 1.3.30
***************************************/
public void reverseRec()
{
first = reverseRec(first);
setLastAndN();
} private Node reverseRec(Node node)
{
return reverseRec(node, null);
} private Node reverseRec(Node srcFirst, Node destFirst)
{
if (srcFirst == null)
return destFirst;
else
{
Node next = srcFirst.next;
srcFirst.next = destFirst;
return reverseRec(next, srcFirst);
}
} /************
* Unit tests
************/ private static void testBaseMethods()
{
int[] a = { 2, 4, 6, 8, 10, 12 }; List<Integer> lst = new List<Integer>();
for (int i = 0; i < a.length; i++)
lst.append(a[i]);
showList(lst); lst = new List<Integer>();
for (int i = 0; i < a.length; i++)
lst.prepend(a[i]);
showList(lst); StdOut.println("removeFirst: " + lst.removeFirst());
showList(lst);
} private static void testRemoveLast()
{
List<Integer> lst = new List<Integer>(new Integer[] { 6, 8, 10, 12 });
showList(lst); while (!lst.isEmpty())
{
StdOut.println("removeLast: " + lst.removeLast());
showList(lst);
}
} private static void testDelete()
{
List<Integer> lst = new List<Integer>(new Integer[] { 2, 4, 6, 8, 10, 12 });
showList(lst); StdOut.printf("delete(%d): %s\n", 5, lst.delete(5));
showList(lst); StdOut.printf("delete(%d): %s\n", 1, lst.delete(1));
showList(lst); StdOut.printf("delete(%d): %s\n", 4, lst.delete(4));
showList(lst); StdOut.printf("delete(%d): %s\n", 8, lst.delete(8));
showList(lst); StdOut.printf("delete(%d): %s\n", 0, lst.delete(0));
showList(lst); while (!lst.isEmpty())
{
StdOut.printf("delete(%d): %s\n", 1, lst.delete(1));
showList(lst);
}
} private static void testContains()
{
Integer[] a = { 4, 6, 10, 12 };
List<Integer> lst = new List<Integer>(a);
showList(lst); StdOut.printf("contains(%d): %s\n", 0, lst.contains(0)); for (int i = 0; i < a.length; i++)
StdOut.printf("contains(%d): %s\n", a[i], lst.contains(a[i]));
} private static void testRemove()
{
for (int k = 0; k < 8; k++)
{
List<Integer> lst1 = randomList(20, 0, 5);
List<Integer> lst2 = new List<Integer>(lst1);
StdOut.println(lst1);
StdOut.println(); int n = StdRandom.uniform(0, 5); StdOut.printf("remove(%d):\n", n);
lst1.remove(n);
showList(lst1); StdOut.printf("removeRec(%d):\n", n);
lst2.removeRec(n);
showList(lst2);
StdOut.println();
}
} private static void testReverse()
{
int n = 10;
Integer[] a = new Integer[n];
for (int i = 0; i < n; i++)
a[i] = 2 * (i + 1); testReverse(new List<Integer>(a));
StdOut.println(); testReverse(randomList(20, 0, 10));
StdOut.println(); testReverse(new List<Integer>(new Integer[] { 37 }));
StdOut.println(); testReverse(new List<Integer>(new Integer[] { }));
StdOut.println();
} private static void testReverse(List<Integer> lst)
{
List<Integer> lst1 = lst;
List<Integer> lst2 = new List<Integer>(lst1);
StdOut.println(lst1); StdOut.println("reverse():");
lst1.reverse();
StdOut.println(lst1); StdOut.println("reverseRec():");
lst2.reverseRec();
StdOut.println(lst2);
} private static void testNode()
{
List<Integer> lst = new List<Integer>(new Integer[] { 2, 6, 12 });
showList(lst); for (int i = -1; i <= 4; i++)
StdOut.printf("node(%d): %s\n", i, lst.node(i) != null ? lst.node(i).item : null);
} private static void testRemoveAfter()
{
List<Integer> lst = new List<Integer>(new Integer[] { 2, 6, 8, 10, 12 });
showList(lst); int[] k = { 0, 2, 1, 5, 3, 2, 1 }; for (int i = 0; i < k.length; i++)
{
StdOut.printf("removeAfter(node(%d)):\n", k[i]);
lst.removeAfter(lst.node(k[i]));
showList(lst);
}
} private static void testInsertAfter()
{
List<Integer> lst = new List<Integer>(new Integer[] { 2, 6, 10, 12 });
showList(lst); StdOut.printf("insertAfter(node(%d), null):\n", 1);
lst.insertAfter(lst.node(1), null);
showList(lst); int ia = 1,
b = 3;
StdOut.printf("insertAfter(node(%d), createNode(%d)):\n", ia, b);
lst.insertAfter(lst.node(ia), lst.createNode(b));
showList(lst); ia = 5;
b = 25;
StdOut.printf("insertAfter(node(%d), createNode(%d)):\n", ia, b);
lst.insertAfter(lst.node(ia), lst.createNode(b));
showList(lst);
} private static void testMax()
{
for (int k = 0; k < 8; k++)
{
List<Integer> lst = randomList(10, 100, 1000);
StdOut.println(lst); StdOut.printf("max(): %d\n", lst.max(lst.node(1)));
StdOut.printf("maxRec(): %d\n\n", lst.maxRec(lst.node(1)));
}
} /*******************
* Unit test helpers
*******************/ public static void showList(List lst)
{
StdOut.println(lst);
if (!lst.isEmpty())
StdOut.printf("Size: %d, First: %s, Last: %s\n\n", lst.size(), lst.first(), lst.last());
else
StdOut.printf("Size: %d\n\n", lst.size());
} private static List<Integer> randomList(int n, int a, int b)
{
Integer[] r = new Integer[n];
for (int i = 0; i < n; i++)
r[i] = StdRandom.uniform(a, b);
return new List<Integer>(r);
} public static void main(String[] args)
{
testBaseMethods();
StdOut.println(); testRemoveLast();
StdOut.println(); testDelete();
StdOut.println(); testContains();
StdOut.println(); testNode();
StdOut.println(); testRemoveAfter();
StdOut.println(); testInsertAfter();
StdOut.println(); testRemove();
StdOut.println(); testMax();
StdOut.println(); testReverse();
StdOut.println();
}
}
算法Sedgewick第四版-第1章基础-016一list的更多相关文章
- 算法Sedgewick第四版-第1章基础-001递归
一. 方法可以调用自己(如果你对递归概念感到奇怪,请完成练习 1.1.16 到练习 1.1.22).例如,下面给出了 BinarySearch 的 rank() 方法的另一种实现.我们会经常使用递归, ...
- 算法Sedgewick第四版-第1章基础-2.1Elementary Sortss-001选择排序法(Selection sort)
一.介绍 1.算法的时间和空间间复杂度 2.特点 Running time is insensitive to input. The process of finding the smallest i ...
- 算法Sedgewick第四版-第1章基础-2.1Elementary Sortss-007归并排序(自下而上)
一. 1. 2. 3. 二.代码 package algorithms.mergesort22; import algorithms.util.StdIn; import algorithms.uti ...
- 算法Sedgewick第四版-第1章基础-2.1Elementary Sortss-006归并排序(Mergesort)
一. 1.特点 (1)merge-sort : to sort an array, divide it into two halves, sort the two halves (recursivel ...
- 算法Sedgewick第四版-第1章基础-2.1Elementary Sortss-005插入排序的改进版
package algorithms.elementary21; import algorithms.util.StdIn; import algorithms.util.StdOut; /***** ...
- 算法Sedgewick第四版-第1章基础-2.1Elementary Sortss-004希尔排序法(Shell Sort)
一.介绍 1.希尔排序的思路:希尔排序是插入排序的改进.当输入的数据,顺序是很乱时,插入排序会产生大量的交换元素的操作,比如array[n]的最小的元素在最后,则要经过n-1次交换才能排到第一位,因为 ...
- 算法Sedgewick第四版-第1章基础-2.1Elementary Sortss-002插入排序法(Insertion sort)
一.介绍 1.时间和空间复杂度 运行过程 2.特点: (1)对于已排序或接近排好的数据,速度很快 (2)对于部分排好序的输入,速度快 二.代码 package algorithms.elementar ...
- 算法Sedgewick第四版-第1章基础-1.3Bags, Queues, and Stacks-001可变在小的
1. package algorithms.stacks13; /******************************************************************* ...
- 算法Sedgewick第四版-第1章基础-1.4 Analysis of Algorithms-005计测试算法
1. package algorithms.analysis14; import algorithms.util.StdOut; import algorithms.util.StdRandom; / ...
随机推荐
- 简单使用location.hash的方法 ,怎么做,有什么用? 简单的js路由页面方法。
hash 属性是一个可读可写的字符串,该字符串是URL的锚部分(从#号开始的部分).语法location.hash刚开始我真不知道hash有什么用,直到我在项目中遇上一个最大的问题.而且很恶心的体验 ...
- 使用BackgroundWorker组件
BackgroundWorker 组件用来执行诸如数据库事务.文件下载等耗时的异步操作. 开始 在应用程序中添加一个BackgroundWorker实例,如果用的是VS,可以从工具上直接拖到应用程序: ...
- nyoj-1278-Prototypes analyze(二叉排序树模板)
题目链接 思路:建树之后,判断有多少种不同的树. 判断不同的树,简单的思路是遍历数组,判断数组后面是否存在一样的树 /* Name:NYOJ-1278-Prototypes analyze Copyr ...
- LeetCode Range Addition II
原题链接在这里:https://leetcode.com/problems/range-addition-ii/description/ 题目: Given an m * n matrix M ini ...
- 浅议Windows 2000/XP Pagefile组织管理
任何时候系统内存资源相对磁盘空间来说都是相形见拙的.因为虚拟内存机制,使我们可以有相对丰富的地址资源(通常32bit的虚拟地址,可以有4G的寻址 空间),而这些资源对物理内存来说一般情况是总是绰绰有余 ...
- Spring Boot基本配置
本文参考javaEE开发的颠覆者SpringBoot实战第一版 基本配置 入口类和@SpringBootApplication Spring Boot通常有一个名为*Application的入口类,且 ...
- (转)C#特性详解
本文转载自:http://www.cnblogs.com/rohelm/archive/2012/04/19/2456088.html 特性提供功能强大的方法,用以将元数据或声明信息与代码(程序集.类 ...
- 我的MyGeneration
话不多说,直接上代码 Interface Code: public class GeneratedGui : DotNetScriptGui { public GeneratedGui(ZeusCon ...
- sql语句中GROUP BY 和 HAVING的使用 count()
在介绍GROUP BY 和 HAVING 子句前,我们必需先讲讲sql语言中一种特殊的函数:聚合函数, 例如SUM, COUNT, MAX, AVG等.这些函数和其它函数的根本区别就是它们一般作用在多 ...
- Make 命令
Linux 下 make 命令是系统管理员和程序员用的最频繁的命令之一.管理员用它通过命令行来编译和安装很多开源的工具,程序员用它来管理他们大型复杂的项目编译问题.本文我们将用一些实例来讨论 make ...