java-实现单链表
前言
单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。在单链表中有两种属性第一为数据,第二则是下一个节点的位置。在学习单链表的时候必须要知道什么是节点?什么是指针(java中为引用)什么是指向下一个节点?什么是头节点?什么是尾节点?因为这是我在开始学习单链表的时候一直在纠结的问题,后面把这样的一些问题都搞清楚了自然的就会写了。
一、我在学习单链表的时候解决的上面的提问
1.什么是节点?
- 节点我们可以理解为是用来存数据的对象,多个节点组成了链表,上一个节点中有指针指向下一个节点环环相扣
2.什么是指针(java中为引用)
- 指针指向的是一个地址,就是在栈中储存了对应的堆中的地址,在链表中因为节点与节点之间是不连续的,分配来说是随机的,所以就会在上一个节点中用指针来指向下一个节点的位置。(实在不懂可以百度一下,这里是用我理解的方式说的)
3.什么是指向下一个节点?
- 在上一个节点中会有指针指向下一个节点的位置。
4.什么是头节点?
- 第一个节点,head:这里我们用head来表示
5.什么是尾节点?
- 顾名思义最后一个节点。
二、实现步骤
1.创建一个节点内部类ListNode如下:
static class ListNode{
int val;//类型可以随意更改这里为了方便用了int
ListNode next;
public ListNode(int val) {//构造只有val的有参构造
this.val = val;
}
2.在内部类的外面创建头结点和尾结点以及记录长度得size,并初始化
ListNode head;
ListNode tail;
int size;
public LinkedList(){
head = null;
tail = null;
size = 0;
}
3.创建尾加法(具体说明看代码)
//在尾部加入新的节点
public void append(int number){
ListNode newNode = new ListNode(number);
if (tail == null){
tail = newNode;
}
else {}
tail.next = newNode;
tail = newNode;//尾节点就变成了新加入的节点
size++;
}
4.创建在指定位置加入新节点的方法(这里会在代码中详细讲解后面的删除和更新将会只有代码)
//在指定位置加入新的节点
public void insert(int position,int number){//输入一个新的节点以及要加的值
if (position > size){//比较节点长度大于则返回
return;
}
ListNode newNode = new ListNode(number);//这个时候定义一个新的节点
//头部添加
if (position == 0){//当输入的节点值为0时,在0位置处插入
newNode.next = head;//新的节点里的next指向将会是头结点head
head = newNode;//这个时候新的头节点变成了新的节点(头插法)
if (tail == null){//这个时候再判断尾节点是不是空,是的话刚才插入的节点就只唯一的节点
tail = newNode;//尾节点也是新的节点
}
size++;//数量加1
}//尾部添加
else if (position == size){
this.append(number);//就是上面的尾插法
}
//中间添加
else {
ListNode prev = head;//定义一个节点为头结点
for (int i = 0;i<position-1;i++){
prev =prev.next;//遍历查找position的前一个节点
}
ListNode now = prev.next;//这个新节点是需要插入节点的下一个节点
newNode.next = now;//之前的节点的下一个节点指向将会是prev节点之前的now节点
now = newNode;//now节点被刚才的节点赋值
size++;//数量加1
}
}
5.删除节点
//删除节点
public void delete(int number){
//当删除的是头结点时
if (head != null && head.val==number){
head = head.next;
size--;
if (size == 0){
head = tail;
}
}
else {
ListNode prev = head;//前一个节点
ListNode cur = head;//当前节点
while (prev != null && cur != null){
if (cur.val == number){
if (cur == tail){
tail = prev;
}
prev.next = cur.next;
size--;
return;
}
//循环遍历
prev = cur;
cur = cur.next;
}
}
}
6.更新节点
//更新节点
public int update(int oldnumber,int newnumber){
ListNode now = head;
for (int i = 0;now != null;i++){
if (now.val == oldnumber){
now.val = newnumber;
return i;
}
now = now.next;
}
return -1;
}
7.查找节点
//查找节点
public int search(int number){
ListNode now = head;
for (int i= 0;now != null;i++){
if (now.val == number){
System.out.println(i);
return i;
}
now = now.next;
}
return -1;
}
8.打印节点
//打印节点
public void printAll(){
ListNode pr = head;
while (pr != null){//只要pr不等于空就打印
System.out.println(pr.val);
pr = pr.next;//打印之后下一个节点位置赋值给pr
}
}
9.代码调度
public static void main(String[] args) {
LinkedList hu = new LinkedList();
hu.insert(0,22);
hu.insert(1,14);
hu.insert(2,89);
hu.append(23);
System.out.println(hu.search(14));
hu.printAll();
hu.delete(23);
hu.printAll();
}
总结
这是我在学习单链表时的代码总结,用来自己忘记时的发散。