20172314 2018-2019-1《程序设计与数据结构》第二周学习总结

教材学习内容总结

第三章 集合概述-栈

集合

  • 集合是一种汇集组织了其余对象的对象
  • 线性集合:元素按直线方式组织的集合 非线性集合:元素按非直线方式(例如网状组织或层次组织)组织的集合。
    html

  • 集合中的元素一般是按照他们添加到集合中的顺序,或者是按元素之间的某种内在关系来组织的。前端

    抽象数据类型
  • 集合是一种隐藏了实现细节的抽象。
  • 数据类型:是一组值及做用于这些数值上的各类操做。(例如整数数据类型就包括数值及这些数值之间的加减乘除操做。)
  • 抽象数据类型:是一种在程序设计语言中还没有定义其值和操做的数据类型。
  • 数据结构是一种用于实现集合的基本编程结构。java

    Java集合API
  • Java程序设计语言的部分用于支持软件开发的类库是以API(应用程序编程接口)形式存在的。
  • Java集合API是一个类集,表示了一些特定类型的集合,这些类的实现方式各不相同。
  • Java集合API提供的集合1.可能只是咱们所需集合的一个子集2.可能并无按照咱们所但愿的方式来实现这些集合3.对软件开发的研究要求咱们深刻理解集合设计以及用数据结构实现集合所涉及的一些问题。因此咱们仍需学习如何设计实现集合。android

    栈集合

  • 一般垂直绘制栈,并把栈的末端称为栈的顶部。
    git

  • 栈的常见操做:
    • push:添加一个元素到栈的顶部
    • pop:从栈的顶部移出一个元素
    • peek(有时称为top):查看栈顶部的元素
    • isempty:肯定栈是否为空
    • size:肯定栈的元素数目
  • 编程人员选择的数据结构,应与须要进行数据管理的类型相适应。程序员

主要的面向对象概念

  • 类型兼容性:把一个对象赋给引用的特定赋值是否合法。例如String x = new Integer(10)就是不合法的。
  • 把数据储存在集合中能够利用继承和多态的概念,以建立能够储存任意类型的对象的集合。

继承与多态

  • 多态引用是一个引用变量,他能够在不一样地点引用不一样类型的对象。继承能够建立一个类层次,一个变量能够用于指向与之相关的任何对象。

泛型

  • 泛型指能够定义一个类,以便他能存储、操做和管理在实例化以前没有指定是何种类型的对象。
  • 把Box类定义为能够储存泛型T
    class Box<T> } //用于管理类型T的对象的声明和代码 }
  • 实例化Box类时,须要用具体的类来替换T来实例化它
    Box<Widge> box1 = new Box<Widge>编程

    Box<Gadget> box2 = new Box<Widge>api

    box1和box2只能分别储存Widge和Gadget类型数组

  • 泛型(T)不能被实例化,他只是一个占位符,容许咱们去定义管理特定类型的对象的类,且只有当该类被实例化时,才建立该类型的对象。数据结构

使用栈计算后缀表达式

  • 当遇到操做符弹出操做数时,首先弹出的是第二个操做数,第二个弹出的是第一个操做数,这种顺序对于加法和乘法无影响,但对减法除法有影响。
  • 后缀表达式不合法的状况:
    • 遇到操做符时栈中没有两个操做数。
    • 当表达式中的符号用完后,栈中的数不止一个。

Javadoc

  • doc注释以 /** 开始,以 */ 结束
  • Javadoc是Java代码添加注释的官方标准
  • @author标识代码的程序员
    @version指定代码的版本号
    @return代表由该方法返回的值
    @param标识传递给该方法的每一个参数

异常

  • 异常就是一个对象,它定义了一种非正常或错误的状况。异常由程序或运行时环境抛出,能够按预期的被捕或被正常处理。
  • 错误与异常相似,只不过错误每每表示一种没法恢复的状况,且没必要去捕获它。

栈ADT

Java接口定义了一个抽象方法集,有助于把抽象数据类型的概念与其实现分隔开来。

  • 经过使用接口名做为返回类型,方法就不会局限于实现栈的任何特定类。
  • 栈接口被定义为StackADT ,表示做用于泛型T。在该接口的方法中,各类参数和返回值的类型每每用泛型T来描述。当实现该接口时,将会用某种数据类型来替换泛型T。
  • 栈接口
  • ```public interface StackADT <T>```
    其中interface是保留字,StackADT是接口名, 是泛型参数。
  • 取消操做能够用栈来实现,名为drop-out,将取消的操做压入栈中,或退回弹出,当达到限制时,栈底的元素将被从栈中丢掉。

用数组实现栈

  • 集合操做的实现不该该影响到用户与该集合进行交互的方式。
  • 建立可储存number个元素的数组,其容量为number
    Object[] collection = Object[number]

  • 当元素添加到一个满的数据结构中时:
    • 若是集合为满,抛出一个异常
    • 实现add操做,返回一个可由用户检查的状态标识符,以便查看该add操做是否成功。
    • 当须要时可扩展集合的容量,这样集合永远也不会满。

ArrayStack类

  • 出于运行效率的考虑,基于数组的栈实现老是使栈底位于数组的索引0处。
  • 栈的数组实现能够经过4个假设来实现
    • 该数组是一个对象引用的数组(数据类型在实例化时肯定)
    • 栈底老是在数组的索引0处
    • 栈的元素是按顺序并连续地储存在数组中
    • 有一个整数变量top,保存了紧跟栈顶元素后的数组索引号
  • 构造函数
    • /*使用默认容量建立一个空栈*/
        public ArryStack()
        {
          top = 0;
          stack = (T[]) (new Object[DEFAULF_CAPACITY]);
          /*实例化了一个Object数组,而后把他转换为一个泛型数组。这里会产生一个未检验类型转换的编译时的警告,可用@SuppressWarnings("uncheched")禁止警告。*/
        }
      /*使用指定容量建立一个空栈,参数initialCapacity表示的是指指定容量*/
      public ArrayStack (int initialCapacity)
      {
          top = 0;
          stack = (T[]) (new Object[initialCapacity])
      }
  • 泛型(包括泛型数组)不能被实例化,这就是为何咱们必须建立一个储存Object引用的数组,而后把它转换成泛型数组的缘由。
  • 建立一个泛型数组
    stack = (T[]) (new Object[initialCapacity]);

push

public void push(T element)
        {
        if (size() == stack.length) 
            expandCapacity();

        stack[top] = element;
        top++;
        }

pop

public T pop() throws EmptyCollectionException
        {
            if (isEmpty())
            throw new EmptyCollectionException("stack");

        top--;
        T result = stack[top];
        stack[top] = null; 

        return result;
        }

peek

public T peek() throws EmptyCollectionException
        {
        if (isEmpty())
            throw new EmptyCollectionException("stack");

        return stack[top-1];
        }

isEmpty

```
 public boolean isEmpty()
    {
    if(size()==0) {
        return true;
    }else {
        return false;
    }
    }
```

size

public int size()
        {
            return top;
        }

toString

public String toString()
        {
            String string="";
            for(int i=0;i<top;i++) {
                System.out.println(stack[i]);
            }
            return string;
        }

第四章 链式结构-栈

  • 链式结构是一种数据结构,它使用对象引用变量来建立对象之间的连接。
  • 对象引用变量存放的是对象的地址,表示该对象在内存中的存储位置。
  • 一般并不显示地址,而是将引用变量描绘成一种“指向”对象的名字,称为“指针”。
  • 在链表中存储的对象一般泛称为该链表的结点。
  • 链表会按需动态增加,所以在本质上,他没有容量限制。

管理链表

  • 访问链表惟一方式就是从第一个元素开始顺着链表往下进行,由于一旦first指针移到了指向链表的第二个元素,就再也没有指向第一个元素的指针了。
  • 改变引用顺序是维护链表的关键。
  • 插入结点:新添加结点的next引用被设置为指向链表的当前首结点,接着,指向链表前端的引用从新设置为指向这个新添加的结点。
  • 删除结点:重置指向链表前端的引用,使其指向链表当前的次结点。
  • 哨兵结点或哑结点能够做为一个假的第一结点,并无真正表示列表中的某个元素。
  • 递归:间接或直接调用自身的过程或方法。
  • 程序栈/运行时栈:每调用一个方法,就会建立一个表示该调用的调用记录,并压入到程序栈中,所以,栈中的元素表示的是一个正在运行的程序中,到达某个位置时所调用的方法系列。

用链表实现栈

  • 栈的链表实现是从链表的一端添加和删除元素。
  • push操做:
    • 建立一个新结点,该结点含有一个引用,指向要放置到栈中的对象
      *把新结点的next引用设置为指向当前栈顶(若是栈为空,它就是null)
    • 把top引用设置为指向该新结点
    • 递增栈的元素计数
  • pop操做
    • 确保栈不为空
    • 设置一个临时引用等于栈顶元素
    • 设置top引用等于栈顶结点的next引用
    • 递减栈的元素计数
  • push和pop的复杂度都为O(1)

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

  • 问题一:使用栈来穿越迷宫的原理
  • 问题二:参考:java 用栈的原理(穷举)实现迷宫游戏

    在一个封闭的空间内,用’0’表示可走,’1’表示墙;有一个起点和一个终点,须要找到从起点到终点的通路,还要保证在寻路的过程当中不会出现来回走的状况。从起点出发,咱们用0,1,2,3来表示上下左右,也就是寻路的方向;每走一步以后都按照0,1,2,3的方向进行试探能否走,若是能走,把能走的坐标和来时的方向进行压栈,栈里都是走过的路线,若是0不通走1,1不通走2,2不通走3,都不通退一格,继续按照0-->1-->2-->3的方向寻路。这就很符合栈的先进后出原理,坐标点在栈里的存储能够用数组实现,也能够用链表实现,这里使用链表。存放坐标和方向使用类的数组,好像叫什么结构体,习惯性叫类的数组。

  • 问题二:关于泛型的理解
  • 问题二解决:

    泛型就是变量类型的参数化。在使用泛型前,存入集合中的元素能够是任何类型的,当从集合中取出时,全部的元素都是Object类型,须要进行向下的强制类型转换,转换到特定的类型。而强制类型转换容易引发运行时错误。泛型类型参数只能被类或接口类型赋值,不能被原生数据类型赋值,原生数据类型须要使用对应的包装类。

    例如:
    class GenericsTest<T> 声明了一个泛型类,这个T没有任何限制,实际上至关于Object类型,实际上至关于
    class GenericsTest<T extends Object>
    与Object泛型类相比,使用泛型所定义的类在声明和构造实例的时候,可使用“ <实际类型> ”来一并指定泛型类型持有者的真实类型。类如
    GenericsTest<Double> douTest=new
    GenericsTest<Double>(new Double("33"));
    固然,也能够在构造对象的时候不使用尖括号指定泛型类型的真实类型,可是你在使用该对象的时候,就须要强制转换了。好比:
    GenericsTest douTest=new GenericsTest(new Double("33"));
    实际上,当构造对象时不指定类型信息的时候,默认会使用Object类型,这也是要强制转换的缘由。

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

  • 问题一:在蓝墨云做业链表练习时,须要从键盘输入整数创建链表,我仿照课堂上老师演示的student事例,可是那个例子须要实例化Student对象,而做业要求是键盘输入不可提早预知数字的,因此没法继续实现。

  • 问题一解决:我以前是想用栈来保存并循环输出,在王文彬同窗的帮助下,实例化时改成以下Node Head = new Node(Integer.parseInt(a[0]));而后用循环插入建立链表
for (int i = 0; i < a.length-1; i++) {
            Node x = new Node(Integer.parseInt(a[i+1]));
            InsertNode(Head,x);
        }

就能够实现了。

  • 问题二:蓝墨云做业实现插入时,老是在最后插入数字
//插入
        System.out.println();
        System.out.println("请输入要插入的数字:");
        Scanner scan3 = new Scanner(System.in);
        int s = scan3.nextInt();
        Node san = new Node(s);

        System.out.println("请输入要插入的位置:");
        Scanner scan4 = new Scanner(System.in);
        int f = scan4.nextInt();

        Node temp3=Head;

        for (int i = 1;i<f;i++){
            temp3=temp3.next;
        }
        InsertNode(Head,san);
        System.out.println("插入后的链表为:");
        PrintLinkedList(Head.next);

  • 问题二解决:我错误的地方在于我插入时使用的循环是往中间插的,而我使用的插入方法InsertNode是尾插法,因此要考虑到插入有三种状况,头插中间插和尾插,要分别来写插入。修改后的代码以下。
//插入
        System.out.println();
        System.out.println("请问想要插入什么数字:");
        Scanner y = new Scanner(System.in);
        int pos2=y.nextInt();
        Node insertnumber = new Node(pos2);
        System.out.println("请问想要插入在什么位置:");
        Scanner qq = new Scanner(System.in);
        int pos = qq.nextInt();
        Node abc = Head;

        if (pos==1){

            System.out.println();
            System.out.println("插入后的链表为:");
            Firstinsert(Head,insertnumber);
            PrintLinkedList(Head);
            Node ii=new Node(pos2);
            InsertNode(Head,ii);
            int num2=Head.data;
            Node numm=new Node(num2);
           InsertNode(Head,numm);
            Node temp0=Head;
        }
        else if (pos!=1&&temp.next!=null){
            for (int i = 1;i<pos-1;i++){
                linshi = linshi.next;
            }
            insert(Head,abc,abc.next,insertnumber);
            System.out.println("插入后的链表为:");
            PrintLinkedList(Head);
            InsertNode(Head,xxx);
        }

        else if (temp.next==null)
        {
            InsertNode(Head,insertnumber);
            System.out.println("插入后的链表为:");
            PrintLinkedList(Head);
            InsertNode(Head,xxx);
        }

代码托管

如今是4975行,上学期结束时3872行,增长了1163行。

  • PP3.2

  • PP3.8

  • PP3.9

  • PP4.2

    因为安卓没法git,代码以下
import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.TextView;

    import java.util.Stack;

    public class MainActivity777 extends AppCompatActivity {
    LinkedStack<String> stack = new LinkedStack();
    String xxx = "";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main777);

        Button button1 = (Button) findViewById(R.id.button);
        Button button2 = (Button) findViewById(R.id.button2);
        button1.setOnClickListener(new myButtonListener());
        button2.setOnClickListener(new myButtonListener1());
        }

        public class myButtonListener implements View.OnClickListener {
        @Override
        public void onClick(View v) {
            EditText editText1 = (EditText) findViewById(R.id.editText);
            stack.push(editText1.getText().toString());
            TextView editText2 = (TextView) findViewById(R.id.editText4);
            editText2.setText(editText1.getText(), TextView.BufferType.EDITABLE);
            xxx += "进入栈中的数是:"+ stack.peek()+"\n";
            editText2.setText(xxx ,TextView.BufferType.EDITABLE);
            xxx += "当前栈是:" +stack+"\n";
            editText2.setText(xxx , TextView.BufferType.EDITABLE);

        }
    }
    public class myButtonListener1 implements View.OnClickListener{
        @Override

        public void onClick(View v){
            EditText editText1 = (EditText) findViewById(R.id.editText);
            stack.pop();
            TextView editText2=(TextView) findViewById(R.id.editText4);
            editText2.setText(editText1.getText(),TextView.BufferType.EDITABLE);
            xxx += "从栈中弹出的数是:" +stack.peek()+"\n";
            editText2.setText( xxx, TextView.BufferType.EDITABLE);
            xxx += "当前栈是:" +stack+"\n";
            editText2.setText(xxx, TextView.BufferType.EDITABLE);
        }
        }
    }

上周考试错题总结

  • 错题一:

  • 错题一解析:应该是健壮性的特征是出错状况下能够获得恰当处理的程度。
  • 错题二:

  • 错题二解析:应该是题目错了。nlogn的阶次大于2n。

结对及互评

点评模板:

  • 博客中值得学习的或问题:
    • 20172305谭鑫的博客中课本疑难问题解决的很好,内容全面,教材中遇到的问题和代码中的问题过程记录的十分详细。
    • 20172323王禹涵的博客中课本内容总结详实,感悟深入,但遇到的问题解决过程能够更加详细一点。
  • 基于评分标准,我给谭鑫的博客打分:11分。得分状况以下:
    • 问题加分8分
    • 感悟不假大空加1分
    • 排版精美的加1分
      -正确使用Markdown语法加1分
      -模板中的要素齐全加1分
  • 基于评分标准,我给王禹涵的博客打分:7分。得分状况以下:
    • 排版精美的加1分
    • 问题加分3分
    • 感悟不假大空加1分
      -正确使用Markdown语法加1分
      -模板中的要素齐全加1分

其余

对LinkedStack类不是很熟悉,还有链表里的头插法,但同时对链表还有栈的学习更加深刻了一些。

学习进度条

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积)
目标 5000行 30篇 400小时
第一周 0/0 1/1 8/8
第二周 1163/1163 1/2 15/23

参考:

相关文章
相关标签/搜索