链表常见的题型(java实现)

链表是面试中最常见的一种题型,因为他的每个题的代码短,短短的几行代码就可以体现出应聘者的编码能力,所以它也就成为了面试的重点。

链表常见的操作有1.打印链表的公共部分,2.删除链表的倒数第K个节点,3.翻转单向链表,4.环形约瑟夫环问题,5.判断链表是否是一个回文链表,6.两个链表生成相加链表,7.删除无序链表中重复出现的节点,8.删除指定值得节点,9.合并两个有序的单链表,10.环形链表的插入

import java.util.*;
/**********
 *@Author:Tom-shushu
 *@Description:链表问题
 *@Date:21:58 2019/10/2
 *  .--,       .--,
 * ( (  \.---./  ) )
 *  ‘.__/o   o\__.‘
 *     {=  ^  =}
 *      >  -  <
 *     /        *    //       \ *   //|   .   |\ *   "‘\       /‘"_.-~^`‘-.
 *      \  _  /--‘         `
 *    ___)( )(___
 *   (((__) (__)))    高山仰止,景行行止.虽不能至,心向往之。
 *
 **********/
public class Node {
    public int value;
    public Node head;
    public Node next;

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

    //打印链表的公共部分
    public void print(Node head1, Node head2) {
        while (head1 != null && head2 != null) {
            if (head1.value < head2.value) {
                head1 = head1.next;
            } else if (head1.value > head2.value) {
                head2 = head2.next;
            } else {
                System.out.println(head1.value);
                head1 = head1.next;
                head2 = head2.next;
            }
        }
    }

    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    //删除单链表的倒数第K个节点
    //版本一
    public Node remove1(Node head, int k) {
        if (head == null || k < 1) {
            return head;
        }
        Node cur = head;
        while (cur != null) {
            k--;
            cur = cur.next;
        }
        if (k == 0) {//要删除的是第一个
            head = head.next;
        }
        if (k < 0) {
            cur = head;
            while (++k != 0) {
                cur = cur.next;
            }
            cur.next = cur.next.next;
        }
        return head;
    }

    //版本二
    public Node remove2(Node head, int k) {
        if (head == null || k <= 0) {
            return null;
        }
        Node slow = head;
        Node fast = head;
        //fast 指向 k + 1
        for (int i = 1; i < k + 1; i++) {
            if (fast.next != null) {
                fast = fast.next;
            } else {
                return null;
            }
        }
        //fast指向尾部,slow指向倒数K+1,即 k 的前一个数。
        while (fast.next != null) {
            fast = fast.next;
            slow = slow.next;
        }
        //删除第 k 个数。
        slow = slow.next.next;
        return head;
    }

    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    //翻转单向链表
    //版本一
    public Node reList(Node head) {
        Node pre = null;
        Node next = null;
        while (head != null) {
            next = head.next;
            head.next = pre;
            pre = head;
            head = next;
        }
        return pre;
    }

    //版本二
    public Node reList2(Node head) {
        if (head == null || head.next == null) {
            return head;
        }
        Node pre = head;
        Node newHead = null;
        while (pre != null) {
            Node temp = pre.next;
            pre.next = newHead;
            newHead = pre;
            pre = temp;
        }
        return newHead;
    }

    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    //环形约瑟夫问题
    public Node yuesefu(Node head, int m) {
        if (head == null || head.next == head || m < 1) {
            return head;
        }
        Node last = head;
        while (last.next != head) {
            last = last.next;
        }
        int count = 0;
        while (head != last) {
            if (++count == m) {
                last.next = head.next;
                count = 0;
            } else {
                last = last.next;
            }
            head = last.next;
        }
        return head;
    }

    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    //判断一个链表是否是回文链表
    public boolean isHuiWen(Node head) {
        Stack<Node> stack = new Stack<Node>();
        Node cur = head;
        while (cur != null) {
            stack.push(cur);
            cur = cur.next;
        }
        while (head != null) {
            if (head.value != stack.pop().value) {
                return false;
            }
            head = head.next;
        }
        return true;
    }
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    //两个单链表生成相加链表
    public Node xinagjialainbiao(Node head1, Node head2) {
        Stack<Integer> stack1 = new Stack<Integer>();
        Stack<Integer> stack2 = new Stack<Integer>();
        while (head1 != null) {
            stack1.push(head1.value);
            head1 = head1.next;
        }
        while (head2 != null) {
            stack2.push(head1.value);
            head2 = head2.next;
        }
        int ca = 0;
        int n1 = 0;
        int n2 = 0;
        int n = 0;
        Node node = null;
        Node pre = null;
        while (!stack1.isEmpty() || !stack2.isEmpty()) {
            if (stack1.isEmpty()) {
                n1 = 0;
            } else {
                n1 = stack1.pop();
            }
            if (stack2.isEmpty()) {
                n2 = 0;
            } else {
                n2 = stack2.pop();
            }
            pre = node;
            node = new Node(n % 10);
            node.next = pre;
        }
        if (ca == 1) {
            pre = node;
            node = new Node(1);
            node.next = pre;
        }
        return node;
    }

    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    //删除无需单链表中重复出现的节点
    public void deletecf(Node head) {
        if (head == null) {
            return;
        }
        HashSet<Integer> set = new HashSet<Integer>();
        Node pre = head;
        Node cur = head.next;
        set.add(head.value);
        while (cur != null) {
            if (set.contains(cur.value)) {
                pre.next = cur.next;
            } else {
                set.add(cur.value);
                pre = cur;
            }
            cur = cur.next;
        }
    }

    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    //在单链表中删除指定值得节点
    public Node deletevalue(Node head, int num) {
        Stack<Node> stack = new Stack<Node>();
        while (head != null) {
            if (head.value != num) {
                stack.push(head);
            }
            head = head.next;
        }
        while (!stack.isEmpty()) {
            stack.peek().next = head;
            head = stack.pop();
        }
        return head;
    }

    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    //合并两个有序单链表(递归)
    public Node Merge(Node list1, Node list2) {
        if (list1 == null) {
            return list2;
        }
        if (list2 == null) {
            return list1;
        }
        if (list1.value <= list2.value) {
            list1.next = Merge(list1.next, list2);
            return list1;
        } else {
            list2.next = Merge(list1, list2.next);
            return list2;
        }
    }
    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++==
    //环形链表的插入
    public Node insertNum(Node head,int num){
        Node node = new Node(num);
        if(head == null){
            node.next = node;
            return node;
        }
        Node pre = head;
        Node cur = head.next;
        while (cur != head){
            if (pre.value <= num && cur.value >= num){
                break;
            }
            pre = cur;
            cur = cur.next;
        }
        pre.next = node;
        node.next = cur;
        return head.value < num ? head : node;
    }
}

原文地址:https://www.cnblogs.com/Tom-shushu/p/11622578.html

时间: 2024-11-09 00:35:29

链表常见的题型(java实现)的相关文章

链表常见题型(java版)

直接上干货..... 链表常见题型: 找到单链表的倒数第k个节点. 删除单链表中的某个结点(O(1)). 反转链表. 两个链表的第一个公共结点. 有环链表返回环路的开头节点(及判断是否有环). 合并两个排序的链表. 删除链表中重复的结点. 先给出链表的定义: /** * 单链表定义 */ public static class Node<E>{ private E element;//节点保存的元素 private Node<E> next;//指向下一个节点的引用 public

java数据结构:单链表常见操作代码实现

一.概述: 本文主要总结单链表常见操作的实现,包括链表结点添加.删除:链表正向遍历和反向遍历.链表排序.判断链表是否有环.是否相交.获取某一结点等. 二.概念: 链表: 一种重要的数据结构,HashMap等集合的底层结构都是链表结构.链表以结点作为存储单元,这些存储单元可以是不连续的.每个结点由两部分组成:存储的数值+前序结点和后序结点的指针.即有前序结点的指针又有后序结点的指针的链表称为双向链表,只包含后续指针的链表为单链表,本文总结的均为单链表的操作. 单链表结构: Java中单链表采用No

【MyEclipse常见错误】-java.lang.NoClassDefFoundError: org/apache/juli/logging/LogFactory的解决

ApacheJavaTomcatMyeclipse 自己前一段时间出现了这个问题,通过在网上搜索,大概知道了原因,整理下一,以供大家参考. 将项目部署好后,启动tomcat后报错,java.lang.NoClassDefFoundError: org/apache/juli/logging/LogFactory 报这个错说明你用的是tomcat7. 目前的MyEclipse的内核为Eclipse3.5.* 尚不能提供直接对tomcat 7的支持,最新的Eclipse3.6.*可以直接支持. 解决

insertion Sort List (链表的插入排序) leecode java

逻辑简单,代码难写,基础不劳,leecode写注释不能出现中文,太麻烦,我写了大量注释,链表问题最重要的就是你那个指针式干啥的 提交地址https://oj.leetcode.com/problems/insertion-sort-list/ /** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { * val = x; *

Java 链表常见考题总结

首先定义自定义结点类,存储节点信息: public class Node { Node next=null; int data; public Node(int data){ this.data=data; } } 获取链表长度: private int length() { int length=0; Node temp=head; while(temp!=null){ length++; temp=temp.next; } return length; } 打印链表: public void

Java链表常见操作【剑指Offer】03:从尾到头打印链表

题目描述 输入一个链表,按链表从尾到头的顺序返回一个ArrayList. 题解一:递归 1 /* 2 在最后一次递归方法返回以后,每一层的递归方法都会做一个arrayList.add(listNode.val)这个操作, 3 从最后一次到第一次,逆向的调用了后面的方法 4 */ 5 static ArrayList<Integer> list = new ArrayList<>(); 6 public static ArrayList<Integer> printLis

单链表基础操作的Java实现

链表是很多的数据结构的基础,比如说:队列,栈,二叉树,优先级队列等等,而链表也是很多公司面试和笔试的常考题. 链表的基本操作包括:判断是否为空,头部插入,尾部插入,根据key值查找,根据key值删除,遍历链表. 当然稍微复杂一点的操作还包括:链表的逆序,链表的排序等等. 在链表中,包含两个类:Node(节点) package com.qiao.lb; public class Node { public long data; public Node next; public Node(long

单向链表的归并排序(Java)

Sort a linked list in O(n log n) time using constant space complexity. 1 package SortList; 2 3 import java.util.Iterator; 4 5 class ListNode { 6 7 int val; 8 ListNode next; 9 ListNode(int val) { 10 this.val = val; 11 } 12 } 13 14 public class Solutio

链表常见的问题【转】

转自:http://blog.csdn.net/goodluckwhh/article/details/8316357版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] 一 第一个问题如何判断单链表中是否存在循环并找出循环起点 方法一 方法二 方法三 二 第二个问题如何判断两个单链表是否交叉并找出交叉点 情形分析 情形一 情形二 情形三 解法 判断是否存在交叉 找出交叉点 关于单链表,常见的两个问题是 1.怎么判断一个单链表中是否存在循环,即出现如下情形 2.如何判断两个单链