Java中单链表的实现及一些简单链表题运行案例
1.链表类和节点内部类的创建
2.插入节点
3.删除节点
4.获取头节点
5.获取链表长度
6.判断链表是否为空
7.判断链表中某数据是否存在
8.根据索引获取元素
9.用新数据替换指定位置的的数据
10.清空链表
11.获取链表中第k个节点
12.判断两个链表是否相交
13.获取两个相交链表的第一个公共节点
14.判断链表是否有环
15.获取环链表的长度
16.获取环链表的入口节点值
17.方法测试(过程包括创建链表、构造相交链表、环链表等)
public class SingleLinkedList {
//记录节点个数
private int size;
//头节点
private Node head;
class Node{
public int val;
public Node next;
public Node(int x){
this.val=x;
}
}
//在尾部插入节点
public void insertTail(int val){
Node cur=new Node(val);
if(head==null)head=cur;
Node temp=head;
while(temp.next!=null){
temp=temp.next;
}
temp.next=cur;
cur.next=null;
this.size++;
}
//删除某个节点
public Node deleteNode(Node head, int val) {
Node node = head;
//如果第一个节点就是要删除的节点,就直接返回下一节点
if ( node.val == val ) return head.next;
while (node != null && node.next != null) {
//从第二个节点开始判断
if ( node.next.val == val ) {
node.next = node.next.next;
break;
}
node= node.next;
}
size--;
return head;
//从第一个节点开始判断
/* Node node=new Node(0);
node.next=head;
Node cur=node;
while(cur!=null&&cur.next!=null)
{
//从第二个节点开始判断
if(cur.next.val==val)
{
cur.next=cur.next.next;
break;
}
cur=cur.next;
}
return node.next;*/
}
//获取节点个数
public int getSize() {
return size;
}
//获取链表的头节点
public Node getHead() {
return head;
}
//判断链表是否为空
public boolean isEmpty(){
if(this.size==0){
return true;
}else {
return false;
}
}
//判断链表中某一数据是否存在
public boolean contains(int x){
//获取链表的头节点
Node head=getHead();
while(head!=null&&head.next!=null){
if(head.val==x)return true;
head=head.next;
}
return false;
}
//根据索引获取元素
public int get(int index){
if(index>size-1){
System.out.println("超出链表边缘");
return -1;
}
else{
Node head=getHead();
for(int i=0;i<size;i++){
if(i==index)return head.val;
head=head.next;
}
}
return 0;
}
//用新数据替换指定位置的的数据
public void replace(int val,int index){
if(index>size-1){
System.out.println("超出链表边缘");
return ;
}else{
Node head=getHead();
for(int i=0;i<size;i++){
if(i==index) head.val=val;
head=head.next;
}
}
}
//清空链表
public void clear(){
this.head=null;
this.size=0;
}
//获取链表中第k个节点
public Node getKthFromEnd(Node head,int k){
Node fast=new Node(0);
fast=head;
while(fast!=null){
if(k==0) {
head = head.next;
}
else{
k--;
}
fast=fast.next;
}
return head;
}
//反转链表
public Node reverseList(Node head){
if(head==null)return null;
Node cur=null;
while(head!=null){
Node temp=head.next;
head.next=cur;
cur=head;
head=temp;
}
return cur;
}
//判断两个链表是否相交
public boolean isIntersectionNode(Node n1,Node n2){
Node node1=n1,node2=n2;
while (node1!=node2){
node1=node1==null?n2:node1.next;
node2=node2==null?n1:node2.next;
}
if(node1==null)return false;
else
return true;
}
//获取两个相交链表的第一个公共节点
public static Node getIntersectionNode(Node n1,Node n2){
Node node1=n1,node2=n2;
while (node1!=node2){
node1=node1==null?n2:node1.next;
node2=node2==null?n1:node2.next;
}
return node1;
}
//构建一个有环的链表
/* public Node loopList(){
Node cur=head;
while (cur!=null){
cur=cur.next;
}
cur.next=head.next;
return head;
}*/
//判断链表是否有环
public boolean isLoopList(Node head) {
Node slowPointer, fastPointer;
//使用快慢指针,慢指针每次向前一步,快指针每次两步
slowPointer = fastPointer = head;
while (fastPointer != null && fastPointer.next != null) {
slowPointer = slowPointer.next;
fastPointer = fastPointer.next.next;
//两指针相遇则有环
if ( slowPointer == fastPointer ) {
return true;
}
}
return false;
}
//获取环链表的长度,环的长度是第一次相遇时,慢指针走的路程(主要是因为从头节点到环入口点的距离等于相遇节点到尾部节点的距离)
public int loopListLen(Node head) {
Node slowPointer, fastPointer;
int len=0;
//使用快慢指针,慢指针每次向前一步,快指针每次两步
slowPointer = fastPointer = head;
while (fastPointer != null && fastPointer.next != null) {
slowPointer = slowPointer.next;
fastPointer = fastPointer.next.next;
len++;
//两指针相遇则有环
if ( slowPointer == fastPointer ) {
return len;
}
}
//如果不为环,返回-1
return -1;
}
//获取入口节点的值
public int getLoopNode(Node head) {
Node slowPointer, fastPointer;
//使用快慢指针,慢指针每次向前一步,快指针每次两步
slowPointer = fastPointer = head;
while (fastPointer != null && fastPointer.next != null) {
slowPointer = slowPointer.next;
fastPointer = fastPointer.next.next;
//两指针相遇则有环
if ( slowPointer == fastPointer ) {
break;
}
}
slowPointer=head;
while(fastPointer != null && fastPointer.next != null){
slowPointer = slowPointer.next;
fastPointer = fastPointer.next;
if ( slowPointer == fastPointer ) {
return slowPointer.val;
}
}
return -1;
}
}
class TestDemo{
public static void main(String[] args){
//新建一个链表
SingleLinkedList lk=new SingleLinkedList();
//在链表中插入值
lk.insertTail(1);
lk.insertTail(2);
lk.insertTail(3);
lk.insertTail(4);
lk.insertTail(5);
//判断两个链表是否相交
//测试getIntersectionNode方法
//构造两个相交链表
SingleLinkedList lk1=new SingleLinkedList();
//测试是否为环链表,获取环长度
lk1.insertTail(6);
lk1.insertTail(7);
lk1.insertTail(8);
SingleLinkedList.Node h=lk1.getHead( );
SingleLinkedList.Node cur=h;
//构建一个环长度为2的入口节点为第二个节点值7的环链表
while (cur.next!=null){
cur=cur.next;
}
cur.next=h.next;
System.out.println("是否为环链表:"+lk1.isLoopList(h));
System.out.println("环长度:"+lk1.loopListLen(h));
System.out.println("环入口节点:"+lk1.getLoopNode(h));
//构建两个相交链表
SingleLinkedList lk2=new SingleLinkedList();
SingleLinkedList lk3=new SingleLinkedList();
SingleLinkedList lk4=new SingleLinkedList();
lk2.insertTail(1);
lk2.insertTail(2);
lk2.insertTail(3);
lk3.insertTail(3);
lk3.insertTail(2);
lk3.insertTail(1);
lk4.insertTail(5);
lk4.insertTail(6);
lk4.insertTail(7);
SingleLinkedList.Node h1=lk2.getHead();
SingleLinkedList.Node h2=lk3.getHead();
SingleLinkedList.Node h3=lk4.getHead();
SingleLinkedList.Node temp1=h1;
SingleLinkedList.Node temp2=h2;
while (temp1.next!=null){
temp1=temp1.next;
}
temp1.next=h3;
while (temp2.next!=null){
temp2=temp2.next;
}
temp2.next=h3;
SingleLinkedList.Node firstNode= SingleLinkedList.getIntersectionNode(h1,h2);
System.out.println("相交链表第一个相交节点:"+firstNode.val);
//删除一个元素
SingleLinkedList.Node head =lk.deleteNode(lk.getHead( ),2);
//获取节点个数
System.out.println("节点个数"+": "+lk.getSize());
// SingleLinkedList.Node head = lk.getHead( );
while(head!=null){
System.out.println(head.val);
head=head.next;
}
//反转链表
/* SingleLinkedList.Node reverseHead = lk.reverseList(lk.getHead( ));
while(reverseHead!=null){
System.out.print(reverseHead.val+" ");
reverseHead=reverseHead.next;
}*/
System.out.println();
//判断链表是否为空
System.out.println(lk.isEmpty());
//判断链表中是否包含某数据
System.out.println(lk.contains(6));
System.out.println(lk.contains(1));
//获取某个节点的数据,使用时需要注释掉反转链表的部分,否则会报错空指针异常
System.out.println(lk.get(3));
//用新数据替换指定位置的的数据
lk.replace(8,3);
System.out.println(lk.get(3));
//获取倒数第k个节点
SingleLinkedList.Node kthHead=lk.getKthFromEnd(lk.getHead(),2);
while(kthHead!=null){
System.out.print(kthHead.val+" ");
kthHead=kthHead.next;
}
System.out.println();
//清空链表
lk.clear();
//清空链表后判断链表是否为空
System. out.println(lk.isEmpty());
}
}