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

參考:

相關文章
相關標籤/搜索