1.2 单链表SingleLinkedList实现

这篇博客介绍了如何在Java中创建一个单链表节点,并详细讲解了如何根据节点值和索引进行删除操作。文章通过实例代码演示了toString方法的重写以及在删除节点时遇到的问题和解决方案,提供了完整的链表操作代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

新建一个节点,把element传进去

new ListNode(element);

它成为一个新的节点,这样子它就具备数据,但是next为空

(next现在是空指针,没有指向任何东西)

@Override
public void add(Object element) {
	if(first==null) {
		first=new ListNode(element);
		last=first;
	}else {
		last.next=new ListNode(element);
		//此时的last不再是上一次的last,last应该指向最后这个新增的这个
		last=last.next;
        //一种更替,修改last指针位置,指向原来的下一个节点(自己是倒数第二了,指针要后移一个,让last明正言顺)
	}		
}

接下来重写一下toString方法:

【有缺陷写法】
while(p.data!=null) {
	sb.append(p.data).append(",");
	p=p.next;
}

这个while是有问题的,否则最后一个元素打不出来
当前情况下p已经是最后一个元素了,等于p.next ,它自己就为空了
所以while就退出了
【正确写法】
@Override
public String toString() {
	StringBuilder sb=new StringBuilder("[");
	ListNode p=first;
	while(p!=null) {//一个经典的写法
		sb.append(p.data).append(",");//把p和first先复制一份,看看它有没有next,如果没有next,就不往下移动了
		p=p.next;//有的话:p=p.next 逐步往后移  p已经是最后一个元素了
	}
	sb.append("]");
	return sb.toString();
}

【此时熟悉一下新建的测试方法】
@Test
public void testAdd() {
    //添加balabala
}

@Test
public void testAdd() {
	SingleLinkedList list=new SingleLinkedList();
	list.add("a");
	list.add("b");
	list.add("c");
	list.add("d");
	list.add("e");
	System.out.println(list);
}

但是测试后:[a,b,c,d,e,]

这个逗号还是让人不爽,则再次改:

@Override
public String toString() {
	StringBuilder sb=new StringBuilder("[");
	ListNode p=first;
	while(p!=null) {//一个经典的写法
		sb.append(p.data);//把p和first先复制一份,看看它有没有next,如果没有next,就不往下移动了
		if(p.next!=null)
			sb.append(",");
		p=p.next;//有的话:p=p.next 逐步往后移  p已经是最后一个元素了
	}
	sb.append("]");
	return sb.toString();
}

@Override
public void delete(Object element) {
	ListNode p=first;//头节点
	ListNode pre=null;//(pre一开始可以定义为null,first的前驱是空的,是没有的
	while(p!=null) {
		if(p.data.equals(element)) {//说明找到元素了,要进行删掉
			if(p==first)
				first=first.next;//first往后挪一下<=>删掉第一个元素
			else
				pre.next=p.next;//跨过p
            (1)
		}
		pre=p;
		p=p.next;
	}
}
//这个做法有点水,不好理解,直接去下一个链接

 (1)处若不加 break;

则删除的是所有值为value的元素

若加上,就第一个

链表节点的删除操作_快支棱起来!的博客-优快云博客

根据索引值删元素:加一个计数器

@Override
public void delete(int index) {
	int i=0;
	ListNode pre=null;
	ListNode p=first;//复制下头指针
	
	while(p!=null){
		if(i==index) {
			if(p==first)
				first=first.next;
			else
				pre.next=p.next;
			break;
		}
		pre=p;
		p=p.next;
		i++;//i代表的是指针指向节点的索引  开始p指向first,索引是0;p后移,i变成1;
	}
}

两个删除有相似之处:模板


@Override
public void update(int index, Object newElement) {
    if(index<0||index>index){return;}//啥也不干
	int i=0;ListNode p=first;
	while(p!=null){
		if(i==index) {
			if(p==first)
				p.data=newElement;
            }
    		p=p.next;
		    i++;
		}

@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 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;
		}
		p=p.next;
		i++;
	}
	return null;//没找到
}
@Override
public int indexOf(Object element) {
	int i=0;
	ListNode p=first;		
	while(p!=null){
		if(p.data.equals(element)) {
			return i;
		}
		p=p.next;
		i++;
	}
	return -1;//没找到
}

全代码:

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)) {
        if (p == first)
          first = first.next;
        else
          pre.next = p.next;
        size--;
        break;//注意这里
      }
      pre = p;
      p = p.next;
    }
  }

  @Override
  public void delete(int index) {
    if (index < 0 || index >= size) {
      return;//啥也不干
    }
    int i = 0;//指针指向的节点的索引
    ListNode p = first;
    ListNode pre = null;

    while (p != null) {
      if (i == index) {
        if (p == first)
          first = first.next;
        else
          pre.next = p.next;
        break;//注意这里
      }
      pre = p;
      p = p.next;
      i++;
    }
    size--;
  }

  @Override
  public void update(int index, Object newElement) {
    if (index < 0 || index >= size) {
      return;//啥也不干
    }
    int i = 0;//指针指向的节点的索引
    ListNode p = first;

    while (p != null) {
      if (i == index) {
        p.data = newElement;
      }
      p = p.next;
      i++;
    }
  }

  @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 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;
      }
      p = p.next;
      i++;
    }
    return null;
  }

  @Override
  public int indexOf(Object element) {
    int i = 0;//指针指向的节点的索引
    ListNode p = first;

    while (p != null) {
      if (p.data.equals(element)) {
        return i;
      }
      p = p.next;
      i++;
    }
    return -1;
  }

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder("[");
    ListNode p = first;
    while (p != null) {
      sb.append(p.data);
      if (p.next != null)
        sb.append(",");
      p = p.next;
    }
    sb.append("]");
    return sb.toString();
  }

  @Override
  public boolean hasNext() {
    return false;
  }

  @Override
  public Object next() {
    return null;
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值