首先我说下我自己对链表的理解
链表它就相当于一个火车 ,火车有很多节车厢(车厢就相当于链表中的节点);
一个车厢包括 车厢里面的人或者东西 还有和下一节车厢相连的挂钩
那么这就很形象的说明了 链表的每个节点 包括 data 和 next (数据和指向下一个节点的指针)
单链表图示:
单链表的实现:
/*
* 线性表的接口的定义
*/
public interface MyList {
/*
* 增加元素
*/
void add(Object element);
/*
* 删除元素
*/
void delete(Object element);
//删除指定索引的元素
void delete(int index);
/*
* 更新元素
* 修改指定索引的值为新的element
*/
void update(int index,Object NewElement);
/*
* 查询元素
*/
boolean contains(Object target);
//查找element元素的索引 如果没有返回-1
int indexOf(Object element);
//返回指定索引的元素
Object at(int index);
}
public class ListNode {
Object data;
ListNode next;
public ListNode(Object data){
this.data = data;
}
}
/*
* 单链表的实现
*/
public class SingleLinkedList implements MyList {
private ListNode first; //头节点
private ListNode last; //最后的节点
private int size;
//向链表中添加一个节点
@Override
public void add(Object element) {
//先判断链表是否为空
if(first == null)
{
first = new ListNode(element);
last = first;
}
else{
//头节点不为空的话
last.next = new ListNode(element);
last = last.next;
}
size++;
}
//删除节点
@Override
public void delete(Object element) {
ListNode p = first;
ListNode pre = null; //记录当前访问节点的前一个节点
//遍历链表
while(p!=null)
{
if(p.data.equals(element))
{
//需要判断p是不是头节点
if(p == first)
{
//直接将头节点指向下一个结点 就相当于删除了头节点
first = first.next;
}
else
{
//如果当前节点不是头节点并且是要删除的结点的话
pre.next = p.next;
}
break;
}
//如果当前节点不是要删除的结点的话 那么需要记录当前节点
pre= p;
//然后继续向后遍历
p = p.next;
}
size--;
}
//通过给定的索引值去删除节点
//需要考虑的一个问题就是 一直删的话 会不会出现越界问题
@Override
public void delete(int index) {
//先判断索引值 是否在范围内 如果不在话 直接return
if(index<0||index>=size)
{
return;
}
ListNode p = first;
ListNode pre = null;
int i = 0; //和每个结点相对应
while(p != null)
{
if(i == index)
{
if(p == first)
{
first = first.next;
}
else{
pre.next = p.next;
}
break;
}
i++;
pre = p;
p = p.next;
}
size--;
}
@Override
public void update(int index, Object NewElement) {
//先判断索引值 是否在范围内 如果不在话 直接return
if(index<0||index>=size)
{
return;
}
ListNode p = first;
int i = 0; //和每个结点相对应
while(p != null)
{
if(i == index)
{
p.data = NewElement;
break;
}
i++;
p = p.next;
}
}
@Override
public boolean contains(Object target) {
ListNode p = first;
while(p != null)
{
if(p.data.equals(target))
{
return true;
}
p = p.next;
}
return false;
}
@Override
public int indexOf(Object element) {
ListNode p = first;
int i = 0;
while(p!=null)
{
if(p.data.equals(element))
{
return i;
}
i++;
p = p.next;
}
return -1;
}
@Override
public Object at(int index) {
if(index<0||index>=size)
{
return null;
}
int i = 0;
ListNode p = first;
while(p!=null)
{
if(i == index)
{
return p.data;
}
i++;
p = p.next;
}
return null;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("[");
//遍历 首先需要将头节点先复制一下 不能直接将头节点拿过来使用
ListNode p = first;
while(p!=null)
{
sb.append(p.data);
p = p.next;
if(p!=null)
{
sb.append(",");
}
}
sb.append("]");
return sb.toString();
}
}
测试:
public class Test {
public static void main(String[] args) {
SingleLinkedList list = new SingleLinkedList();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
list.add("e");
System.out.println(list.toString());
list.delete("c");
System.out.println(list.toString());
list.delete(2);
System.out.println(list.toString());
list.update(0, "w");
System.out.println(list.toString());
System.out.println(list.contains("b"));
System.out.println(list.contains("j"));
System.out.println(list.at(0));
System.out.println(list.indexOf("b"));
System.out.println(list.indexOf("j"));
}
}