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