1.单向,不带头,非循环(常用,head一直在变)
class ListNode{
public int val;
public ListNode next;
public ListNode (int val){
this.val=val;
}
}
public class MyLinkedList {
public ListNode head;
public void createList(){
ListNode listNode1=new ListNode(1);
ListNode listNode2=new ListNode(22);
ListNode listNode3=new ListNode(33);
listNode1.next=listNode2;
listNode2.next=listNode3;
this.head=listNode1;
}
public void play(){
while (this.head!=null){
//这里this。head指的是head的地址不为空
//这里如果换成this.head.next!=null,则是head的下一个节点不为空,会把最后一个节点少打印
System.out.println(this.head.val);//这里打印的是head的值。listnode.head值不为空,但地址为空
this.head=this.head.next;
}
}
}
这里打印完之后,head就不知道指向哪里了,只能使用一次,所以head不应该动,应该改为
public void play(){
ListNode cur=this.head;
while (cur!=null){
System.out.println(cur.val);
cur=cur.next;
}
}
2.单向,带头,非循环(简单,傀儡节点)
3.双向,不带头,循环
4.双向,带头,循环
在链表里找到需要的节点:
public boolean contains(int num){
ListNode cur=this.head;
while (cur!=null){
if(num== cur.val){
System.out.println("successful!");
return true;
}
cur=cur.next;
}
return false;
}
得到单链表的长度:
public int size(){
int count=0;
ListNode cur=this.head;
while (cur!=null){
count++;
cur=cur.next;
}
return count;
}
头插法:
public void addFirst(int data){
ListNode node=new ListNode(data);
node.next=this.head;
this.head=node;
}
尾插法:
cur和node都是指针。node.next==null就是尾插
public void addLast(int data){
ListNode node=new ListNode(data);
ListNode cur=this.head;
if(this.head==null){
this.head=node;
}else {
while (cur.next!=null){
cur=cur.next;
}
cur.next=node;
}
}
任意位置插入:第一个数据节点下标为0
node.next=cur.next
cur.next=node;
public ListNode findIndex(int index){
ListNode cur=this.head;
while (index-1!=0){
cur=cur.next;
index--;
}
return cur;
}
public void addIndex(int index,int data){
if (index == 0) {
addFirst(data);
return;
}
if (index == size()) {
addLast(data);
return;
}
if(index<0&&index>size()){
System.out.println("位置不合法");
return;
}
ListNode node=new ListNode(data);
ListNode cur=findIndex(index);
node.next=cur.next;
cur.next=node;
}
删除查找到关键字的第一个元素:
Listnode del=cur.next;(当前节点的下一个节点)
cur.next=del.next;
删除查找到关键字的所有元素:
链表反转:
public ListNode reverseList(){
ListNode cur=this.head;
ListNode prev=null;
ListNode curNext=null;
while (cur!=null){
curNext=cur.next;
cur.next=prev;
prev=cur;
cur=curNext;
}
return prev;
}
public void play2(ListNode newhead) {
ListNode cur = newhead;
while (cur != null) {
//这里this。head指的是head的地址不为空
//这里如果换成this.head.next!=null,则是head的下一个节点不为空,会把最后一个节点少打印
System.out.println(cur.val);//这里打印的是head的值。listnode.head值不为空,但地址为空
cur = cur.next;
}
}
这里之所以又定义了打印函数,是因为之前的play()函数是从头head向后打印,但是现在的链表head向后是空的,所以如果用原函数只能打印head的值,因此要再定义一个打印函数。
ListNode ret =myLinkedList.reverseList();
myLinkedList.play2(ret);