淺談線性表的原理及簡單實現(xiàn)方法
一、線性表
原理:零個或多個同類數(shù)據(jù)元素的有限序列
原理圖:

特點 :
1、有序性
2、有限性
3、同類型元素
4、第一個元素?zé)o前驅(qū),最后一個元素?zé)o后繼,中間的元素有一個前驅(qū)并且有一個后繼
線性表是一種邏輯上的數(shù)據(jù)結(jié)構(gòu),在物理上一般有兩種實現(xiàn) 順序?qū)崿F(xiàn)和鏈表實現(xiàn)
二、基于數(shù)組的 線性表順序?qū)崿F(xiàn)
原理 : 用一段地址連續(xù)的存儲單元依次存儲線性表數(shù)據(jù)元素。
原理圖:

算法原理:
1、初始化一個定長的數(shù)組空間 elementData[] , size 存儲長度 存儲元素
2、通過索引來快速存取元素
3、通過數(shù)組復(fù)制實現(xiàn)元素的插入和刪除
總結(jié):
1、無需為表示表中元素之間的邏輯關(guān)系增加額外的存儲空間
2、可以快速存取表中任一位置元素
3、插入和刪除需要進行數(shù)組復(fù)制(即大量元素的移動)
4、線性表長度變化較大時,需要頻繁擴容,并造成存儲空間碎片
實現(xiàn)代碼:
接口定義:
package online.jfree.base;
/**
* author : Guo LiXiao
* date : 2017-6-14 11:46
*/
public interface LineList <E>{
/**
* lineList 是否為空
* @return
*/
boolean isEmpty();
/**
* 清空 lineList
*/
void clear();
/**
* 獲取指定位置元素
* @param index
* @return
*/
E get(int index);
/**
* 獲取元素第一次出現(xiàn)的位置
* @param e
* @return
*/
int indexOf(E e);
/**
* 判斷 lineList是否包含指定元素
* @param e
* @return
*/
boolean contains(E e);
/**
* 設(shè)置指定位置數(shù)據(jù),如數(shù)據(jù)已存在 則覆蓋原數(shù)據(jù)
* @param index
* @param e
* @return
*/
E set(int index, E e);
/**
* 移除指定位置元素
* @param index
* @return
*/
E remove(int index);
/**
* 在lineList結(jié)尾插入元素
* @param e
* @return
*/
E add(E e);
/**
* 在index后面插入元素
* @param index
* @param e
* @return
*/
E add(int index, E e);
/**
* 返回lineList長度
* @return
*/
int size();
}
算法實現(xiàn):
package online.jfree.base;
/**
* author : Guo LiXiao
* date : 2017-6-15 13:44
*/
public class OrderedLineList<E> implements LineList<E> {
private static final int INIT_CAPACITY = 10;
private transient E[] elementData;
private transient int elementLength;
private int size;
public OrderedLineList() {
this(0);
}
public OrderedLineList(int initCapacity) {
init(initCapacity);
}
private void init(int initCapacity) {
if (initCapacity >= 0) {
this.elementData = (E[]) new Object[initCapacity];
this.elementLength = initCapacity;
} else {
throw new IllegalArgumentException("Illegal Capacity: " +
initCapacity);
}
this.size = 0;
}
/**
* 擴容
*/
private void dilatation() {
int oldCapacity = this.elementLength;
int newCapacity = oldCapacity;
if (oldCapacity <= this.size) {
newCapacity = oldCapacity + INIT_CAPACITY;
}else if(oldCapacity - INIT_CAPACITY > this.size){
newCapacity = oldCapacity - INIT_CAPACITY;
}
if (oldCapacity != newCapacity){
E[] newElementData = (E[]) new Object[newCapacity];
System.arraycopy(elementData, 0, newElementData, 0, oldCapacity);
this.elementLength = newCapacity;
this.elementData = newElementData;
}
}
/**
* 校驗列表索引越界
* @param index
*/
private void checkCapacity(int index){
if (index > this.size - 1 || index < 0)
throw new IndexOutOfBoundsException(new StringBuffer("[index : ").append(index).append("] , [size : ").append(size).append("] ").toString());
}
@Override
public boolean isEmpty() {
return this.size == 0;
}
@Override
public void clear() {
this.init(0);
}
@Override
public E get(int index) {
this.checkCapacity(index);
return this.elementData[index];
}
@Override
public int indexOf(E e) {
for (int i = 0; i < this.size; i++){
if (e == null && elementData[i] == null || e.equals(elementData[i])){
return i;
}
}
return -1;
}
@Override
public boolean contains(E e) {
return this.indexOf(e) > 0;
}
@Override
public E set(int index, E e) {
this.checkCapacity(index);
this.dilatation();
E oldElement = this.elementData[index];
this.elementData[index] = e;
return oldElement;
}
@Override
public E remove(int index) {
this.dilatation();
E e = elementData[index];
if (index == size - 1) elementData[index] = null;
else {
int length = size - index - 1;
System.arraycopy(elementData, index + 1, elementData, index, length);
}
size --;
return e;
}
@Override
public E add(E e) {
return this.add(size, e);
}
@Override
public E add(int index, E e) {
this.dilatation();
if (index == size) elementData[index] = e;
else {
index++;
int lastLength = size - index;
E[] lastElementData = (E[]) new Object[lastLength];
System.arraycopy(elementData, index, lastElementData, 0, lastLength);
elementData[index] = e;
System.arraycopy(lastElementData, 0, elementData, index + 1, lastLength);
}
size ++ ;
return e;
}
@Override
public int size() {
return this.size;
}
}
以上這篇淺談線性表的原理及簡單實現(xiàn)方法就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java 判斷字符串a(chǎn)和b是否互為旋轉(zhuǎn)詞
本篇文章主要介紹了判斷字符串a(chǎn)和b是否互為旋轉(zhuǎn)詞的相關(guān)知識,具有很好的參考價值。下面跟著小編一起來看下吧2017-05-05
Java通過MyBatis框架對MySQL數(shù)據(jù)進行增刪查改的基本方法
MyBatis框架由Java的JDBC API進一步封裝而來,在操作數(shù)據(jù)庫方面效果拔群,接下來我們就一起來看看Java通過MyBatis框架對MySQL數(shù)據(jù)進行增刪查改的基本方法:2016-06-06
spring整合atomikos實現(xiàn)分布式事務(wù)的方法示例
本文整合了一個spring和atomikos的demo,并且通過案例演示說明atomikos的作用,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-05-05
詳解Springboot整合Dubbo之代碼集成和發(fā)布
本篇文章主要介紹了Springboot整合Dubbo之代碼集成和發(fā)布,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-12-12
java.lang.ClassCastException的問題解決
本文主要介紹了java.lang.ClassCastException的問題解決,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-06-06
Spring Security 使用 OncePerRequestFilter
OncePerRequestFilter是一個過濾器,每個請求都會執(zhí)行一次;一般開發(fā)中主要是做檢查是否已登錄、Token是否過期和授權(quán)等操作,而每個操作都是一個過濾器,下面介紹Spring Security 使用 OncePerRequestFilter 過濾器校驗登錄過期、請求日志等操作方法,感興趣的朋友一起看看吧2024-06-06

