Java实现链表算法集合

本文介绍了Java实现链表的各种操作,包括数据结构定义、添加节点、删除节点、排序、合并有序链表、反转链表、倒叙打印、环链表检测以及寻找链表的倒数第k个节点的方法。重点讲述了寻找倒数第k个节点的双指针策略。

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

1、链表的数据结构定义

public class Node() {
private int data;
private Node next;

public Node(int data) {
this.data = data
}
}

2、添加链表节点

public void addNode(int d){
		Node newNode=new Node(d);
		if (head==null) {	//若原链表为空,新建结点为头结点
			head=newNode;
			return;
		}
		Node tmp=head;  //否则将新节点插入表尾
		while(tmp.next!=null){
			tmp=tmp.next;
		}
		tmp.next=newNode;		
	}

3、删除指定位置的节点

public Boolean deleteNode(int index){
		if (index<1|| index>length()) {	//删除元素位置不合理
			return false;
		}
		//删除链表第一个元素
		if (index==1) {		
			head=head.next;
			return true;
		}
		int i=1;
		Node preNode=head;  //preNode指向头结点
		Node curNode=preNode.next;  //curNode指向头结点的下一个结点,即当前结点
		while(curNode!=null){ //当前结点非空
			if (i==index) {
				preNode.next=curNode.next;
				return true;
			}
			preNode=curNode;
			curNode=curNode.next;
			i++;
		}
		return true;
	}

 4、链表排序

public Node orderList(){ //冒泡排序~~~~~~~
		Node nextNode=null;
		int tmp=0;
		Node curNode=head;
		while(curNode.next!=null){
			nextNode=curNode.next;
			while(nextNode!=null){
				if (curNode.data>nextNode.data) {//exchanhe
					tmp=curNode.data;
					curNode.data=nextNode.data;
					nextNode.data=tmp;
				}
				nextNode=nextNode.next;
			}
			curNode=curNode.next;
		}
		return head;
	}

5、合并有序链表

// 两个参数代表的是两个链表的头结点
	public Node mergeLinkList(Node head1, Node head2) {
 
		if (head1 == null && head2 == null) { // 如果两个链表都为空
			return null;
		}
		if (head1 == null) {
			return head2;
		}
		if (head2 == null) {
			return head1;
		}
 
		Node head; // 新链表的头结点
		Node current; // current结点指向新链表
 
		// 一开始,我们让current结点指向head1和head2中较小的数据,得到head结点
		if (head1.data < head2.data) {
			head = head1;
			current = head1;
			head1 = head1.next;
		} else {
			head = head2;
			current = head2;
			head2 = head2.next;
		}
 
		while (head1 != null && head2 != null) {
			if (head1.data < head2.data) {
				current.next = head1; // 新链表中,current指针的下一个结点对应较小的那个数据
				current = current.next; // current指针下移
				head1 = head1.next;
			} else {
				current.next = head2;
				current = current.next;
				head2 = head2.next;
			}
		}
 
		// 合并剩余的元素
		if (head1 != null) { // 说明链表2遍历完了,是空的
			current.next = head1;
		}
 
		if (head2 != null) { // 说明链表1遍历完了,是空的
			current.next = head2;
		}
 
		return current ;
	}

6、链表的反转

//遍历反转
public static Node reverseList(Node node) {
    Node pre = null;
    Node next = null;
    while (node != null) {
        next = node.next;
        node.next = pre;
        pre = node;
        node = next;
    }
    return pre;
}

//递归反转
public Node reverse(Node head) {
    if (head == null || head.next == null)
        return head;
    Node temp = head.next;
    Node newHead = reverse(head.next);
    temp.next = head;
    head.next = null;
    return newHead;
}

7、倒叙打印链表

//自定义栈,倒序打印
public void reversePrint(Node head) {
	 
	         if (head == null) {
	             return;
	          }
	  
	         Stack<Node> stack = new Stack<Node>();  //新建一个栈
	          Node current = head;
	 
	        //将链表的所有结点压栈
	         while (current != null) {
	             stack.push(current);  //将当前结点压栈
	             current = current.next;
	         }
	
	         //将栈中的结点打印输出即可
	        while (stack.size() > 0) {
	             System.out.println(stack.pop().data);  //出栈操作
	         }
	     }


//递归倒序打印
public void reversePrint1(Node head) {
    	 
 
         if (head == null) {
             return;
         }
         reversePrint(head.next);
         System.out.println(head.data);
     }

8、判断链表是否有环


// 判断单链表是否有环,我们用两个指针去遍历:
	// first指针每次走一步,second指针每次走两步,如果first指针和second指针相遇,说明有环。
	public static boolean hasCycle(Node head) {
 
		if (head == null) {
			return false;
		}
 
		Node first = head;
		Node second = head;
 
		while (second != null) {
			first = first.next; // first指针走一步
			second = second.next.next; // second指针走两步
 
			if (first == second) { // 一旦两个指针相遇,说明链表是有环的
				return true;
			}
		}
 
		return false;
	}

9、求链表的倒数第k个节点的数据

我们定义两个指针,第一个指针从链表的头指针开始遍历向前走k-1步,第二个指针保持不动:从第k步开始,第二个指针也开始从链表的头指针开始遍历,由于两个指针的距离保持在k-1,当第一个(走在前面的)指针到达链表的尾结点时,第二个指针(走在后面的)指针正好是倒数第k个结点.。

public static Node FindKthtoTail(Node head, int k) {
		if (head == null || k == 0)
			return null;
 
		Node slow = head;
		Node fast = head;
 
		for (int i = 0; i < k - 1; i++)
			fast = fast.next;
 
		while (fast.next != null) {
			fast = fast.next;
			slow = slow.next;
		}
		return slow;
 
	}

 

 

 

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值