20172313 2018-2019-1 《程序設計與數據結構》實驗一報告

20172313 2018-2019-1 《程序設計與數據結構》實驗一報告

課程:《程序設計與數據結構》
班級: 1723
姓名: 餘坤澎
學號:20172313
實驗教師:王志強
實驗日期:2018年9月26日
必修/選修: 必修java

1.實驗內容

  • 實驗一
    鏈表練習,要求實現下列功能:
    經過鍵盤輸入一些整數,創建一個鏈表;
    這些數是你學號中依次取出的兩位數。 再加上今天的時間。
      例如你的學號是 20172301
      今天時間是 2018/10/1, 16:23:49秒數字就是20, 17,23,1, 20, 18,10,1,16,23,49
      打印全部鏈表元素, 並輸出元素的總數。 在你的程序中,請用一個特殊變量名來紀錄元素的總數,變量名就是你的名字。 例如你叫 張三, 那麼這個變量名就是
      int nZhangSan = 0; //初始化爲 0.
    作完這一步,把你的程序簽入源代碼控制(git push)。
  • 實驗二
      實現節點插入、刪除、輸出操做;
      繼續你上一個程序,擴展它的功能,每作完一個新功能,或者寫了超過10行新代碼,就簽入代碼,提交到源代碼服務器;
    從磁盤讀取一個文件, 這個文件有兩個數字。
    從文件中讀入數字1, 插入到鏈表第 5 位,並打印全部數字,和元素的總數。 保留這個鏈表,繼續下面的操做。
    從文件中讀入數字2, 插入到鏈表第 0 位,並打印全部數字,和元素的總數。 保留這個鏈表,並繼續下面的操做。
    從鏈表中刪除剛纔的數字1. 並打印全部數字和元素的總數。
    簽入全部代碼。
  • 實驗三
      使用冒泡排序法或者選擇排序法根據數值大小對鏈表進行排序;
      若是你學號是單數, 選擇冒泡排序,不然選擇選擇排序。
      在排序的每個輪次中,打印元素的總數,和目前鏈表的全部元素。 在實驗二獲得的程序中繼續擴展, 用同一個程序文件,寫不一樣的函數來實現這個功能。 仍然用 nZhangSan (你的名字)來表示元素的總數。
  • 實驗四
      用數組代替鏈表實現實驗一和實驗二。
  • 實驗五
      用數組代替鏈表實現實驗三node

    2. 實驗過程及結果

實驗一

  • 學習教材,瞭解鏈表的數據結構並結合網絡上的相關知識進行實現。
  • 使用StringTokenizer分割輸入的數據,將其存入到鏈表中。
LinkedQueue lq = new LinkedQueue();
        System.out.println("請輸入一系列整數:");
        Scanner scan = new Scanner(System.in);
        String str = scan.nextLine();
        StringTokenizer st = new StringTokenizer(str);
        while(st.hasMoreTokens()){
            lq.enqueue(st.nextToken());
        }

實驗二

  • 實驗二要求實現節點的插入,刪除和輸出。注意在節點添加和刪除時指針的前後指向順序,防止鏈表丟失。操做完成後要對錶示鏈表元素數目的變量(nYuKunpeng)進行自增和自減。
insert 方法 (將數據(element)插入適當的索引(A)處)
 public void insert(T element1, int A){
        LinearNode<T> node1 = new LinearNode<T>(element1);
        LinearNode<T> current = head;

        if(A==0){
            node1.setNext(current);
            head = node1;
        }
        else{
            for(int i = 1; i < A; i ++)
                current = current.getNext();
            node1.setNext(current.getNext());
            current.setNext(node1);
        }
        nYuKunpeng++;

    }
delete 方法 (刪除指定索引處(A)的元素)
public void delete(int A){
        LinearNode current, temp = null;
        current = head;

        if( A == 0)
            head = head.getNext();
        else{
            for(int i = 0; i < A; i ++) {
                temp = current;
                current = current.getNext();
            }
            temp.setNext(current.getNext());
        }
        nYuKunpeng --;
    }
ToString 方法(便歷鏈表依次打印)
public String toString(){
        String result = "";
        LinearNode<T> current = head;
        int a = nYuKunpeng;
        while(a > 0) {
            result += current.getElement()+ ",";
            current = current.getNext();
            a--;
        }
        return result;
    }

實驗三

  • 在實驗二的基礎上對元素進行排序,因爲我使用的是冒泡排序法,在每次的循環中把該位置的元素與該元素以前位置的元素相比較,在合適的狀況下兩個節點內保存的數據進行交換,已達到冒泡的目的。
sort 方法
public void sort(){
        LinearNode2<T> current, temp = null;
        T n;
        for(current = head; current != null; current = current.getNext()){         //外層循環遍歷鏈表內的元素
            for(temp = current;temp.getPrevious() != null; temp = temp.getPrevious()){   //內層循環使用該元素與他以前的元素進行比較
                if(Integer.parseInt(temp.getPrevious().getElement()+"")>Integer.parseInt(temp.getElement()+ "")){
                    n = temp.getPrevious().getElement();              //使用臨時變量n來交換兩個節點內的元素
                    temp.getPrevious().setElement(temp.getElement());
                    temp.setElement(n);
                }
            }
            System.out.println("此輪排序後元素的順序" + toString() + "此時元素的個數爲" + size());
        }
    }

實驗四

  • 實驗四與實驗一二的不一樣之處在於這裏採用數組進行實現。鏈表是動態的,在進行插入和刪除操做時直接能夠在原鏈表上進行操做,不佔用多餘的儲存空間。但若是是數組的話,須要考慮數組的長度。在插入和刪除時,若是直接對原數組操做時會比較麻煩容易出錯,因此我在這裏的思路是另外申請一個數組,先把原數組要刪除或插入地方的索引前面的元素遍歷進入新的數組中,再對須要添加或刪除的元素進行操做,以後再遍歷該索引後的元素。
add方法 (把指定的元素(element)插入到適當的索引處(a))
//add方法分爲兩種,在不加索引參數的時候直接在數組的末尾進行添加,在這裏只列舉有索引參數的方法,下面的delete方法也是如此。
 public void add(T element, int a){
        T[] B = (T[])(new Object[size() + 1]);
        for(int i =0; i < a;i ++)
            B[i] = A[i];
        B[a] = element;
        for(int i = a + 1;i < size() + 1; i ++ ) {
            B[i] = A[i - 1];
        }
        A = B;
        nYuKunpeng ++;
    }
delete方法 (刪除指定索引處(a)的元素)
  public void delete(int a){
        T[] B = (T[])(new Object[size() - 1 ]);
        for(int i = 0;i < a; i++)
            B[i] = A[i];
        for(int i = a;i < size() - 1; i++)
            B[i] = A[i+1];
        A = B;
        nYuKunpeng--;
    }

實驗五

  • 數組的排序實現較爲簡單,在這裏直接吧重要代碼貼上。
public void sort(){
       for(int i=0;i<size();i++) {
           for (int j = i; j > 0; j--) {
               if (Integer.parseInt(A[j-1] + "") > Integer.parseInt(A[j]+ "")) {
                   T temp = A[j];
                   A[j] = A[j - 1];
                   A[j - 1] = temp;
                }
            }
           System.out.println("此時元素爲:" + toString()+ "元素的個數爲" + size());
        }
    }

3. 實驗過程當中遇到的問題和解決過程

  • 問題一:在作實驗三的時候,發如今進行冒泡排序的時候,兩個數沒法進行比較,會顯示數據被封裝。
  • 問題一解決方案:強制類型轉換在T類型和char類型當中進行轉換是不適用的,先把T類型轉化爲String類型,在轉換爲int就能夠了。

    git

  • 問題二:在作實驗四的時候,在進行元素的插入後發現元素會減小一個。
  • 問題二解決方案:在插入元素的時候,記錄數組內元素個數的變量nYuKunpeng沒有進行自增,致使最後在ToString時遍歷數組會致使元素個數少一。
    算法

  • 問題三:我在進行鏈表冒泡排序的時候,不是很能理解冒泡排序的含義。
    數組

    算法原理
    冒泡排序算法的原理以下:
      比較相鄰的元素。若是第一個比第二個大,就交換他們兩個。
      對每一對相鄰元素作一樣的工做,從開始第一對到結尾的最後一對。在這一點,最後的元素應該會是最大的數。
      針對全部的元素重複以上的步驟,除了最後一個。
      持續每次對愈來愈少的元素重複上面的步驟,直到沒有任何一對數字須要比較。
    算法穩定性:
      冒泡排序就是把小的元素往前調或者把大的元素日後調。比較是相鄰的兩個元素比較,交換也發生在這兩個元素之間。因此,若是兩個元素相等,是不會再交換的;若是兩個相等的元素沒有相鄰,那麼即便經過前面的兩兩交換把兩個相鄰起來,這時候也不會交換,因此相同元素的先後順序並無改變,因此冒泡排序是一種穩定排序算法。服務器

  • 問題三解決方案:我在進行排序的時候一直想着把最小的數值放在前面,爲了可以獲得所選節點前面的節點,因此我只好使用雙向鏈表,但這樣勢必會增長代碼的繁瑣量。我在上網查詢了資料後,發現了一種更好的排序代碼,在這裏貼上,代碼博客地址附在本博客末尾。
//單鏈表冒泡排序  
        public Node blueSortList(Node node){  
            System.out.println("blue start...");  
            //當前節點  
            Node cur = node.next;  
            //下一個節點  
            Node next = cur.next;  
            //前一個節點,兩節點n1,n2交換位置時須要前一個節點的next指向n2節點  
            Node upperNode = node;  
            //一次排序的最後一個節點  
            Node lastNode = null;  
            int i = 1;  
            //當第二個節點爲當次排序的最後一個節點時,總體排序結束  
            while(node.next != lastNode){  
                //當下一個節點爲一次次排序的最後一個節點時,本次排序結束。  
                if(next == lastNode){  
                    lastNode = cur;  
                    cur = node.next;  
                    next = cur.next;  
                    upperNode = node;  
                }else if(next.value < cur.value){  
                    cur.next = next.next;  
                    next.next = cur;  
                    upperNode.next = next;  
                    upperNode = next;  
                }else{  
                    upperNode = cur;  
                    cur = cur.next;  
                }  
                next = cur.next;  
                System.out.println("第" + i++ + "次排列結果:");  
                printList(node.next);  
            }  
            System.out.println("blue end...");  
            return node;  
        }

其餘

  此次實驗的難度相對來講不是特別高,一方面沒有新的知識,另外一方面其中須要的不少代碼在以前也有練習過。儘管如此,因爲本身的粗心和理解的不透徹,仍是在實驗中浪費了很多時間,但願可以在之後的學習生活中繼續努力,不斷進步!網絡

參考資料

相關文章
相關標籤/搜索