1.链表的增加
1.1 链表头部增加addFirst(int val)
- 先创建节点 Node node = new node(val);
- 判断头部是否为空,若为空,head=node;头部不为空,让新建的节点指向头部,node.next=head;头指针再指向新建节点head=node;
注意:如果不清除指向的先后顺序,可以画图帮助判断。如若各种指向顺序都不行,建立临时变量
public void addFirst(int val){
// 先创建需要挂载的车厢节点
Node node =new Node(val);
// 判断火车头部是否为空
if (head==null){
head=node;
}
// 火车有节点,要将当前新车厢挂载到火车头节点上
else{
// 新车厢指向head头节点
node.next=head;
// 新的头节点再指向之前的头节点
head=node;
}
size++;
}
1.2 链表中间位置插入addIndex(int index,int val)
- 首先判断索引的合法性(index<0 || index>size)非法
- 若index=0为头部插入
- index在中间位置(核心是找到插入位置的前驱节点)
例如将7插入到index为1的位置,先让7指向插入位置,再让它的前驱节点指向它。
前驱节点怎样找?
用for循环遍历找到prev位置
public void addIndex(int index,int val){
// 判断合法性
if (index<0 || index>size){
System.out.println("error");
return;
}
if (index==0){
addFirst(val);
return;
}
// 插入元素,先创建
Node node =new Node(val);
// 找插入位置的前驱节点,先让前驱节点为头节点,在遍历向后走index-1步
Node prev=head;
for (int i = 0; i < index-1; i++) {
prev=prev.next;
}
node.next=prev.next;
prev.next=node;
size++;
}
2.链表的查找
- get(int index)返回index位置的元素值
- contains(int value) 查询值为value的元素在单链表中是否存在,存在返回true,否则返回false;
2.1 get(int index)
先判断index合法性(index<0 || index>=size)非法,此处index不能=size,因为size位置无元素
public int get(int index){
// 合法性校验 rangecheck(index)为index合法性检测的方法
if (rangecheck(index)){
Node node=head;
// 规定了node节点走了多少步
for (int i = 0; i < index; i++) {
node=node.next;
}
return node.val;
}else{
System.out.println("error");
return -1;
}
}
2.2 contains(int value)
public boolean contains(int val){
Node temp=head;
while(temp!=null){
if (temp.val==val){
return true;
}
temp=temp.next;
}
return false;
}
3.链表的修改set(int index,int newval)
// 修改链表index位置的元素值,返回修改前的值
public int set(int index,int newval){
if (rangecheck(index)){
Node node=head;
for (int i = 0; i < index; i++) {
node=node.next;
}
int oldval=node.val;
node.val=newval;
return oldval;
}else{
System.out.println("error");
return -1;
}
}
4.链表的删除
4.1 利用索引删除链表元素
例如删除3这个节点,先让3的前驱节点指向3的下一个节点,再让3指向5的线断掉
public void removeindex(int index){
if (rangecheck(index)){
// 删除头节点
if (index==0){
Node temp=head;
head=head.next;
temp.next=null;
size--;
}else{
// index是中间位置
// 找到待删除节点的前驱节点
Node prev =head;
for (int i = 0; i < index-1; i++) {
prev=prev.next;
}
// 待删除节点
Node cur=prev.next;
prev.next=cur.next;
cur.next=null;
size--;
}
}
}
// 删除头部
public void removeFirst(){
removeindex(0);
}
// // 删除尾部
public void removeLast(){
removeindex(size-1);
}
4.2 利用元素值删除链表元素
removeValue(int value)
removeValueAll(int value)
public void removeValueOnce(int val){
// 遍历链表找到值为val的节点
// 找到后删除
if (head!=null&&head.val==val){
// 头节点为待删除的节点
Node temp=head;
head=head.next;
temp.next=null;
size--;
}else{
// 头节点不是待删除的节点,此时需要找到待删除节点的前驱节点
Node prev=head;
// 判断前驱节点的下一个节点值是否是val
while(prev.next!=null){
if(prev.next.val==val){
Node cur=prev.next;
// cur是待删除的节点
prev.next=cur.next;
cur.next=null;
size--;
return;
}
prev=prev.next;
}
}
}
public void removeValueAll(int val){
// 头节点就是待删除的节点
while (head!=null&&head.val==val){
head=head.next;
size--;
}
if(head==null){
// 链表中全是待删除的元素
return;
}else{
// head不是待删除的节点
Node prev=head;
while(prev.next!=null){
if (prev.next.val==val){
Node cur=prev.next;
prev.next=cur.next;
cur.next=null;
size--;
}else{
prev=prev.next;
}
}
}
}
5 完整代码
package seqlist;
// 火车类,里面包含多个车厢和第一个车厢的地址
public class SingleLinkedList {
// 车厢的节点个数
private int size;
// 火车头节点
private Node head;
// 火车头部添加元素
public void addFirst(int val){
// 先创建需要挂载的车厢节点
Node node =new Node(val);
// 判断火车头部是否为空
if (head==null){
head=node;
}
// 火车有节点,要将当前新车厢挂载到火车头节点上
else{
// 新车厢指向head头节点
node.next=head;
// 新的头节点再指向之前的头节点
head=node;
}
size++;
}
public void addIndex(int index,int val){
// 判断合法性
if (index<0 || index>size){
System.out.println("error");
return;
}
if (index==0){
addFirst(val);
return;
}
// 插入元素,先创建
Node node =new Node(val);
// 找插入位置的前驱节点,先让前驱节点为头节点,在遍历向后走index-1步
Node prev=head;
for (int i = 0; i < index-1; i++) {
prev=prev.next;
}
node.next=prev.next;
prev.next=node;
size++;
}
public void addLast(int val){
addIndex(size,val);
}
public int get(int index){
// 合法性校验
if (rangecheck(index)){
Node node=head;
// 规定了node节点走了多少步
for (int i = 0; i < index; i++) {
node=node.next;
}
return node.val;
}else{
System.out.println("error");
return -1;
}
}
public boolean contains(int val){
Node temp=head;
while(temp!=null){
if (temp.val==val){
return true;
}
temp=temp.next;
}
return false;
}
// 修改链表index位置的元素值,返回修改前的值
public int set(int index,int newval){
if (rangecheck(index)){
Node node=head;
for (int i = 0; i < index; i++) {
node=node.next;
}
int oldval=node.val;
node.val=newval;
return oldval;
}else{
System.out.println("error");
return -1;
}
}
// 利用索引删除链表元素
public void removeindex(int index){
if (rangecheck(index)){
// 删除头节点
if (index==0){
Node temp=head;
head=head.next;
temp.next=null;
size--;
}else{
// index是中间位置
// 找到待删除节点的前驱节点
Node prev =head;
for (int i = 0; i < index-1; i++) {
prev=prev.next;
}
// 待删除节点
Node cur=prev.next;
prev.next=cur.next;
cur.next=null;
size--;
}
}
}
// 删除头部
public void removeFirst(){
removeindex(0);
}
// // 删除尾部
public void removeLast(){
removeindex(size-1);
}
//
public void removeValueOnce(int val){
// 遍历链表找到值为val的节点
// 找到后删除
if (head!=null&&head.val==val){
// 头节点为待删除的节点
Node temp=head;
head=head.next;
temp.next=null;
size--;
}else{
// 头节点不是待删除的节点,此时需要找到待删除节点的前驱节点
Node prev=head;
// 判断前驱节点的下一个节点值是否是val
while(prev.next!=null){
if(prev.next.val==val){
Node cur=prev.next;
// cur是待删除的节点
prev.next=cur.next;
cur.next=null;
size--;
return;
}
prev=prev.next;
}
}
}
public void removeValueAll(int val){
// 头节点就是待删除的节点
while (head!=null&&head.val==val){
head=head.next;
size--;
}
if(head==null){
// 链表中全是待删除的元素
return;
}else{
// head不是待删除的节点
Node prev=head;
while(prev.next!=null){
if (prev.next.val==val){
Node cur=prev.next;
prev.next=cur.next;
cur.next=null;
size--;
}else{
prev=prev.next;
}
}
}
}
// 索引合法性检测,改,查,删除
private boolean rangecheck(int index){
// 判断合法性
if (index<0 || index>=size){
return false;
}
else{
return true;
}
}
public String toString(){
String ret="";
// 遍历火车类,从头走到尾
// node暂时存放当前头节点,相当于临时变量
Node node=head;
while(node!=null){
ret += node.val;
ret += "->";
// node走向下一个节点
node =node.next;
}
ret += "NULL";
return ret;
}
}
// 车厢类
class Node{
// 存储每个车厢存放的数据
int val;
//下个车厢的节点
Node next;
public Node(int val) {
this.val=val;
}
}
package seqlist;
public class Test {
public static void main(String[] args) {
// 使用火车类,创建火车类对象
SingleLinkedList singleLinkedList=new SingleLinkedList();
singleLinkedList.addFirst(1);
singleLinkedList.addFirst(3);
singleLinkedList.addFirst(5);
//5->3->1->NULL
System.out.println(singleLinkedList);
singleLinkedList.addIndex(1,10);
//5->10->3->1->NULL
System.out.println(singleLinkedList);
//3
System.out.println(singleLinkedList.get(2));
// false
System.out.println(singleLinkedList.contains(2));
// true
System.out.println(singleLinkedList.contains(10));
//10
System.out.println(singleLinkedList.set(1,7));
//5->7->3->1->NULL
System.out.println(singleLinkedList);
singleLinkedList.removeindex(1);
//5->3->1->NULL
System.out.println(singleLinkedList);
singleLinkedList.removeFirst();
//3->1->NULL
System.out.println(singleLinkedList);
singleLinkedList.removeLast();
//3->NULL
System.out.println(singleLinkedList);
singleLinkedList.addFirst(3);
singleLinkedList.addFirst(5);
//5->3->3->NULL
System.out.println(singleLinkedList);
singleLinkedList.removeValueOnce(3);
//5->3->NULL
System.out.println(singleLinkedList);
singleLinkedList.addFirst(3);
singleLinkedList.addFirst(3);
singleLinkedList.addFirst(3);
singleLinkedList.removeValueAll(3);
//5->NULL
System.out.println(singleLinkedList);
}
}