最基本数据结构—"线性表"
表结构是一种最基本的数据结构,最常见的实现是数组,几乎在每个程序每一种开发语言中都提供了数组这个顺序存储的线性表结构实现.
什么是线性表?
由0个或多个数据元素组成的有限序列.如果没有元素,称为空表,如果存在多个元素,则第一个元素无前驱,最后一个元素无后继,其他元素元素都有且只有一个前驱和后继.线性表是n个类型相同数据元素的有限序列。
a. 相同数据类型
b.序列(顺序表)唯一的前驱,后继
c.有限
1.线性表接口定义如下:
public interface Sequence {
/**
* 向线性表中添加元素
* @param data 要存储的元素
*/
void add(Object data);
/**
* 线性表中删除元素
* @param index 要删除的元素下标
* @return 是否删除成功
*/
boolean remove(int index);
/**
* 在线性表中查找指定索引的元素
* @param index 要查找的索引
* @return
*/
Object get(int index);
/**
* 判断线性表中是否有指定元素
* @param data 要查找的元素内容
* @return
*/
boolean contains(Object data);
/**
* 修改线性表中指定索引的内容
* @param index 要修改的元素下标
* @param newData 修改后的内容
* @return
*/
Object set(int index,Object newData);
/**
* 返回当前线性表元素个数
* @return
*/
int size();
/**
* 直接清空线性表内容
*/
void clear();
/**
* 将线性表转为数组
* @return
*/
Object[] toArray();
}
动态数组实现
package data.Link;
import data.Link.Bittech;
import java.util.Arrays;
public class BittechArrayImpl implements Bittech {
// 存放元素的对象数组
private Object[] elementData;
// 默认容量
private final static int DEFAULT_CAPACITY=10;
// 存放的元素个数
private int size;
// 线性表的最大容量
private final static int MAX_CAPACITY=Integer.MAX_VALUE-8;
public BittechArrayImpl() {
this.elementData = new Object[DEFAULT_CAPACITY];
// 初始化存储元素数组,初始化为10
}
public BittechArrayImpl(int capacity){
if(capacity>0){
this.elementData=new Object[capacity];
}
}
@Override
public void add(Object data) {
// 首先判断元素是否越界,如果越界先进扩容,而后存储元素
ensureCapacityInternal(size+1);
elementData[size++]=data;
}
@Override
public boolean remove(int index) {
rangeCheck(index);
int moveSteps=size-index-1;
if(moveSteps>0){
System.arraycopy(elementData,index+1,elementData,index,moveSteps);
}
// 数组的最后一个元素
elementData[--size]=null;
return true;
}
public Object get(int index) {
rangeCheck(index);
return elementData[index];
}
@Override
public boolean contains(Object data) {
// 判断之前是否有指定内容
if(data==null){
for(int i=0;i<size;i++){
if(elementData[i]==null){
return true;
}
}
}else
for(int i=0;i<size;i++){
if(data.equals(elementData[i])){
return true;
}
}
return false;
}
@Override
public Object set(int index, Object newData) {
rangeCheck(index);
// 取得修改前的内容
Object oldData=elementData[index];
elementData[index]=newData;
return oldData;
}
@Override
public int size() {
return this.size;
}
@Override
public void clear() {
for(int i=0;i<size;i++){
elementData[i]=null;
}
this.size=0;
}
@Override
public Object[] toArray() {
return this.elementData;
}
private void ensureCapacityInternal(int cap){
if(cap-elementData.length>0){
// 扩容策略
grow(cap);
}
}
private void grow(int cap){
int oldCap=elementData.length;
int newCap=oldCap<<1;
if (cap-newCap>0){
newCap=cap;
}
if(newCap-MAX_CAPACITY>0)
//数组扩容
elementData= Arrays.copyOf(elementData,newCap);
}
private void rangeCheck(int index){
if(index<0||index>=size){
throw new ArrayIndexOutOfBoundsException("索引非法");
}
}
}
单链表实现
package data.Link;
import data.Link.Bittech;
public class BittechLinkedImpl implements Bittech {
//虚拟头节点,不存储元素,专门作为头节点使用
private Node dummyHead;
private int size;
public BittechLinkedImpl() {
this.dummyHead = new Node(null,null);
}
private class Node {
Object data;
Node next;
public Node(Object data, Node next) {
this.data = data;
this.next = next;
}
public Node(Object data) {
this.data = data;
}
}
@Override
public void add(Object data) {
addLast(data);
}
@Override
public boolean remove(int index) {
rangeCheck(index);
Node prev = dummyHead;
for (int i = 0;i < index;i++) {
prev = prev.next;
}
// 取得当前节点
Node cur = node(index);
prev.next = cur.next;
// 清空当前节点
cur.next = cur = null;
size --;
return true;
}
@Override
public Object get(int index) {
rangeCheck(index);
// 取得相应index的Node节点
Node node = node(index);
return node.data;
}
@Override
public boolean contains(Object data) {
Object[] datas = toArray();
if (data == null) {
for (int i = 0;i < datas.length;i++) {
if (datas[i] == null) {
return true;
}
}
}else {
for (int i = 0;i < datas.length;i++) {
if (data.equals(datas[i])) {
return true;
}
}
}
return false;
}
@Override
public Object set(int index, Object newData) {
rangeCheck(index);
// 取得相应index的Node节点
Node node = node(index);
Object oldData = node.data;
node.data = newData;
return oldData;
}
@Override
public int size() {
return size;
}
@Override
public void clear() {
for (Node node = dummyHead.next;node != null;) {
node.data = null;
Node temp = node.next;
node.next = null;
node = temp;
size--;
}
}
@Override
public Object[] toArray() {
// 遍历节点将数据存放到对象数组中
Object[] datas = new Object[size];
int i = 0;
for (Node temp = dummyHead.next;temp!=null;temp = temp.next) {
datas[i++] = temp.data;
}
return datas;
}
// 在任意位置插入元素
public void add(int index,Object data) {
rangeCheck(index);
Node prev = dummyHead;
for (int i = 0;i < index;i++) {
prev = prev.next;
}
Node newNode = new Node(data);
newNode.next = prev.next;
prev.next = newNode;
size++;
}
private void addFirst(Object data) {
add(0,data);
}
private void addLast(Object data) {
add(size,data);
}
// 判断index是否合法
private void rangeCheck(int index) {
if (index < 0 || index > size) {
throw new IndexOutOfBoundsException("Illegal Index!");
}
}
// 找到index的当前节点
private Node node(int index) {
Node cur = dummyHead.next;
for (int i = 0;i < index;i++) {
cur = cur.next;
}
return cur;
}
}
双链表实现
package data.Link;
import data.Link.Bittech;
public class DoubleLinkedListImpl implements Bittech {
private Node head;
private Node tail;
private int size;
private class Node {
Node prev;
Object data;
Node next;
public Node(Object data) {
this.data = data;
}
public Node(Node prev, Object data, Node next) {
this.prev = prev;
this.data = data;
this.next = next;
}
}
/**
* 尾插法
* @param data 要存储的元素
*/
@Override
public void add(Object data) {
// 产生新节点,尾插入链表中
Node newNode = new Node(tail,data,null);
if (head == null) {
head = newNode;
}else {
tail.next = newNode;
}
tail = newNode;
size++;
}
@Override
public boolean remove(int index) {
rangeCheck(index);
// 要删除的节点
Node cur = node(index);
Node prev = cur.prev;
Node next = cur.next;
// 要删除的是头结点
if (prev == null) {
head = cur.next;
}
// 存在前驱节点
else {
prev.next = cur.next;
cur.prev = null;
}
// 要删的是尾节点
if (next == null) {
tail = cur.prev;
}else {
next.prev = cur.prev;
cur.prev = null;
}
size--;
return false;
}
@Override
public Object get(int index) {
rangeCheck(index);
// 取得指定位置Node
return node(index).data;
}
@Override
public boolean contains(Object data) {
return false;
}
@Override
public Object set(int index, Object newData) {
rangeCheck(index);
// 取得指定位置Node
Node node = node(index);
Object oldData = node.data;
node.data = newData;
return oldData;
}
@Override
public int size() {
return size;
}
@Override
public void clear() {
for (Node temp = head;temp!=null;) {
Node next = temp.next;
temp.prev = temp.next = null;
temp.data = null;
temp = next;
size--;
}
}
@Override
public Object[] toArray() {
Object[] data = new Object[size];
int i = 0;
for (Node temp = head;temp != null;temp = temp.next) {
data[i++] = temp.data;
}
return data;
}
private void rangeCheck(int index) {
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException("Illegal Index!");
}
}
private Node node(int index) {
// 此时要查找的节点在中间位置左边
if (index < (size >> 1)) {
Node temp = head;
for (int i = 0;i < index;i++) {
temp = temp.next;
}
return temp;
}else {
Node temp = tail;
for (int i = size - 1;i > index;i--) {
temp = temp.prev;
}
return temp;
}
}
}