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 printMyList(){
        Node temp=this.head;
        while(temp!=null){
            System.out.print(temp.data);
            temp=temp.next;
            if(temp!=null){
                System.out.print("-->");
            }else{
                System.out.println();
            }
        }
    }

向链表中插入数据:

public void addNode(int d){
        Node node=new Node(d);
        if(head==null){
            head=node;
            return;
        }
        Node temp=head;
        while(temp.next!=null){
            temp=temp.next;
        }
        temp.next=node;
    }

向链表中插入结点:

public void addNode(Node node){
        if(head==null){
            head=node;
            return;
        }
        Node temp=head;
        while(temp.next!=null){
            temp=temp.next;
        }
        temp.next=node;
    }

在链表尾部添加另一个链表:

public static void  addList(MyLinkedList list,MyLinkedList afterlist) {
        Node thishead = list.head;
        Node addhead  = afterlist.head;
        if(thishead==null){
            thishead=addhead;
            return;
        }
        Node temp=thishead;
        while(temp.next!=null){
            temp=temp.next;
        }
        temp.next=addhead;
    }

从链表中删除指定位置的数据:

public boolean deleteNode(int index){//index:删除的元素的位置
        if(index<1||index>length()){
            return false;
        }
        if(index==1){
            head=head.next;
            return true;
        }
        int i=2;
        Node preNode=head;
        Node curNode=preNode.next;
        while(curNode!=null){
            if(i==index){
                preNode.next=curNode.next;
                return true;
            }
            preNode=curNode;
            curNode=curNode.next;
            i++;
        }
        return true;
    }

对链表进行排序,返回排序后的头结点:

public Node orderList(){
        Node nextNode=null;
        int temp=0;
        Node headNode=head;
        while(headNode.next!=null){
            nextNode=headNode.next;
            while(nextNode!=null){
                if(headNode.data>nextNode.data){
                    temp=nextNode.data;
                    nextNode.data=headNode.data;
                    headNode.data=temp;
                }
                nextNode=nextNode.next;
            }
            headNode=headNode.next;
        }
        return head;
    }

从链表中删除重复数据 第一种方法

public void deleteRepetition1(){
        Hashtable<Integer, Integer>hashtable=new Hashtable<>();
        Node temp=this.head;
        Node pre=null;
        while(temp!=null){
            if(hashtable.containsKey(temp.data))
            {
                pre.next=temp.next;
            }
            else
            {
                hashtable.put(temp.data, 1);
                pre=temp;
            }
            temp=temp.next;
        }
    }

从链表中删除重复数据 第二种方法:

public void deleteRepetition2(){
        Node temp=head;
        while(temp!=null){
            Node i=temp;
            while(i.next!=null){
                if(temp.data==i.next.data)
                {
                    i.next=i.next.next;
                }
                else
                {
                    i=i.next;
                }
            }
            temp=temp.next;
        }
    }

找出单链表中的倒数第k个元素:

public Node findLastElem(int k){
        if(k<1){
            System.out.println("k不合法");
            return null;
        }
        if(head==null){
            System.out.println("链表不包含元素");
            return null;
        }
        Node p1=head;
        Node p2=head;
        for(int i=0;i<k-1;i++){
            p2=p2.next;
        }
        while(p2.next!=null){
            p1=p1.next;
            p2=p2.next;
        }
        return p1;
        }

链表反转:

public void reversal(){
        Node pReversalHead=this.head;
        Node pNode=this.head;
        Node pPrev=null;
        while(pNode!=null){
            Node pNext=pNode.next;
            if(pNext==null)
            {
                pReversalHead=pNode;
            }
            pNode.next=pPrev;
            pPrev=pNode;
            pNode=pNext;
        }
        this.head=pReversalHead;
    }

不反转链表,倒序输出链表元素:

public void printReversalList(Node pHead){
        if(pHead.next==null){
            System.out.print(pHead.data);
        }
        if(pHead.next!=null){
            printReversalList(pHead.next);
            System.out.print("-->"+pHead.data);
        }
    }

寻找单链表中间节点:

public Node searchMidNode(){
        Node pNode=this.head;
        Node qNode=this.head;
        while(pNode!=null&&pNode.next!=null&&pNode.next.next!=null){
            pNode=pNode.next.next;
            qNode=qNode.next;
        }
        return qNode;
    }

判断一个链表是否有环:

public boolean isHaveLoop(){
        Node fast=head;
        Node slow=head;
        if(fast==null){
            return false;
        }
        while(fast!=null&&fast.next!=null){
            fast=fast.next.next;
            slow=slow.next;
            if(fast==slow){
                return true;
            }
        }
        return false;
    }

寻找环入口:

public Node getLoopStart(MyLinkedList list){
        //在链表头和相遇点分别设置一个指针,每次各走一步,两个指针必定相遇,且第一个相遇点为环入口
        Node slow=list.head;
        Node fast=list.head;
        while(slow.next!=null&&fast.next!=null){
            slow=slow.next;
            fast=fast.next.next;
            if(slow==fast){
                break;
            }
        }
        while(slow!=fast){
            slow=slow.next;
            fast=fast.next;
        }
        return slow;
    }

在不知道头指针的情况下删除指定节点:

public boolean deleteNode(Node node){
        //此方法不能删除链表最后一个节点,因为无法使其前驱结点的next指向null;
        if(node==null||node.next==null){
            return false;
        }
        node.data=node.next.data;
        node.next=node.next.next;
        return true;
    }

判断两个链表是否相交:

public static boolean isIntersect(MyLinkedList list,MyLinkedList list2){
        Node head1=list.head;
        Node head2=list2.head;
        if(head1==null||head2==null){
            return false;
        }
        while(head1.next!=null){
            head1=head1.next;
        }
        while(head2.next!=null){
            head2=head2.next;
        }
        return head1==head2;
    }

寻找两个链表相交的第一个节点:

public static Node getFirstMeetNode(MyLinkedList list,MyLinkedList list2){
        Node head1=list.head;
        Node head2=list2.head;
        if (isIntersect(list, list2)==false){
            return null;
        }
        Node t1=head1;
        Node t2=head2;
        if(list.length()>list2.length()){
            int d=list.length()-list2.length();
            while(d!=0){
                t1=t1.next;
                d--;
            }
        }
        else {
            int d=list2.length()-list.length();
            while(d!=0){
                t2=t2.next;
                d--;
            }
        }
        while(t1!=t2){
            t1=t1.next;
            t2=t2.next;
        }
        return t1;
    }
时间: 2024-11-09 02:40:51

Java 链表常见考题总结的相关文章

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数据结构:单链表常见操作代码实现

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

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

链表是面试中最常见的一种题型,因为他的每个题的代码短,短短的几行代码就可以体现出应聘者的编码能力,所以它也就成为了面试的重点. 链表常见的操作有1.打印链表的公共部分,2.删除链表的倒数第K个节点,3.翻转单向链表,4.环形约瑟夫环问题,5.判断链表是否是一个回文链表,6.两个链表生成相加链表,7.删除无序链表中重复出现的节点,8.删除指定值得节点,9.合并两个有序的单链表,10.环形链表的插入 import java.util.*; /********** *@Author:Tom-shush

链表常见题型(java版)

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

Java基础常见英语词汇

(转自http://www.jianshu.com/p/2743fe834166) Java基础常见英语词汇(共70个) ['?bd?ekt] ['?:rientid]导向的 ['pr??ɡr?m??]编程OO: object-oriented ,面向对象 OOP: object-oriented programming,面向对象编程 [d?'vel?pm?nt][k?t]工具箱 ['v??tj??l]虚拟的JDK:Java development kit, java开发工具包 JVM:java

Java链表基本操作和Java.util.ArrayList

Java链表基本操作和Java.util.ArrayList 今天做了一道<剑指offer>上的一道编程题"从尾到头打印链表",具体要求如下:输入一个链表,按链表值从尾到头的顺序返回一个ArrayList. 一开始我想的是通过两次遍历链表,第一次遍历得到链表元素的个数count.然后定义一个ArrayList 变量,由于ArrayList是动态数组,不能在未初始化的情况下对任意位置进行插入指定的值.所以只能先对其进行初始化,将count个ArrayList元素赋值为初始值0

Java中常见的5种WEB服务器介绍

这篇文章主要介绍了Java中常见的5种WEB服务器介绍,它们分别是Tomcat.Resin.JBoss.WebSphere.WebLogic,需要的朋友可以参考下 Web服务器是运行及发布Web应用的容器,只有将开发的Web项目放置到该容器中,才能使网络中的所有用户通过浏览器进行访问.开发Java Web应用所采用的服务器主要是与JSP/Servlet兼容的Web服务器,比较常用的有Tomcat.Resin.JBoss.WebSphere 和 WebLogic 等,下面将分别进行介绍. Tomc

java中常见的输入输出流案例学习

字节输入流: 1.FileInputStream 用途:从文件系统中的文件获得输入字节,常用于读取图像.声音等原始字节流,读取字符流可考虑使用FileReader 详细构造函数与常用方法可参考API文档,网上已经有中文版的API了,我是个E文盲,伤不起 这里介绍一个最常见的方法: read(byte[] b, int off, int len) 从此输入流中将最多 len 个字节的数据读入一个 byte 数组中. ->off:b字节数组中的偏移量 小知识:数组偏移量,比如a[1,2,3,4,5]

Java链表的删除操作

刚开始接触java时很长一段时间, 总觉得java链表的删除操作自己写的有bug. 第一个bug版本: 仅接removeByForlist.remove(j)之后应该显示调用i-- public static void testRemoveByFor() { List<Integer> removeByForlist = Lists.newArrayList(1, 1, 1, 1, 1, 1, 1, 1, 1, 1); System.out.println(ToStringBuilder.re