MyFirstList接口
package dataStructure.myFirstList;
//基于链表结构存取元素的API接口定义
public interface MyFirstList<E> {
void add(E element); //向单向链表之中添加元素
E get(int index); //根据输入的索引值得到需要的元素 返回的是添加的元素
int size(); //获取元素之中的元素
E remove(int index); //根据输入的索引值删除不需要的元素 返回的是删除的元素
}
MyfirstList2类(MyFirstList接口的实现类)
package dataStructure.myFirstList;
//链表结构 单向链表
/*
* 链表结构的定义:
* 链表由许多节点构成 每个节点都由两个部分组成
* 数据部分:保存每个节点的数据
* 地址部分:
*
* 单向链表/双向链表/双向循环链表
*
* 链表的特点:
* 节点在存储器中的位置不是一致的,即逻辑上存在物理空间不是连贯的
* 访问时只能通过头节点或者没节点进入链表
* 所以查询数据时,需要遍历着找数据
* 扫描其余节点:寻找第一个节点和最后一个节点所花费的时间不等
*
* 链表的优缺点:
* 优点:
* 数据元素的个数可以自由扩充,插入,删除等才做不必移动的数据,只需修改链接地址
* 修改效率较高
* 缺点:
* 必须采用顺序存储,即存取数据元素时,只能按链表的顺序进行访问,访问节点效率低
*
* 单向链表结构
* 单向链表的定义:
* 单向链表(单链表)是链表的一种,其特点是链表的连接方向是单向的,对链表的访问要通过从头部开始顺序读取
*
* */
public class MyFirstList2<E> implements MyFirstList<E> {
private Node head; //存放在链表中的头节点
private int size; //记录元素个数
/*定义单向链表中的节点类*/
class Node<E>{
private E item; //存储元素
private Node next; //存储下一个对象的节点地址
//item与next都是形参名称,创建对象时需要传入实际类型的值
Node(E item,Node next){
this.item=item;
this.next=next;
}
}
/*获取为节点对象的前一个节点地址值*/
private Node getTail(){
if (this.head==null){ //判断节点对象是否为空
return null;
}
Node aa=this.head; //此处将head赋给aa
while (true){
if (aa.next==null){
break;
}
aa=aa.next; //aa中保存的是节点对象,可以调用节点的属性next
}
return aa;
}
/*根据输入元素向链表中添加元素*/
@Override
public void add(E element) {
//add()方法中的element元素就是节点中的数据元素
//创建一个对象时,需要向形参中传入具体值,而不是形参名称
Node<E> node=new Node<>(element,null);
Node tail=getTail(); //头一个节点的next值时下一个节点的地址值
if (tail==null){
this.head=node; //此处将创建的节点对象赋给head
}else {
tail.next=node;
}
this.size++;
}
/*校验index合法性*/
private void checkIndex(int index){
if (!(index>=0 && index<this.size)){
throw new IndexOutOfBoundsException("Index "+index+"size"+this.size);
}
}
/*根据位置获取节点*/
private Node getNode(int index){
Node<E> bb=this.head;
for (int i=0;i<index;i++){
bb=bb.next;
}
return bb;
}
/*获取尾结点对象的前一个节点地址值*/
@Override
public E get(int index) {
this.checkIndex(index);
Node<E> node=this.getNode(index);
return node.item;
}
/*获取聊表中元素的个数*/
@Override
public int size() {
return this.size;
}
/*根据索引值移除链表中的元素*/
@Override
public E remove(int index) {
this.checkIndex(index);
Node<E> node=this.getNode(index);
E item=node.item;
if (this.head==node){
this.head=node.next;
}else{
Node<E> temp=this.head;
for (int i = 0; i <index-1; i++) {
temp=temp.next;
}
temp.next=node.next;
}
node.next=null;
this.size--;
return item;
}
public static void main(String[] args) {
MyFirstList2<Object> cc = new MyFirstList2<>();
cc.add("a");
cc.add("b");
cc.add("c");
cc.add("d");
System.out.println(cc.size);//4
System.out.println(cc.get(2));
//b 如果没有重写get,返回的是地址 dataStructure.myFirstList.MyFirstList2$Node@677327b6
System.out.println(cc.remove(1));//b
System.out.println(cc.get(1));
//b 如果没有重写get,返回的是地址 dataStructure.myFirstList.MyFirstList2$Node@677327b6
}
}