• 2018-2019-20172309 《程序设计与数据结构(下)》第三周学习总结


    教材学习内容总结

    教材学习内容总结

    5.1 队列概述

    • 队列的元素是按照FIFO方式处理的:第一个进入的元素,也就是第一个退出的元素。
    • 队列的处理方式与栈相反,栈的处理方式是LIFO。
    • 队列中的方法有enqueue,dequeue,first等同于栈中的push,pop,peek

    5.2 java API中的队列

    • java集合API提供了java.util.Stack类,他实现了栈集合。但他并没有提供队列类,而是提供了一个Queue接口。
    • java.util.Stack类提供了push,pop和peek等操作,queue接口提供了两个方法add和offer。
    • queue中的方法:

    5.3 使用队列:代码秘钥和售票口模拟。

    • 队列是一种可储存重复编码秘钥的遍历集合。
    • 通常用表示排队的队列来实现模拟。

    5.4 队列ADT

    • 就像栈一样,我们也定义一个泛型QueueADT接口,表示队列的操作,把操作的一般目标与各种实现方式分开。

    5.5 实现队列

    5.5.1 用链表实现对列

    • 两个分别指向链表首元素、链表末元素的引用方便队列的链表实现。
    • 对于单向链表,可选择从末端入列,从前段出列。双向链表可以解决需要遍历链表的问题,因此在双向链表实现中,无所谓从哪端入列和出列。
    • 代码:
    public class CircularArrayQueue<T> implements QueueADT<T>
    {
        private final static int DEFAULT_CAPACITY = 100;
        private int front, rear, count;
        private T[] queue; 
      
        /**
         * Creates an empty queue using the specified capacity.
         * @param initialCapacity the initial size of the circular array queue
         */
        public CircularArrayQueue (int initialCapacity)
        {
            front = rear = count = 0;
            queue = (T[]) (new Object[initialCapacity]);
        }
      
        /**
         * Creates an empty queue using the default capacity.
         */
        public CircularArrayQueue()
        {
            this(DEFAULT_CAPACITY);
        }    
    	
    	/**
         * Adds the specified element to the rear of this queue, expanding
         * the capacity of the queue array if necessary.
         * @param element the element to add to the rear of the queue
         */
        public void enqueue(T element)
        {
            if (size() == queue.length) 
                expandCapacity();
        
            queue[rear] = element;
            rear = (rear+1) % queue.length;
        
            count++;
        }
    	
    	/**
         * Creates a new array to store the contents of this queue with
         * twice the capacity of the old one.
         */
        private void expandCapacity()
        {
            T[] larger = (T[]) (new Object[queue.length *2]);
        
            for (int scan = 0; scan < count; scan++)
            {
                larger[scan] = queue[front];
                front = (front + 1) % queue.length;
            }
        
            front = 0;
            rear = count;
            queue = larger;
        }
    	
        /**
         * Removes the element at the front of this queue and returns a
         * reference to it. 
    	 * @return the element removed from the front of the queue
         * @throws EmptyCollectionException  if the queue is empty
         */
        public T dequeue() throws EmptyCollectionException
        {
            if (isEmpty())
                throw new EmptyCollectionException("queue");
        
            T result = queue[front];
            queue[front] = null;
            front = (front+1) % queue.length;
        
            count--;
        
            return result;
        }
      
        /** 
         * Returns a reference to the element at the front of this queue.
         * The element is not removed from the queue.  
         * @return the first element in the queue
         * @throws EmptyCollectionException if the queue is empty
         */
        public T first() throws EmptyCollectionException
        {
            if (isEmpty()){
                throw  new EmptyCollectionException("queue");
            }
            else
                return queue[front];
            // To be completed as a Programming Project
        }
      
        /**
         * Returns true if this queue is empty and false otherwise.
         * @return true if this queue is empty 
         */
        public boolean isEmpty()
        {
           return count==0;
            // To be completed as a Programming Project
        }
      
        /**
         * Returns the number of elements currently in this queue.
         * @return the size of the queue
         */
        public int size()
        {
            return  count;
            // To be completed as a Programming Project
        }
      
        /**
         * Returns a string representation of this queue. 
         * @return the string representation of the queue
         */
        public String toString()
        {
           String result = "";
           int a =front;
           for (int i = 0 ;i< count;i++){
               result += queue[a]+" ";
               a++;
           }
           return  result;
            // To be completed as a Programming Project
        }
    }
    

    5.5.2 用数组实现队列

    • 由于队列操作会修改集合的两端,因此将一段固定于索引0处要求移动元素。
    • 非环形数组实现元素的移位,将产生O(n)的复杂度。
    • 将数组看作是环形的,可以去除在队列的数组实现中把元素移位的需要
    • 代码:
    public class LinkedQueue<T> implements QueueADT<T>
    {
        private int count;
        private LinearNode<T> head, tail;
    
        /**
         * Creates an empty queue.
         */
        public LinkedQueue()
        {
            count = 0;
            head = tail = null;
        }
    
        /**
         * Adds the specified element to the tail of this queue.
         * @param element the element to be added to the tail of the queue
         */
        public void enqueue(T element)
        {
            LinearNode<T> node = new LinearNode<T>(element);
    
            if (isEmpty())
                head = node;
            else
                tail.setNext(node);
    
            tail = node;
            count++;
        }
    
        /**
         * Removes the element at the head of this queue and returns a
         * reference to it. 
         * @return the element at the head of this queue
         * @throws EmptyCollectionException if the queue is empty
         */
        public T dequeue() throws EmptyCollectionException
        {
            if (isEmpty())
                throw new EmptyCollectionException("queue");
    
            T result = head.getElement();
            head = head.getNext();
            count--;
    
            if (isEmpty())
                tail = null;
    
            return result;
        }
       
        /**
         * Returns a reference to the element at the head of this queue.
         * The element is not removed from the queue.  
         * @return a reference to the first element in this queue
         * @throws EmptyCollectionException if the queue is empty
         */
        public T first() throws EmptyCollectionException
        {
            if (isEmpty()){
                throw  new EmptyCollectionException("queue");
            }
            else
                return head.getElement() ;
            // To be completed as a Programming Project
        }
    
        /**
         * Returns true if this queue is empty and false otherwise. 
         * @return true if this queue is empty 
         */
        public boolean isEmpty()
        {
            return  count == 0;
            // To be completed as a Programming Project
        }
     
        /**
         * Returns the number of elements currently in this queue.
         * @return the number of elements in the queue
         */
        public int size()
        {
            return count;
            // To be completed as a Programming Project
        }
    
        /**
         * Returns a string representation of this queue. 
         * @return the string representation of the queue
         */
        public String toString()
        {
            String result = "" ;
            while(head!=null){
                result+=head.getElement()+" ";
                head = head.getNext();
            }
            return  result;
            // To be completed as a Programming Project
        }
    }
    

    5.6 双向链表

    课后作业:

    代码总览:

    测试结果

    • pp5.1 pp5.2:

    • pp5.7:

    教材学习中的问题和解决过程

    • 问题1:课本81页说:在链表的前端实现dequeue操作,需将一个临时变量指向链表前端的元素,然后把front变量设置为第一个节点的next指针的值。 我想问为什么不可以直接front.next = front.next.next
    • 问题1解决方案:个人觉得两种方法都可以。
    • 问题2:如何理解front = (front + 1 ) % queue,length?
    • 问题2解决方案:书上说是非环形的数组实现元素移位,将产生O(n)的复杂度,所以把数组看作是环形的,可以除去在队列的数组实现中把原始与移位的需要。

    代码调试中的问题和解决过程

    • 问题1:用数组实现链表时,使用两次enqueue方法,在使用一次dequeue方法,发现第一次实现的没有用为null。

    • 问题1解决方案:toString方法出现错误:
      修改前:
      修改后:
      出现这个问题的原因是:当使用dequeue方法后不知道front已经发生变化。

    代码托管

    上周考试错题总结

    • 错题暂未公布

    点评模板:

    • 队友值得学习的地方:
      • 课本内容记录详细,课本中的有些错误也能发现并及时纠正。
      • 不懂得地方选择自己尝试,选择去敲代码验证。

    点评过的同学博客和代码

    • 本周结对学习情况
      • 20172310
      • 结对学习内容
        • 第五章内容
        • 如何用数组、链表实现对列
        • 双向对列的编程

    其他(感悟、思考等,可选)

    虽然这一章使用的是以前的知识,比如相关的数组、栈、多态、继承什么的,但是发现自己还是不能很熟练的运用。很多基础概念还是很模糊,说明自己还是得加油。  
    

    学习进度条

    代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
    目标 5000行 30篇 400小时
    第一周 075/200 1/1 05/20
    第二周 560/500 1/2 13/38
    第三周 983/1000 1/3 21/60

    补充作业

    • (写之前说一下,之前没有看到这个补充作业,现在补充)

    参考文献

  • 相关阅读:
    使用内部单向链表实现的一个简单堆栈
    通过反射调用内部类的隐藏方法
    动态代理生成空对象
    通过使用java.lang.reflect.Proxy实现动态代理
    简单代理模式
    暗色CSS,适用与Stylish, IE, FF, OPERA等.
    CWnd派生的控件处理MouseMove, MouseHover, MouseLeave
    _tcscpy_s的size应至少为src的长度+1(要把计算在内)
    用INET(CHttpFile)下载有重定向链接时获取最终URL的方法.
    GetDlgItem以及其他获得CWnd相关的函数要注意。。
  • 原文地址:https://www.cnblogs.com/dky-wzw/p/9709920.html
Copyright © 2020-2023  润新知