首页 > 其他分享 >CS61B srping 2018 proj1A https://sp18.datastructur.es/

CS61B srping 2018 proj1A https://sp18.datastructur.es/

时间:2025-01-07 16:33:38浏览次数:1  
标签:srping sp18 proj1A int next item sentinel public size

proj1A 数据结构

skeleton地址
开始这个proj之前,至少应该对SLList, DLList,AList有所了解

介绍

在proj1A里要用 list和Array 来创建“Double Ended Queue” ,在接下来的proj1B里要对应编写测试。LinkedListDeque.java and ArrayDeque.java是这个proj里边要操作的文件, 推荐使用intelliJ。

找到课程提供的skeleton

找到proj1a的文件夹(反正找到就行,按照课程网页介绍可不一定能找到emmmm),里边应该有个LinkedListDequeTest.java文件,应该像这个样子:示范/或者说没找到哦在这里能找到
LinkedListDequeTest.java文件 中包含了一些测试示范,你可以仿照编写来测试你的程序。 这里貌似没有JUnit的使用痕迹。
课程提供的LinkedListDequeTest.java文件仅仅包含了课程认为必要的测试内容,请根据其内容至少编写两条测试。
否则会出现测试没有覆盖所有 API的情况。

The Deque API /Deque的API介绍

Deque非常像 课程视频里介绍的SLList and AList ,这有一个cpp(网站上)版本的介绍

emmm,如果你忘记了SLList和AList,可以去看看这里
Deque就是 Double-ended queues的缩写,可长可短,动态变化,可以在首/尾增加或减少元素,Deque普遍包含下列的API:

  • public void addFirst(T item): Adds an item of type T to the front of the deque.
  • public void addLast(T item): Adds an item of type T to the back of the deque.
  • public boolean isEmpty(): Returns true if deque is empty, false otherwise.
  • public int size(): Returns the number of items in the deque.
  • public void printDeque(): Prints the items in the deque from first to last, separated by a space.
  • public T removeFirst(): Removes and returns the item at the front of the deque. If no such item exists, returns null.
  • public T removeLast(): Removes and returns the item at the back of the deque. If no such item exists, returns null.
  • public T get(int index): Gets the item at the given index, where 0 is the front, 1 is the next item, and so forth. If no such item exists, returns null. Must not alter the deque!

要编写泛型而不是固定某个类型的Deque,如何编写可以看这里:cs61B lecture5
看这个视频也行:cs61B 第6?5节视频

对于泛型类vs sentinel的具体处理 ,可以看这个博文:CS61B資料結構及演算法筆記:(二)單向串列及雙向串列

开始任务

1. Linked List Deque /链表Deque

注意课程第4-5节(5-6?)已经包含了所有完成本项目的内容。
先在项目文件夹中创建LinkedListDeque.java文件,随后编写一个以链表作为存储载体的Deque,具体要求如下:

  • add and remove operations must not involve any looping or recursion. A single such operation must take “constant time”, i.e. execution time should not depend on the size of the deque.
  • get must use iteration, not recursion.
  • size must take constant time.
  • 使用内存数量和Deque实际存储数据的数量应该差不多,比如你加了10000个元素,又减了9999个,那使用内存数量应该是更趋向于1而不是10000,而且注意不允许“已经被删除的”对象在内存里常驻,做好对“已经被删除的”对象的引用管理。
  • 要完成前文已经提到的api,并还要完成下面两个:
  • public LinkedListDeque(): Creates an empty linked list deque.
  • public T getRecursive(int index): Same as get, but uses recursion.
  • 可以增加private(helper)方法或者private类

可以参考课程上关于doubly linked lists的内容,可以参考关于sentinel node的内容,推荐用circular sentinel,下面是参考的ppt:
two sentinel topology,Double sentinel
and circular sentinel topology.

You are not allowed to use Java’s built in LinkedList data structure (or any data structure from java.util.*) in your implementation.
不让用Java自带的链表什么的类似数据结构

下方是作为参考的程序,不一定对,emmmmm。

SLList
public class SLList<ItemType>  {


    private static class ItemNode<ItemType> {
        public ItemType item ;
        public ItemNode next;
        public ItemNode(ItemType f, ItemNode n){
            item=f;
            next=n;
        }
    }
    public int size;
    private ItemNode<ItemType> sentinel ;
    public SLList(){
        sentinel = new ItemNode<ItemType>(null,null);
    }
    public SLList(ItemType item){

        sentinel = new ItemNode<ItemType>(null,null);
        sentinel.next=new ItemNode(item,null);
        size+=1;
}
    public void addFirst(ItemType item){
        size+=1;
        sentinel.next=new ItemNode<>(item,sentinel.next);

}
    public void addLast(ItemType item){
        size+=1;


        ItemNode<ItemType> tmpPtr= sentinel.next;
        while(tmpPtr.next!=null){
            tmpPtr=tmpPtr.next;

        }
        tmpPtr.next=new ItemNode(item,null);
    }

    public static void main(String[] args) {

        SLList<Integer> list = new SLList(5);
        list.addFirst(4);
        list.addFirst(3);
        list.addFirst(2);
        list.addLast(6);
        list.addFirst(1);
        list.addLast(7);


    }
}




DLList
public class DLList<ItemType> {
// Doubly linked list 每个 node上需要有双向的“通道”
//   建议使用一个sentinel 规避 last可能指向sentinel 也可能指向正常节点的情况。

    private static class ItemNode<ItemType> {
        public ItemType item;
        public ItemNode next;
        public ItemNode prev;

        public ItemNode(ItemNode p, ItemType i, ItemNode n) {
            prev = p;
            item = i;
            next = n;
        }
    }
/**
 * 为了让sentinel 更加明显,且不会被轻易修改
 */

    private static class SentinelNode<ItemType> extends ItemNode {
        public final ItemType item;
        public ItemNode next;
        public ItemNode prev;

        public SentinelNode(ItemNode p, ItemType i, ItemNode n) {
            super(p,i,n);
            prev = p;
            item = i;
            next = n;

        }
    }

    public int size;
    private SentinelNode<String> sentinel;

    public DLList() {
//initialization sentinel
        sentinel = new SentinelNode<String>(null, "this is sentinel,don't change its value", null);
        sentinel.prev = sentinel;
        sentinel.next = sentinel;

    }

    public DLList(ItemType item) {
//initialization sentinel
        sentinel = new SentinelNode<String>(null, "this is sentinel,don't change its value", null);
        sentinel.prev = sentinel;
        sentinel.next = sentinel;
        ItemNode<ItemType> newNode = new ItemNode(null, item, null);
        sentinel.next = newNode;
        newNode.next=sentinel;
        sentinel.prev=newNode;
        newNode.prev=sentinel;

        size += 1;
    }

    public void addFirst(ItemType item) {

        ItemNode<ItemType> newNode = new ItemNode<>(null,item, null);
        if(size==0){
            sentinel.next=newNode;
            sentinel.prev=newNode;
            newNode.prev=sentinel;
            newNode.next=sentinel;
        }
        else {
            ItemNode oldFirstNode= sentinel.next;
            newNode.next=oldFirstNode;
            newNode.prev=sentinel;
            sentinel.next=newNode;
            oldFirstNode.prev=newNode;

        }
        size += 1;
    }

    public void addLast(ItemType item) {
        ItemNode<ItemType> newNode = new ItemNode<>(null,item, null);

       if(size==0){
           sentinel.next=newNode;
           sentinel.prev=newNode;
           newNode.prev=sentinel;
           newNode.next=sentinel;
       }
       else {
           ItemNode oldLastNode= sentinel.prev;
           newNode.next=sentinel;
           newNode.prev=oldLastNode;
           sentinel.prev=newNode;
           oldLastNode.next=newNode;

       }
        size += 1;

    }

    public static void main(String[] args) {
        DLList list = new DLList(5);
        list.addFirst(4);
        list.addFirst(3);
        list.addFirst(2);
        list.addLast(6);
        list.addFirst(1);
        list.addLast(7);


    }
}




LinkedListDeque
public class LinkedListDeque<ItemType> {

   private static class ItemNode<ItemType> {
        public ItemType item;
        public ItemNode next;
        public ItemNode prev;

        public ItemNode(ItemNode p, ItemType i, ItemNode n) {
            prev = p;
            item = i;
            next = n;
        }
    }
/**
 * 为了让sentinel 更加明显,且不会被轻易修改
 */

    private static class SentinelNode<ItemType> extends ItemNode {
        public final ItemType item;
        public ItemNode next;
        public ItemNode prev;

        public SentinelNode(ItemNode p, ItemType i, ItemNode n) {
            super(p,i,n);
            prev = p;
            item = i;
            next = n;

        }
    }
    private int size;
    public SentinelNode<String> sentinel;
    public LinkedListDeque(){
        // in this situation ,size is 0,because ,it's empty.
        sentinel = new SentinelNode<String>(null,"this is a sentinel ,don't mess with it",null);
        sentinel.prev=sentinel;
        sentinel.next=sentinel;
    }

    public LinkedListDeque(ItemType item){
        // in this situation ,size is 1 ,because during the initialization ,an item is added into the list.
        sentinel = new SentinelNode<String>(null,"this is a sentinel ,don't mess with it",null);
        ItemNode<ItemType> newNode= new ItemNode<>(null,item,null);
        sentinel.prev=newNode;
        sentinel.next=newNode;
        size+=1;
    }


    public void addFirst(ItemType item){
//        初始化一个Node,随后插入到要插入的位置
        ItemNode<ItemType> newNode= new ItemNode<>(null,item,null);
//        如果是空列表
    if(size==0){

        sentinel.next=newNode;
        sentinel.prev=newNode;
        newNode.prev=sentinel;
        newNode.next=sentinel;
    }
//    如果不是空列表
    else{
        ItemNode<ItemType> oldFirstNode = sentinel.next;
        sentinel.next=newNode;
        newNode.prev=sentinel;
        newNode.next=oldFirstNode;
        oldFirstNode.prev=newNode;
    }
        size+=1;
    }


    public void addLast(ItemType item){
        //        初始化一个Node,随后插入到要插入的位置
        ItemNode<ItemType> newNode= new ItemNode<>(null,item,null);
//        如果是空列表
        if(size==0){
            sentinel.next=newNode;
            sentinel.prev=newNode;
            newNode.prev=sentinel;
            newNode.next=sentinel;
        }
//        如果不是空列表
        else{
            ItemNode<ItemType> oldLastNode = sentinel.prev;
            sentinel.prev=newNode;
            newNode.next=sentinel;
            newNode.prev=oldLastNode;
            oldLastNode.next=newNode;
        }
        size+=1;
    }
    public boolean isEmpty(){
        return size==0;
    }
    public int size(){
        return size;
    }

    public String printDeque(){
        String resultStr="";
        if(size==0){
            System.out.println("");
            return  resultStr;
        }
        else{
            ItemNode tmpPtr= sentinel.next;
            while(tmpPtr.next!=null){
                System.out.print(tmpPtr.item+" ");
                resultStr+=tmpPtr.item+" ";
                tmpPtr=tmpPtr.next;
                if(tmpPtr.next==null){
                    System.out.println();
                }
            }
        }
        return resultStr;
    }
//    不准有 loitering ,no 废弃对象不被处理
public ItemType removeFirst(){
        if(size==0){
            return null;
        }

    ItemNode<ItemType> oldFirstNode = sentinel.next;
    sentinel.next=oldFirstNode.next;
    oldFirstNode.next.prev=sentinel;
    oldFirstNode.prev=null;
    oldFirstNode.next=null;
    size-=1;
    return oldFirstNode.item;
}

    public ItemType removeLast(){
        if(size==0){
            return null;
        }
        ItemNode<ItemType> oldLastNode = sentinel.prev;
        sentinel.prev=oldLastNode.prev;
        oldLastNode.prev.next=sentinel;
        oldLastNode.prev=null;
        oldLastNode.next=null;
        size-=1;
        return oldLastNode.item;
    }

    public ItemType get(int index){
        if(index>size-1||index<0){
            return null;
        }
        ItemNode<ItemType> tmpPtr =sentinel.next;
        while(index!=0){
            index-=1;
            tmpPtr=tmpPtr.next;
        }
        return tmpPtr.item;
    }
    public ItemType getRecursive(int index){
        if(index>size-1||index<0){
            return null;
        }
        ItemNode<ItemType> tmpPtr =sentinel.next;
        if(index==0){
            return tmpPtr.item;
        }
        else {
            return gRHelper(tmpPtr.next,index-1);
        }
    }
    private ItemType gRHelper(ItemNode ptr,int idx){
        ItemNode<ItemType> tmpPtr =ptr;
        if(idx==0){
            return tmpPtr.item;
        }
        return gRHelper(ptr.next,idx-1);
    }
    public static void main(String[] args) {

    }
}


LinkedListDequeTest
/** Performs some basic linked list tests. */
public class LinkedListDequeTest {

	/* Utility method for printing out empty checks. */
	public static boolean checkEmpty(boolean expected, boolean actual) {
		if (expected != actual) {
			System.out.println("isEmpty() returned " + actual + ", but expected: " + expected);
			return false;
		}
		return true;
	}

	/* Utility method for printing out empty checks. */
	public static boolean checkSize(int expected, int actual) {
		if (expected != actual) {
			System.out.println("size() returned " + actual + ", but expected: " + expected);
			return false;
		}
		return true;
	}

	/* Prints a nice message based on whether a test passed.
	 * The \n means newline. */
	public static void printTestStatus(boolean passed) {
		if (passed) {
			System.out.println("Test passed!\n");
		} else {
			System.out.println("Test failed!\n");
		}
	}

	/** Adds a few things to the list, checking isEmpty() and size() are correct,
	  * finally printing the results.
	  *
	  * && is the "and" operation. */
	public static void addIsEmptySizeTest() {
		System.out.println("Running add/isEmpty/Size test.");
//		System.out.println("Make sure to uncomment the lines below (and delete this print statement).");

		LinkedListDeque<String> lld1 = new LinkedListDeque<String>();

		boolean passed = checkEmpty(true, lld1.isEmpty());

		lld1.addFirst("front");

		// The && operator is the same as "and" in Python.
		// It's a binary operator that returns true if both arguments true, and false otherwise.
		passed = checkSize(1, lld1.size()) && passed;
		passed = checkEmpty(false, lld1.isEmpty()) && passed;

		lld1.addLast("middle");
		passed = checkSize(2, lld1.size()) && passed;

		lld1.addLast("back");
		passed = checkSize(3, lld1.size()) && passed;

		System.out.println("Printing out deque: ");
		lld1.printDeque();

		printTestStatus(passed);

	}


	/** Adds an item, then removes an item, and ensures that dll is empty afterwards. */
	public static void addRemoveTest() {

		System.out.println("Running add/remove test.");

//		System.out.println("Make sure to uncomment the lines below (and delete this print statement).");

		LinkedListDeque<Integer> lld1 = new LinkedListDeque<Integer>();
		// should be empty
		boolean passed = checkEmpty(true, lld1.isEmpty());

		lld1.addFirst(10);
		// should not be empty
		passed = checkEmpty(false, lld1.isEmpty()) && passed;

		lld1.removeFirst();
		// should be empty
		passed = checkEmpty(true, lld1.isEmpty()) && passed;


		printTestStatus(passed);

	}
    /*
    * check add and remove function
    *
    * */
    public static void addRemoveTest2(){

        LinkedListDeque<Integer> lld1 = new LinkedListDeque<Integer>();
        // should be empty
        boolean passed = checkEmpty(true, lld1.isEmpty());

        lld1.addFirst(5);
        lld1.addFirst(4);
        lld1.addLast(3);
        lld1.addFirst(6);
        lld1.addLast(2);
        lld1.addFirst(7);
        lld1.addLast(1);
        // 7 6 5 4 3 2 1
        passed=checkEmpty(false, lld1.isEmpty())&&passed;
        printTestStatus(passed);
        lld1.removeFirst();
        lld1.removeLast();
        lld1.removeLast();
        lld1.removeFirst();
        String expectedRemainList = "453";

        System.out.println("result should be "+expectedRemainList);

        System.out.print("and actual is");
        String actualResult =lld1.printDeque().replaceAll("\\s+", "");
        passed= expectedRemainList.equals(actualResult);
        System.out.println();

        printTestStatus(passed);
    }
    public static void getTest(){
        LinkedListDeque<Integer> lld1 = new LinkedListDeque<Integer>();
        System.out.println("Running get test.");

        lld1.addFirst(4);
        lld1.addFirst(5);
        lld1.addLast(3);
        lld1.addFirst(6);
        lld1.addLast(2);
        lld1.addLast(0);
        lld1.removeLast();
        lld1.addFirst(7);
        lld1.addLast(1);
        System.out.println("Printing out deque: ");

        System.out.println("should be: \n7 6 5 4 3 2 1\nand actual is:");
        lld1.printDeque();
        // should be 1
        System.out.println("the last item is this method get is "+lld1.get(6));
        boolean passed = lld1.get(6)==1;
        printTestStatus(passed);
    }
    public static void getReTest(){
        LinkedListDeque<Integer> lld1 = new LinkedListDeque<Integer>();
        System.out.println("Running getRecursive test.");

        lld1.addFirst(4);
        lld1.addFirst(5);
        lld1.addLast(3);
        lld1.addFirst(6);
        lld1.addLast(2);
        lld1.addLast(0);
        lld1.removeLast();
        lld1.addFirst(7);
        lld1.addLast(1);
        System.out.println("Printing out deque: ");

        System.out.println("should be: \n7 6 5 4 3 2 1\nand actual is:");
        lld1.printDeque();
        // should be 1
        System.out.println("the last item this method get is "+lld1.getRecursive(6));
        boolean passed = lld1.getRecursive(6)==1;
        printTestStatus(passed);
    }

	public static void main(String[] args) {
		System.out.println("Running tests.\n");
//		addIsEmptySizeTest();
//		addRemoveTest();
//        addRemoveTest2();
//        getTest();
        getReTest();
	}
}

2. Array Deque 数组作为存储载体的 Deque

在project directory 创建ArrayDeque.java, ArrayDeque 类要使用数组作为核心存储数据结构(就是用array存元素,没办法,我的翻译水平无力,但是懂得自然懂,懂linkedList的人都知道这里面门道有多深!)

  • add and remove must take constant time, except during resizing operations.add remove也要消耗恒定时间,除了 resize操作的时候
  • get and size must take constant time. get 和size方法应该消耗恒定时间(那肯定就是特别短的意思)
  • The starting size of your array should be 8. 初始数组长度是8
  • 内存使用应该和元素数量相匹配,(load factor啊,就是实际元素个数/数组总长度)占用率不应低于25%,

包含下列API(就是上面)有过的

  • public void addFirst(T item): Adds an item of type T to the front of the deque.
  • public void addLast(T item): Adds an item of type T to the back of the deque.
  • public boolean isEmpty(): Returns true if deque is empty, false otherwise.
  • public int size(): Returns the number of items in the deque.
  • public void printDeque(): Prints the items in the deque from first to last, separated by a space.
  • public T removeFirst(): Removes and returns the item at the front of the deque. If no such item exists, returns null.
  • public T removeLast(): Removes and returns the item at the back of the deque. If no such item exists, returns null.
  • public T get(int index): Gets the item at the given index, where 0 is the front, 1 is the next item, and so forth. If no such item exists, returns null. Must not alter the deque!
  • public ArrayDeque():Creates an empty array deque.

课程墙裂建议使用circular 的解决方案,据说会避免很多special coner cases,resize操作可能很麻烦,要自己好好思考。
在开始ArrayDeque之前,类似的,可以参考AList, 在lectureCode中可以找到AList,如下:

AList 课程原版
/** Array based list.
 *  @author Josh Hug
 */

public class AList {
    /** Creates an empty list. */
    public AList() {
    }

    /** Inserts X into the back of the list. */
    public void addLast(int x) {
    }

    /** Returns the item from the back of the list. */
    public int getLast() {
        return 0;        
    }
    /** Gets the ith item in the list (0 is the front). */
    public int get(int i) {
        return 0;        
    }

    /** Returns the number of items in the list. */
    public int size() {
        return 0;        
    }

    /** Deletes item from back of the list and
      * returns deleted item. */
    public int removeLast() {
        return 0;
    }
} 
AList 课程原版实现

implementation:

/** Array based list.
 *  @author Josh Hug
 */

//         0 1  2 3 4 5 6 7
// items: [6 9 -1 2 0 0 0 0 ...]
// size: 5

/* Invariants:
 addLast: The next item we want to add, will go into position size
 getLast: The item we want to return is in position size - 1
 size: The number of items in the list should be size.
*/

public class AList<Item> {
    private Item[] items;
    private int size;

    /** Creates an empty list. */
    public AList() {
        items = (Item[]) new Object[100];
        size = 0;
    }

    /** Resizes the underlying array to the target capacity. */
    private void resize(int capacity) {
        Item[] a = (Item[]) new Object[capacity];
        System.arraycopy(items, 0, a, 0, size);
        items = a;
    }

    /** Inserts X into the back of the list. */
    public void addLast(Item x) {
        if (size == items.length) {
            resize(size + 1);
        }

        items[size] = x;
        size = size + 1;
    }

    /** Returns the item from the back of the list. */
    public Item getLast() {
        return items[size - 1];
    }
    /** Gets the ith item in the list (0 is the front). */
    public Item get(int i) {
        return items[i];
    }

    /** Returns the number of items in the list. */
    public int size() {
        return size;
    }

    /** Deletes item from back of the list and
      * returns deleted item. */
    public Item removeLast() {
        Item x = getLast();
        items[size - 1] = null;
        size = size - 1;
        return x;
    }
} 

AList课程原版 test:
import org.junit.Test;
import static org.junit.Assert.*;

/** Tests the AList class.
 *  @author Josh Hug
 */

public class AListTest {
    @Test
    public void testEmptySize() {
        AList L = new AList();
        assertEquals(0, L.size());
    }

    @Test
    public void testAddAndSize() {
        AList L = new AList();
        L.addLast(99);
        L.addLast(99);
        assertEquals(2, L.size());
    }

    
    @Test
    public void testAddAndGetLast() {
        AList L = new AList();
        L.addLast(99);
        assertEquals(99, L.getLast());        
        L.addLast(36);
        assertEquals(36, L.getLast());        
    }

    
    @Test
    public void testGet() {
        AList L = new AList();
        L.addLast(99);
        assertEquals(99, L.get(0));        
        L.addLast(36);
        assertEquals(99, L.get(0));        
        assertEquals(36, L.get(1));        
    }


    @Test
    public void testRemove() {
        AList L = new AList();
        L.addLast(99);
        assertEquals(99, L.get(0));        
        L.addLast(36);
        assertEquals(99, L.get(0));
        L.removeLast(); 
        assertEquals(99, L.getLast());
        L.addLast(100);
        assertEquals(100, L.getLast());
        assertEquals(2, L.size());
    }

    /** Tests insertion of a large number of items.*/
    @Test
    public void testMegaInsert() {
        AList L = new AList();
        int N = 1000000;
        for (int i = 0; i < N; i += 1) {
            L.addLast(i);
        }

        for (int i = 0; i < N; i += 1) {
            L.addLast(L.get(i));
        }
    }

    public static void main(String[] args) {
        jh61b.junit.TestRunner.runTests("all", AListTest.class);
    }
} 
AList speedTest

可以用 time命令来测试程序运行时间。
(是 javac *.class ,然后在 java SpeedTest ,或者使用idea,直接在out/production 类似的文件夹里java SpeedTest

    public static void main(String[] args) {
        AList L = new AList();
        int N = 1000000000;
        for (int i = 0; i < N; i += 1) {
            L.addLast(i);
        }

        for (int i = 0; i < N; i += 1) {
            L.addLast(L.get(i));
        }
    }
}

下面是 自己写的,可以比对上面看看区别。

AList非课程原版实现,无法保甜
/** Array based list.
 *  @author Josh Hug
 */

public class AList {
   private  int[] items;
   private int size ;
//index   0 1 2 3 4 5 6
// items [0 0 0 0 0 0 0]
// size   1 2 3 4 5 6 7
    /** Creates an empty list. */
    public AList() {
        size=0;
        items = new int[8];

    }

    private   int[] createNewArray(int currentLength){
        int[] newArray = new int[currentLength*2];
        System.arraycopy(items,0,newArray,0,size);
        return newArray;
    }
    /** Inserts X into the back of the list. */
    public void addLast(int x) {
        int length = items.length;
        if(size==length){

            int[] newArray= createNewArray(size);
            newArray[size]=x;
            items=newArray;
            size+=1;
            return;
        }


        items[size]=x;
        size+=1;
    }

    /** Returns the item from the back of the list. */
    public int getLast() {
        return items[size-1];
    }
    /** Gets the ith item in the list (0 is the front). */
    public int get(int i) {
        return items[i];
    }

    /** Returns the number of items in the list. */
    public int size() {
        return size;
    }

    /** Deletes item from back of the list and
      * returns deleted item. */
    public int removeLast() {
        int length = items.length;
        if(size/length<=0.25){
            int newArrLength = length/2;
            if(newArrLength<16){
                newArrLength= 16;
            }

            int[] newArray = new int[newArrLength];
            System.arraycopy(items,0,newArray,0,length);
            int oldLastItem =newArray[size-1];
            newArray[size-1]=0;
            size-=1;
            items=newArray;
            return oldLastItem;
        }

        int x = getLast();
        items[size-1]=0;
        size-=1;
        return x;
    }
} 
AList测试,不保甜版本

AListTest

import org.junit.Test;
import static org.junit.Assert.*;

/** Tests the AList class.
 *  @author Josh Hug
 */

public class AListTest {
    @Test
    public void testEmptySize() {
        AList L = new AList();
        assertEquals(0, L.size());
    }

    @Test
    public void testAddAndSize() {
        AList L = new AList();
        L.addLast(99);
        L.addLast(99);
        assertEquals(2, L.size());
    }

    
    @Test
    public void testAddAndGetLast() {
        AList L = new AList();
        L.addLast(99);
        assertEquals(99, L.getLast());        
        L.addLast(36);
        assertEquals(36, L.getLast());        
    }

    
    @Test
    public void testGet() {
        AList L = new AList();
        L.addLast(99);
        assertEquals(99, L.get(0));        
        L.addLast(36);
        assertEquals(99, L.get(0));        
        assertEquals(36, L.get(1));        
    }


    @Test
    public void testRemove() {
        AList L = new AList();
        L.addLast(99);
        assertEquals(99, L.get(0));        
        L.addLast(36);
        assertEquals(99, L.get(0));
        L.removeLast(); 
        assertEquals(99, L.getLast());
        L.addLast(100);
        assertEquals(100, L.getLast());
        assertEquals(2, L.size());
    }

    /** Tests insertion of a large number of items.*/
    @Test
    public void testMegaInsert() {
        AList L = new AList();
        int N = 1000000;
        for (int i = 0; i < N; i += 1) {
            L.addLast(i);
        }

        for (int i = 0; i < N; i += 1) {
            L.addLast(L.get(i));
        }
    }

    public static void main(String[] args) {
        jh61b.junit.TestRunner.runTests("all", AListTest.class);
    }
} 
ArrayDeque 不保甜 版本
public class ArrayDeque<ItemType> {
   private int size;
   private  ItemType[] items;
// array   [0 0 0 0 0 0 0 0]
// index   [0 1 2 3 4 5 6 7]
// size    [1 2 3 4 5 6 7 8]
// length  [1 2 3 4 5 6 7 8]

    public ArrayDeque(){
        items=(ItemType[] ) new Object[8];
        size-=0;

    }
    private void resize(int oldLength){
        ItemType[] newArray =(ItemType[] ) new Object[oldLength*2];
        System.arraycopy(items,0,newArray,0,oldLength);
        items=newArray;
    }
//    在有限条件下(可以确定总元素个数不大于数组总长度。(
//    也就是向后移动元素后,元素顺序不变,元素没有移动位置,元素个数没有少,
//    这个操作的关键思路是,从最后一个(如果设置为空)索引,从后往前替换。
    private  void MoveArrayItemBackward() {

        for (int i = items.length - 1; i >0; i--) {
            items[i] = items[i - 1]; // 向后移动元素
//            注意 原始的第 items[0] 没变化
        }

    }
//    类似操作,把元素向前移动。
//    这里也要保证 第一个元素为空,数组总长足够。
    private  void moveArrayItemsForward() {

        for (int i = 0; i <items.length-1; i++) {

            items[i] = items[i + 1]; // 向前移动元素

        }
        items[items.length-1]=null;


    }
//    addFirst 就是把所有元素后移,在空出来的第一个位置加一个
    public void addFirst(ItemType item){
        if(size== items.length){
            resize(items.length);
        }
        if(size==0){
            items[0]=item;
            size+=1;
            return;
        }
        else{
//            这里可以确定 增加一个元素后的元素总个数也没有超过数组总长,因为最开始做了  size和items.length的检查
            MoveArrayItemBackward();
            items[0]=item;
            size+=1;
            return;
        }

    }

    public int size(){
        return size;
    }
    public void addLast(ItemType item){
        if(size== items.length){
            resize(items.length);
        }
        items[size]=item;
        size+=1;
    }
    public boolean isEmpty(){
        return size==0;
    }
    public void printDeque(){
        for(int i =0;i<size;i++){
            System.out.print(items[i]+" ");
        }
    }
    public ItemType removeFirst(){
        int currentLength = items.length;
        double compareResult = (double)size/currentLength;
        if(compareResult<0.25){
            resize((int)Math.floor(items.length/4));
        }

        ItemType FirstItem = items[0];
        items[0]=null;
        moveArrayItemsForward();
        size-=1;
        return FirstItem;
    }

    public ItemType removeLast(){
        int currentLength = items.length;
        double compareResult = (double)size/currentLength;
        if(compareResult<0.25){
            resize((int)Math.floor(items.length/4));
        }
        ItemType lastItem = items[size-1];
        items[size-1]=null;
        size-=1;
        return lastItem;
    }
    public ItemType get(int index){
        if(index<0||index>size-1){
            return null;
        }
        return items[index];
    }
    public static void main(String[] args) {

    }
}
ArrayDequeTest 不保甜 版本
import org.junit.Test;

import static org.junit.Assert.*;

public class ArrayDequeTest {
    @Test
    public void testEmptySize() {
        ArrayDeque L = new ArrayDeque<Integer>();
        assertEquals(0, L.size());

    }

    @Test
    public void testAddFirst() {
        ArrayDeque L = new ArrayDeque<Integer>();
        for (int i = 10; i > 0; i--) {
            L.addFirst(i);
        }
        L.addFirst(0);
        assertEquals(11, L.size());
    }

    @Test
    public void testIsEmpty() {
        ArrayDeque L = new ArrayDeque<Integer>();
        assertTrue(L.isEmpty());
        L.addFirst(1);
        assertFalse(L.isEmpty());
    }

    @Test
    public void testPrintDeque() {
        ArrayDeque L = new ArrayDeque<Integer>();
        System.out.println("testing PrintDeque,\nexpected should be:\n1 2 3 4 5 6 7 8 9 10");
        for (int i = 10; i > 0; i--) {
            L.addFirst(i);

        }
        System.out.println("actual is :");
        L.printDeque();
    }

    @Test
    public void testRemoveFirst() {
        ArrayDeque L = new ArrayDeque<Integer>();

        for (int i = 10; i > 0; i--) {
            L.addFirst(i);

        }
        System.out.println("testing RemoveFirst,\nexpected should be:\n1 2 3 4 " +
                "5 6 7 8 9 10,the first item will disappear in turn");
        for (int i = 0; i < 10; i++) {

            L.removeFirst();
            L.printDeque();
            System.out.println();
        }

    }
    @Test
    public void testRemoveLast() {
        ArrayDeque L = new ArrayDeque<Integer>();

        for (int i = 10; i > 0; i--) {
            L.addFirst(i);

        }
        System.out.println("testing RemoveFirst,\noriginal list is:\n1 2 3 4 " +
                "5 6 7 8 9 10,the last item will disappear in turn");
        for (int i = 0; i < 10; i++) {

            L.removeLast();
            L.printDeque();
            System.out.println();
        }

    }
    @Test
    public void testGet() {
        ArrayDeque L = new ArrayDeque<Integer>();
        L.addFirst(4);
        L.addFirst(5);
        L.addFirst(6);
        L.addLast(5);
        L.addLast(6);
        L.addLast(8);
        L.removeLast();
        L.removeFirst();
        L.removeFirst();
        L.addFirst(3);
        L.addFirst(2);
        L.addFirst(1);
        L.addLast(9);
        L.removeFirst();

        System.out.println("test Get ,should be:\n 2 3 4 5 6 9\nactual is:\n");
        L.printDeque();
        assertEquals(L.get(5), 9);
        System.out.println("get the last item ,should be 9\nactual is:" + L.get(5));


    }

    public static void main(String[] args) {
        jh61b.junit.TestRunner.runTests("all", ArrayDequeTest.class);
    }

}
SpeedTestLinkedList LinkedList的速度测试,貌似超过10w就很慢了。
public class SpeedTestLinkedList
{

        public static void main(String[] args) {
            LinkedListDeque<Integer> L = new LinkedListDeque<Integer>();
            int N = Integer.parseInt(args[0]);
            for (int i = 0; i < N; i += 1) {
                L.addLast(i);

            }

            for (int i = 0; i < N; i += 1) {
                L.addLast(L.get(i));
            }
    }
}

不保证准确。。。。

标签:srping,sp18,proj1A,int,next,item,sentinel,public,size
From: https://www.cnblogs.com/nulixuexipython/p/18646503

相关文章

  • CS61B srping 2018 lab03 https://sp18.datastructur.es/
    UnitTestingwithJUnit,Debugging准备装好CS61B插件(emmmmm,不装也没事)把lab2的IntList.java复制到lab3/IntList文件夹.看看关于测试的课程视频介绍啊?JUnit是java测试框架,现在要用JUnit进行单元测试,单元Unit就是把程序分成小块的单元,一个单元的功能尽量少,单独测试,......
  • CS61B srping 2018 examprep03 https://sp18.datastructur.es/
    flatten方法接受二维数组,返回一个一维数组比如,flatten({{1,2,3},{},{7,8}})shouldreturn{1,2,3,7,8}补全下面的程序片段publicstaticint[]flatten(int[][]x){inttotalLength=0;for(____________________________________){_______________________......
  • CS61B srping 2018 disc03 https://sp18.datastructur.es/
    为下面方法添加SLList.insert方法,要求签名如publicvoidinsert(intitem,intposition){},如果position大于最后一个元素,那就是添加到最后。(注意这个作业里的SLList和课程中介绍的SLList相比少点东西,故意的,可能是为了让学生开拓思路?)publicclassSLList{privateclassIn......
  • CS61B srping 2018 project00 https://sp18.datastructur.es/
    GettingtheSkeletonFiles,网站上应该有仓库地址,这个也行,https://gitee.com/heqilaoge/skeleton-sp18。拉下来找到proj0,就能开始作业。可以不使用IDE。2.ThePlanetClassandItsConstructor创建Planet类publicclassPlanet{publicdoublexxPos;publicdo......
  • CS61B srping 2018 examprep01(?02) https://sp18.datastructur.es/
    1.写出第21、24行的运行结果。(画出box-pointer指示图会对答题很有帮助)1publicclassShock{2publicstaticintbang;3publicstaticShockbaby;4publicShock(){5this.bang=100;6}7publicShock(intnum){8this.bang=num;9baby=starter();10this......
  • CS61B srping 2018 disc02 sol https://sp18.datastructur.es/
    第19行的变量level是静态方法change方法内部的本地变量,他对main方法里的level或者是实例变量level没什么影响。publicclassPokemon{//一个名为Pokemon的类publicStringname;//实例变量namepublicintlevel;//实例变量levelpublicPokemon(String......
  • CS61B srping 2018 disc02 https://sp18.datastructur.es/
    passbywhat?a.下列程序每一行怎么运行?b.画出box-and-pointer指示图c.在第19行,level被赋值为50,level是什么?是Pokemon的实例变量?(instancevariable)还是change方法的本地变量?(localvariable?)还是main方法里的变量?还是其他什么东西?1publicclassPokemon{2public......
  • CS61B srping 2018 disc01 answer
    1intsize=27;//声明一个int类型的变量size,并把27赋值给他2Stringname="Fido";//声明一个String类型的变量,并把“Fido”赋值给他3DogmyDog=newDog(name,size);//声明一个Dog类型的变量myDog,并调用Dog构造函数,分别把name和size传入其中,生成一个Dog类型的对......
  • CS61B srping 2018 disc01
    //1.写出每一行(你认为)的运行结果intsize=27;Stringname="Fido";DogmyDog=newDog(name,size);intx=size-5;if(x<15){myDog.bark(8);}while(x>3){x-=1;myDog.play();}int[]numList={2,4,6,8};System.out.print("Hell......
  • SP1843 LEONARDO - Leonardo Notebook 题解
    题目传送锚点博客园食用更佳前置知识1前置知识2首先是判断有无解。先疯狂寻找完所有的环,然后判断是否是偶环,最后如果都是偶环,且偶环的路径数成双成对地出现,或全是奇环,就输出Yes,不然就直接pass掉,输出No。然后我们发现:这里竟然出现了置换群!!!为什么它是置换群呢?我们从群的定......