线性表是n个类型相同的数据元素的有限序列,通常记作(a0,a1,a2…an)、
特点:
接口信息
public interface Liner {
//获取表大小,即数据元素的个数
public int size();
//判断是否为空
public boolean isEmpty();
//获取
public Object get(int i);
//判断线性表是否包括数据元素obj
public boolean contains(Object obj);
//返回数据元素obj在线性表中的序号
public int indexOf(Object obj);
//将元素obj插入到线性表末尾
public void add(Object index);
//将元素obj插入到index位置
public void add(int index,Object obj);
//删除序号为index的元素
public Object remove(int index) ;
}
自定义异常
public class MyArrayIndexOutOfBoundsException extends RuntimeException{
public MyArrayIndexOutOfBoundsException() {
super();
// TODO Auto-generated constructor stub
}
public MyArrayIndexOutOfBoundsException(String message) {
super(message);
// TODO Auto-generated constructor stub
}
}
实现类
import java.util.ArrayList;
import java.util.Arrays;
public class LinerTable implements Liner {
private Object[] elementData;// 底层是个数组,目前未分配长度
private int size;// 不是数组分配的空间,是元素的个数
public LinerTable() {
// 没有指定长度,默认长度4
this(4);
// 没有指定长度,长度是0
// elementData =new Object[]{};
}
/**
* @param initialCapacity
* 指定数组的初始长度
*/
public LinerTable(int initialCapacity) {
// 给数组分配指定的数量的空间
elementData = new Object[initialCapacity];
// 指定顺序表的元素个数
//
}
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
public Object get(int i) {
if (i < 0 || i >= size) {
throw new MyArrayIndexOutOfBoundsException("数组索引越界异常" + i);
}
return elementData[i];
}
public boolean contains(Object obj) {
if (isEmpty()) {
return false;
}
for (int i = 0; i < size; i++) {
if (obj.equals(elementData[i])) {
return true;
}
}
return false;
}
public int indexOf(Object obj) {
for (int i = 0; i < size; i++) {
if (obj.equals(elementData[i])) {
return i;
}
}
return -1;
}
public void add(Object index) {
// 数组满了,扩容
if (size == elementData.length) {
// 船舰一个新的数组,长度旧数组长度的2 倍
Object[] newArr = new Object[elementData.length * 2];
// 将就数组的数据拷贝到新数组
for (int i = 0; i < size; i++) {
newArr[i] = elementData[i];
}
// 让elementData指向新数组
elementData = Arrays.copyOf(elementData, elementData.length * 2);
}
// 给数组赋值
elementData[size] = index;
// 元素加一
size++;
}
public void add(int index, Object obj) {
if (index < 0 || index > size) {
throw new MyArrayIndexOutOfBoundsException("数组索引越界异常" + index);
}
// 数组满了,扩容
if (size == elementData.length) {
// 船舰一个新的数组,长度旧数组长度的2 倍
Object[] newArr = new Object[elementData.length * 2];
// 将就数组的数据拷贝到新数组
for (int i = 0; i < size; i++) {
newArr[i] = elementData[i];
}
// 让elementData指向新数组
elementData = Arrays.copyOf(elementData, elementData.length * 2);
}
// 后裔index及其后面的元素,从最后一个元素开始
for (int j = size; j > index; j--) {
elementData[j] = elementData[j - 1];
}
// 给数组第index位置赋值
elementData[index] = obj;
size++;
}
public Object remove(int index) {
if (index < 0 || index > size) {
throw new MyArrayIndexOutOfBoundsException("数组索引越界异常" + index);
}
return elementData[index];
}
}
测试类
import java.util.ArrayList;
import java.util.List;
public class TestLiner {
public static void main(String[] args) {
List list=new ArrayList();
list.add(111);
list.add(222);
list.add(333);
list.add(444);
list.add(555);
list.add(3,123);
list.remove(3);
System.out.println(list.size());
System.out.println(list.isEmpty());
System.out.println(list.get(3));
System.out.println(list.toString());
}
}
线性表中每个节点有唯一的前驱和后继节点。
设计链式储存结构是,每个逻辑节点储存单独存储,为了表示逻辑关系,增加指针域。
单链表的结点 类
public class Node{
/*private Object data;
private Node next;*/
Object data;
Node next;
public Node() {
}
public Node(Object data) {
super();
this.data = data;
}
public Node(Object data, Node next) {
super();
this.data = data;
this.next = next;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public Node getNext() {
return getNext();
}
public void setNext(Node next) {
this.data = next;
}
}
实现类
import java.util.List;
public class SingleLinkedList implements Liner {
private Node head = new Node();// 头结点,不储存数据,
private int size;// 一共有几个结点
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
public Object get(int i) {
Node p = head;
for (int j = 0; j <= i; j++) {
p = p.next;
}
return p.data;
}
public boolean contains(Object obj) {
if (isEmpty()) {
return false;
}
for (int i = 0; i < size; i++) {
Node p = head;
if (obj.equals(p.data)) {
return true;
}
}
return false;
}
public int indexOf(Object obj) {
for (int i = 0; i < size; i++) {
Node p = head;
if (obj.equals(p.data)) {
return i;
}
}
return -1;
}
public void add(Object index) {
this.add(size, index);
}
public void add(int index, Object obj) {
// 如果i位置错误异常
if (index < 0 || index > size) {
throw new MyArrayIndexOutOfBoundsException("数组指针越界异常" + index);
}
// 找到前 一个节点,从head节点开始
Node p = head;
for (int j = 0; j < index; j++) {
p = p.next;
}
// 暂时创建一个节点
Node newNode = new Node();
newNode.data = obj;
// 指明新结点的直接后继结点
newNode.next = p.next;
// 指明新结点的直接前驱节点
p.next = newNode;
size++;
}
//头结点删除
public Object removeFirst(){
Node temp = head;//移动指针
if(temp == null){
//头指针为空的情况
System.out.println("这是一个空链表");
}else{
Node removeNode = temp;//头指针不为空,指向的结点即为第一个结点,也就是删除结点。定义这个变量是为存储删除的值
temp = temp.next;//指针移动,指向删除结点的后一个结点
head = temp;//把头指针指向删除结点的后一个结点
size--;
return removeNode.data;//把删除结点的值返回
}
return null;
}
//尾结点删除
public Object removeLast(){
Node temp = head;//定义一个临时指针,先指向头指针
if(temp == null){
//头指针
System.out.println("这是一个空链表");
}else{
Node currentNode = temp.next;//定义一个当前指针,把它作为移动指针。
while(currentNode.next != null){
//循环遍历指针
temp = currentNode;//临时指针指向当前指针,即存储当前结点的值。
currentNode = currentNode.next;//当前指针的移动
}
temp.next = null;//到了这里,说明当前currentNode.next==null的,即currentNode是没有后继结点了,而他就是要被删除的结点。把它前一个结点的指针域赋值为空,不指向它,那它不就删除了。
size--;
return currentNode.data;//把删除结点的值返回
}
return null;
}
//删除指定的序号的结点
public Object remove(int index){
Node temp = head;//定义临时指针
if(temp == null){
//头指针为空
System.out.println("这是一个空链表");
}else{
Node currentNode = temp.next;//定义一个当前指针的变量
int i = 1;//定义一个记录位置的变量
if(index<1 || index>size+1){
System.out.println("删除位置不合理");
}
while(currentNode.next!=null){
if(index == i++){
temp = currentNode;//把当前结点的值即要删除的结点存储到temp临时指针中。目的是要把它存储的值返回回来。
currentNode = currentNode.next;
size--;
return temp.data;
}
currentNode = currentNode.next;
}
}
return null;
}
/*public Object remove(int index) {
if(index<1||index>size+1){
throw new MyArrayIndexOutOfBoundsException("位置不合法");
}
return index;
}
*/
@Override
public String toString() {
if (size == 0) {
return "[]";
}
StringBuilder builder = new StringBuilder("[");
Node p = head;
for (int i = 0; i < size; i++) {
if (i != size - 1) {
builder.append(p.data + ",");
} else {
builder.append(p.data);
}
}
builder.append("]");
return builder.toString();
}
}
测试类
import java.util.List;
public class TestSingleLinkedList {
public static void main(String[] args) {
SingleLinkedList list= new SingleLinkedList();
list.add(111);
list.add(222);
list.add(333);
list.add(454);
list.add(555);
list.add(5,123);
list.remove(3);
System.out.println(list.size());
System.out.println(list.isEmpty());
System.out.println(list.get(2));
System.out.println(list.toString());
}
}