1. 程式人生 > >資料結構(1):使用面向物件模擬陣列

資料結構(1):使用面向物件模擬陣列

陣列是一種常用的資料結構,陣列具有不可變性,建立後的陣列的長度固定,通過索引訪問陣列中的元素,訪問速度快,刪除新增效率低。

通過面向物件模擬陣列,模擬的陣列具有以下功能:

  1. 新增新元素
  2. 展示
  3. 查詢元素所在位置
  4. 根據索引獲取元素
  5. 根據索引刪除元素
  6. 修改指定位置的元素

同時使用兩個演算法對陣列進行操作:

  1. 有序新增元素
  2. 二分查詢法

1.建立陣列類 MyArray.java

資料如何儲存呢?在類中新增一個數組型別的私有屬性用來儲存資料,同時新增一個變數儲存有效資料的長度(也就是元素的個數)

建立陣列的時候需要指定陣列的長度,所以要新增兩個構造方法:

1.無參構造方法設定陣列預設長度
2.有參構造方法指定陣列長度

public class MyArray {
    //儲存元素
    private long[] arr;
    //表示有效資料的長度
    private int elements;

    //無參構造預設50個長度
    public MyArray() {
        arr=new long[50];
    }

    public MyArray(int maxsize) {
        arr=new long[maxsize];
    }
}

2.編寫新增資料的方法

elements 屬性的預設值是 0,第一次向物件中新增元素也是新增到索引為0 的元素中,新增後將 elements 的長度加1,就能一直向陣列中新增元素了,新增元素的個數取決於 arr 的長度。

public void insert(long value) {
    arr[elements]=value;
    elements++;
}

3.編寫展示資料的方法

簡單的展示陣列中的元素即可,使用 for 迴圈遍歷

public void display() {
    System.out.print("[");
    for (int i = 0; i < elements; i++) {
        System.out.print(arr[i]+" ");
    }
    System.out.println("]");
}

4.編寫查詢資料的方法

思路:使用迴圈遍歷陣列 arr ,將要查詢的資料和 arr 中每個元素進行比較。如果相等,則跳出迴圈。迴圈結束後,如果迴圈次數等於元素個數說明沒有找到資料,返回-1。否則返回迴圈次數(即找到的索引)。

public int search(long value) {
    int i ;
    for (i = 0; i < elements; i++) {
        if(value==arr[i]) {
            break;
        }
    }
    //遍歷到末尾說明沒有找到
    if (i==elements) {
        return -1;
    }else {
        return i;
    }
}

5.根據索引獲取元素

思路:這相對比較簡單了,直接給 arr 索引就能獲取到元素。但是要注意傳入的索引必須可用,不能用的索引可以丟擲異常。

public long get(int index) {
    //如果索引大於可用,或索引小於0 都是無效的索引
    if (index>=elements||index<0) {
        //丟擲陣列越界異常
        throw new ArrayIndexOutOfBoundsException();
    }else {
        return arr[index];
    }
}

6.根據索引刪除元素

思路:和獲取元素時一樣,先檢查索引是否可用。如果可用,就從要刪除元素的位置開始向後遍歷,每次都將下一個元素的值賦值給當前元素。也就相當於要刪除的元素被下一個元素覆蓋,下一個元素被下下一個元素覆蓋,以此類推。元素移動完成後,將可用元素長度 elements 減1。

public void delete(int index) {
    //如果索引大於可用,或索引小於0 都是無效的索引
    if (index>=elements||index<0) {
        throw new ArrayIndexOutOfBoundsException();
    }else {
        for(int i=index;i<elements;i++) {
            arr[index]=arr[i+1];
        }
        elements--;
    }
}

7.修改指定位置的元素

思路:和獲取差不多,就是把獲取改為修改

public void change(int index,int newValue) {
    //如果索引大於可用,或索引小於0 都是無效的索引
    if (index>=elements||index<0) {
        throw new ArrayIndexOutOfBoundsException();
    }else {
        arr[index]=newValue;
    }
}

8.完整程式碼

public class MyArray {
    private long[] arr;
    //表示有效資料的長度
    private int elements;

    public MyArray() {
        arr=new long[50];
    }

    public MyArray(int maxsize) {
        arr=new long[maxsize];
    }

    /**
     * 新增資料
     * @param value
     */
    public void insert(long value) {
        arr[elements]=value;
        elements++;
    }

    /**
     * 顯示資料
     */
    public void display() {
        System.out.print("[");
        for (int i = 0; i < elements; i++) {
            System.out.print(arr[i]+" ");
        }
        System.out.println("]");
    }

    /**
     * 查詢資料
     */
    public int search(long value) {
        int i ;
        for (i = 0; i < elements; i++) {
            if(value==arr[i]) {
                break;
            }
        }
        //遍歷到末尾說明沒有找到
        if (i==elements) {
            return -1;
        }else {
            return i;
        }
    }

    /**
     * 查詢資料,根據索引來查
     */
    public long get(int index) {
        //如果索引大於可用,或索引小於0 都是無效的索引
        if (index>=elements||index<0) {
            throw new ArrayIndexOutOfBoundsException();
        }else {
            return arr[index];
        }
    }

    /**
     * 刪除資料 
     */
    public void delete(int index) {
        //如果索引大於可用,或索引小於0 都是無效的索引
        if (index>=elements||index<0) {
            throw new ArrayIndexOutOfBoundsException();
        }else {
            for(int i=index;i<elements;i++) {
                arr[index]=arr[i+1];
            }
            elements--;
        }
    }

    /**
     * 更新資料
     */
    public void change(int index,int newValue) {
        //如果索引大於可用,或索引小於0 都是無效的索引
        if (index>=elements||index<0) {
            throw new ArrayIndexOutOfBoundsException();
        }else {
            arr[index]=newValue;
        }
    }
}

9.有序新增元素

思路:修改 insert 方法,遍歷 arr 陣列,如果當前元素大於新增的資料,當前的位置就要存入的位置。從最後一個元素開始,逐個將元素向後位移,空出要存入的位置。存入要新增的元素後,將有效資料長度加1。

public void insert(long value) {
    int i;
    for(i=0;i<elements;i++) {
        if(arr[i]>value) {
            break;
        }
    }
    for (int j = elements; j > i; j--) {
        arr[j]=arr[j-1];
    }
    arr[i]=value;
    
    elements++;
}

10.二分查詢法

思路:資料必須是有序的,才能使用二分查詢法!可以結合有序新增元素一塊使用,這裡的序列是升序(從小到大)。二分查詢是每次和一組數中間的數進行比較,如果大於就再和右邊的數最中間的數比較,如果小於就和左邊的數最中間的數比較。直到中間的數和要查詢的數相等,否則就是沒有這個數。

public int binarySearch(long value) {
    int mid=0;//中間值
    int low=0;
    int high = elements;
    
    while(true) {
        mid=(high+low)/2;
        if(arr[mid]==value) {
            return mid;
        }else if(low>high) {
            return -1;
        }else {
            if (value>arr[mid]) {
                high=mid+1;
            }else {
                high=mid-1;
            }
        }
    }
    
}

相關推薦

資料結構1使用面向物件模擬陣列

陣列是一種常用的資料結構,陣列具有不可變性,建立後的陣列的長度固定,通過索引訪問陣列中的元素,訪問速度快,刪除新增效率低。 通過面向物件模擬陣列,模擬的陣列具有以下功能: 新增新元素 展示 查詢元素所在位置 根據索引獲取元素 根據索引刪除元素 修改指定位置的元素 同時使用兩個演算法對陣列進行操作: 有序

資料結構1陣列

1.陣列優勢 (1)快速查詢 (2)適用於有語境的情況 2.製作私有陣列 (1)使用泛型,從而可以實現儲存多種型別資料 (2)可以動態擴容或者縮容 (3)實現增刪改查基本操作 3.java實現 public class ArrayDynamic<E> {

無鎖資料結構1簡介

希望本文能成為無鎖(lock free)資料結構系列文章一個好的開端。我很樂意與社群分享我的經歷,這個系列就什麼是無鎖資料結構、如何實現以及 STL 容器概念是否適用於無鎖容器,何種情形下適合應用無鎖資料結構做一些分享。 談論無鎖資料結構,必然要談論諸如原子操作、程

小朋友學資料結構1約瑟夫環的連結串列解法、陣列解法和數學公式解法

約瑟夫環(Josephus)問題是由古羅馬的史學家約瑟夫(Josephus)提出的,他參加並記錄了公元66—70年猶太人反抗羅馬的起義。約瑟夫作為一個將軍,設法守住了裘達伯特城達47天之久,在城市淪陷之後,他和40名死硬的將士在附近的一個洞穴中避難。在那裡,這些

JavaScript 資料結構 連結串列

前言 從實用性角度來說,連結串列對Javascript 來說沒有任何價值,為什麼呢? 我們先了解連結串列的特性,這個特性我們放在c++前提下來說,因為 這個特性是 根據 記憶體特性 來闡述的,Javascript 不存在記憶體操作,所有資料型別,本質性繼承Object 物件,而Ob

資料結構線性表

一、線性表及其邏輯結構 1、線性表的定義 線性表是具有相同特性的資料元素的一個有限序列。 該序列中所含的元素個數叫做線性表的長度,用 n表示(n>=0)。當 n=0時,表示線性表是一個空表,即表中不包含任何資料元素。 線性表中的第一個元素叫做表頭元素,最後一

資料結構演算法及其描述

一、演算法及其描述 1、什麼是演算法 資料元素之間的關係有邏輯關係和物理關係,對應的操作有邏輯結構上的操作功能和具體儲存結構上的操作實現。 把 具體儲存結構上的操作實現方法 稱為演算法。 確切地說,演算法是對特定問題求解步驟的一種描述,它是指令的有限序列,其中每一

資料結構什麼是資料結構

一、什麼是資料結構 1、資料結構的定義 資料:從計算機的角度來看,資料是所有能被輸入到計算機中且能被計算機處理的符號的集合。它是計算機操作的物件的總稱,也是計算機處理資訊的某種特定的符號表示形式(二進位制碼的抽象表示?)。 資料元素:資料元素是資料中的一個個體

php7新特性面向物件部分

1)、PHP 7 支援new class 來例項化一個匿名類這可以用來替代一些"用後即焚"的完整類定義。 2)、Closure::call():將一個閉包函式動態繫結到一個新的物件例項並呼叫執行該函式 3)、use:可以使用一個 use 從同一個 namespace 中匯入類、函

再談資料結構棧和佇列

1 - 前言 棧和佇列是兩種非常常用的兩種資料結構,它們的邏輯結構是線性的,儲存結構有順序儲存和鏈式儲存。在平時的學習中,感覺雖然棧和佇列的概念十分容易理解,但是對於這兩種資料結構的靈活運用及程式碼實現還是比較生疏。需要結合實際問題來熟練佇列和棧的操作。 2 - 例題分析 2.1

Cris 的Python筆記面向物件三大特徵之繼承

文章目錄 1、繼承的特性 2、Python 的多繼承(瞭解) 1、繼承的特性 # 通過繼承可以使得子類很好的複用父類的程式碼,減少冗餘程式碼,同時更加符合現實邏輯(程式設計就是對現實世界的抽象)

Java語言學習面向物件進階

    上篇部落格中我們初步認識了Java面向物件程式設計,下面進一步學習下。     面向物件程式設計三大特性:封裝、繼承、多型。     封裝隱藏了類的內部實現機制,對外界而言它的內部細節是隱藏的,暴露給外界的只是它的訪問方法。

小朋友學資料結構16基於鄰接矩陣的的深度優先遍歷和廣度優先遍歷

觀察下面兩個無向圖: 這兩個圖其實是一樣的,只是畫法不同罷了。第一張圖更有立體感,第二張圖更有層次感,並且把A點置為頂點(事實上圖的任何一點都可以做為頂點)。 一、用陣列來存放頂點 vexs[0] = ‘A’ vexs[1] = ‘B’ vexs[2] = ‘C’ ve

小朋友學資料結構13斐波契那查詢

《大話資料結構》第八章8.4節介紹了斐波契那查詢。 斐波那契查詢的理解難點就一個:為什麼需要把陣列長度擴充到f[k]-1而不是f[k]或者f[k+1]? 這是為了能正確遞迴計算mid值,看下圖可發現 f[k]-1

資料結構1順序查詢之C語言實現

#include <stdio.h> #include <stdlib.h> /** 順序查詢: 無序; */ void mainSS() { int num[]={0,1,2,38,99,56,67,87,55,26}; int f

胡八一之Java面向物件的陷阱

一、instanceof的陷阱: 如果前面運算元的編譯型別與後面的型別沒有任何關係,那麼編譯將不通過。例如: String a ="aaa"; System.out.println("a是否屬於MATH的型別:"+(a.instanceof Math)); Stri

資料結構C++順序表的實現

包含取值、查詢、插入、刪除等功能:  #include <iostream> using namespace std; typedef int ElemType; //定義 #define MAXSIZE 100 typedef struct {ElemTyp

python快速學習系列6面向物件程式設計OOP

一、面向物件程式設計: 1.比設計模式更重要的是設計原則: 1)面向物件設計的目標: ·可擴充套件:新特性很容易新增到現有系統中,基本不影響系統原有功能 ·可修改:當修改某一部分程式碼時,不會影響到其他不相關的部分 ·可替代:用具有相同介面的程式碼去替換系統中某一部分程式碼時,系統不受影

再談資料結構排序與查詢

1 - 引言 雖然C++中的STL庫中提供了許多排序和查詢的方法。但是我們還是需要了解一下排序和查詢內部的原理,下面讓我們學習一下各類排序與查詢演算法 2 - 歸併排序 第一種高效的排序演算法是歸併排序,按照分治三步法,對歸併排序演算法介紹如下: 劃分問題:把序列分成

C++自定應執行緒安全資料結構1

執行緒安全的棧 該執行緒安全棧的作用是,允許多個執行緒對棧進行操作,不必再棧上進行加鎖,而是棧本身內部封裝了鎖的機制。操作的本身不是並行化的,因為不可能同時對棧既新增資料,又取出資料;其真正的意義是多個執行緒訪問時,避免上述不安全的情況發生。 #include <excep