`
天使的左手
  • 浏览: 55590 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

不带头结点的单链表面试汇总

    博客分类:
  • java
阅读更多
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.HashMap;

import org.apache.commons.io.IOUtils;

//不带头结点的链表
public class LinkedList3<T>
{
    @SuppressWarnings("unchecked")
    public static void main(String[] args) throws Exception
    {
        LinkedList3<Integer> list = new LinkedList3<Integer>(1, 2, 3, 4, 5);
        // System.out.println(list.isEmpty());
        // System.out.println(list.size());
        System.out.println(list);

        // Entry<Integer> entry = list.getEntry(2);

        // LinkedList3<Integer> n_list = (LinkedList3<Integer>) list.clone();
        // System.out.println(n_list);
        // LinkedList3.reverseListByIterator(n_list);
        // LinkedList3.reverseListByRecursion(n_list);
        // System.out.println(n_list);

        // Entry<Integer> entry = LinkedList3.lastIndexOf(list, 6);
        // Entry<Integer> entry = LinkedList3.lastIndexOfByArray(list, 2);
        // Entry<Integer> entry = LinkedList3.getMiddleEntry(list);

        // LinkedList3.reversePrintListByStack(list);
        // LinkedList3.reversePrintListByRecursion(list);

        // LinkedList3<Integer> list1 = new LinkedList3<Integer>();
        // LinkedList3<Integer> list2 = new LinkedList3<Integer>(2, 3, 4, 5);
        // System.out.println(list1);
        // System.out.println(list2);
        // LinkedList3<Integer> list3 = LinkedList3.mergeList(list1, list2);
        // System.out.println(list3);

        // LinkedList3<Integer> list1 = new LinkedList3<Integer>(1, 2, 3, 4);
        // list1.getEntry(3).setNext(list1.getEntry(3));
        // System.out.println(LinkedList3.hasLoop(list1));
        // Entry<Integer> entry = LinkedList3.getFirstEnterLoopEntry(list1);
        // Entry<Integer> entry = LinkedList3.getFirstEnterLoopEntry2(list1);

        // LinkedList3<Integer> list1 = new LinkedList3<Integer>(1, 2, 3, 4, 5);
        // LinkedList3<Integer> list2 = new LinkedList3<Integer>(11, 22, 33, 44,
        // 55);
        // list2.getEntry(1).setNext(list1.getEntry(0));
        // list2.getEntry(3).setNext(list1.getEntry(2));
        // System.out.println(list1);
        // System.out.println(list2);
        // System.out.println(LinkedList3.isIntersect(list1, list2));
        // System.out.println(LinkedList3.isIntersect2(list1, list2));
        // System.out.println(LinkedList3.isIntersect3(list1, list2));
        //
        // Entry<Integer> entry = LinkedList3.getFirstIntersectEntry(list1,
        // list2);
        // System.out.println(entry == null ? "not found" : entry.element);
        // LinkedList3.deleteEntry(list, list.getEntry(0));
        // System.out.println(list);
    }

    // 头指针
    private Entry<T> head;

    public LinkedList3()
    {
        //初始化头指针为空
        head = null;
    }

    public LinkedList3(T... elements)
    {
        this();
        Entry<T> tail = head;
        for (T element : elements)
        {
            Entry<T> newEntry = new Entry<T>(element);
            //第一次头指针为空
            if (head == null)
            {
                head = newEntry;
                tail = head;
            }
            else
            {
                //头指针不为空,直接用尾指针来添加节点
                tail.next = newEntry;
                tail = newEntry;
            }
        }
    }

    public boolean isEmpty()
    {
        return head == null;
    }

    // 1. 求单链表中结点的个数
    public int size()
    {
        if (isEmpty())
            return 0;

        Entry<T> curEntry = head;
        int c = 0;
        while (curEntry != null)
        {
            c++;
            curEntry = curEntry.next;
        }
        return c;
    }

    // 2. 将单链表反转: reverseList(遍历)
    public static <T> void reverseListByIterator(LinkedList3<T> list)
    {
        Entry<T> curEntry = list.head;
        Entry<T> nextEntry = null;
        Entry<T> nextnextEntry = null;

        if (curEntry == null || curEntry.next == null)
            return;

        while (curEntry.next != null)
        {
            nextEntry = curEntry.next;
            nextnextEntry = nextEntry.next;
            nextEntry.next = list.head;
            list.head = nextEntry;
            curEntry.next = nextnextEntry;
        }
    }

    // 2. 将单链表反转: reverseListRec(递归)
    public static <T> void reverseListByRecursion(LinkedList3<T> list)
    {
        if (list.head == null || list.head.next == null)
            return;
        list.head = reverseList(list.head);
    }

    private static <T> Entry<T> reverseList(Entry<T> entry)
    {
        if (entry.next == null)
            return entry;

        Entry<T> newHead = reverseList(entry.next);
        entry.next.next = entry;
        entry.next = null;
        return newHead;
    }

    // 3. 查找单链表中的倒数第K个结点(k > 0)
    public static <T> Entry<T> lastIndexOf(LinkedList3<T> list, int n)
    {
        if (n <= 0)
            throw new IllegalArgumentException("The input number should be greater than zero");

        Entry<T> first = list.getEntry(n - 1);
        Entry<T> second = list.head;

        while (first.next != null)
        {
            first = first.next;
            second = second.next;
        }
        return second;
    }

    // 3. 查找单链表中的倒数第K个结点(k > 0),数组实现
    @SuppressWarnings("unchecked")
    public static <T> Entry<T> lastIndexOfByArray(LinkedList3<T> list, int n)
    {
        if (n <= 0)
            throw new IllegalArgumentException("The input number should be greater than zero");

        Object[] storage = new Object[n];
        int index = 0, c = 0;
        Entry<T> curEntry = list.head;

        while (curEntry != null)
        {
            storage[index] = curEntry;
            curEntry = curEntry.next;
            index = (index + 1) % n;
            c++;
        }

        if (storage[index] == null)
            throw new IllegalStateException("less than " + n + " elemements, current is " + c);
        return Entry.class.cast(storage[index]);
    }

    // 4. 查找单链表的中间结点
    public static <T> Entry<T> getMiddleEntry(LinkedList3<T> list)
    {
        if (list.isEmpty())
            return null;

        Entry<T> first = list.head;
        Entry<T> second = list.head;

        while (first.next != null && first.next.next != null)
        {
            first = first.next.next;
            second = second.next;
        }
        return second;
    }

    // 5. 从尾到头打印单链表,通过栈实现
    public static <T> void reversePrintListByStack(LinkedList3<T> list)
    {
        java.util.LinkedList<Entry<T>> stack = new java.util.LinkedList<Entry<T>>();
        Entry<T> curEntry = list.head;

        while (curEntry != null)
        {
            stack.push(curEntry);
            curEntry = curEntry.next;
        }

        String result = "[";
        while (!stack.isEmpty())
            result += stack.pop().element + ", ";

        if (result.length() > 1)
            result = result.substring(0, result.length() - 2);
        result += "]";
        System.out.println(result);
    }

    // 5. 从尾到头打印单链表(递归)
    public static <T> void reversePrintListByRecursion(LinkedList3<T> list)
    {
        String result = reversePrintList(list.head);
        if (result.length() > 0)
            result = result.substring(0, result.length() - 2);
        result = "[" + result + "]";
        System.out.println(result);
    }

    private static <T> String reversePrintList(Entry<T> entry)
    {
        if (entry == null)
            return "";
        String result = reversePrintList(entry.next);
        result += entry.element;
        return result + ", ";
    }

    // 6. 已知两个单链表list1和list2各自有序,把它们合并成一个链表依然有序
    @SuppressWarnings("unchecked")
    public static <T> LinkedList3<T> mergeList(LinkedList3<T> list1, LinkedList3<T> list2)
    {
        Entry<T> curEntry1 = list1.head;
        Entry<T> curEntry2 = list2.head;
        Entry<T> newHead = null;
        Entry<T> curEntry = newHead;

        //先处理新的头指针为空的情况
        if (curEntry1 != null && curEntry2 != null)
        {
            if (((Comparable) curEntry1.element).compareTo(curEntry2.element) < 0)
            {
                newHead = new Entry(curEntry1.element, null);
                curEntry1 = curEntry1.next;
            }
            else
            {
                newHead = new Entry(curEntry2.element, null);
                curEntry2 = curEntry2.next;
            }
            curEntry = newHead;
        }
        else if (curEntry1 != null)
        {
            newHead = new Entry(curEntry1.element, null);
            curEntry = newHead;
            curEntry1 = curEntry1.next;
        }
        else if (curEntry2 != null)
        {
            newHead = new Entry(curEntry2.element, null);
            curEntry = newHead;
            curEntry2 = curEntry2.next;
        }

        while (curEntry1 != null && curEntry2 != null)
        {
            if (((Comparable) curEntry1.element).compareTo(curEntry2.element) < 0)
            {
                curEntry.next = new Entry(curEntry1.element, null);
                curEntry = curEntry.next;
                curEntry1 = curEntry1.next;
            }
            else
            {
                curEntry.next = new Entry(curEntry2.element, null);
                curEntry = curEntry.next;
                curEntry2 = curEntry2.next;
            }
        }

        while (curEntry1 != null)
        {
            curEntry.next = new Entry(curEntry1.element, null);
            curEntry = curEntry.next;
            curEntry1 = curEntry1.next;
        }

        while (curEntry2 != null)
        {
            curEntry.next = new Entry(curEntry2.element, null);
            curEntry = curEntry.next;
            curEntry2 = curEntry2.next;
        }

        LinkedList3<T> result = new LinkedList3<T>();
        result.setHead(newHead);
        return result;
    }

    // 7. 判断一个单链表中是否有环
    public static <T> boolean hasLoop(LinkedList3<T> list)
    {
        Entry<T> first = list.head;
        Entry<T> second = list.head;

        while (first != null && first.next != null)
        {
            first = first.next.next;
            second = second.next;
            if (first == second)
                return true;
        }
        return false;
    }

    // 8. 已知一个单链表中存在环,求进入环中的第一个节点
    public static <T> Entry<T> getFirstEnterLoopEntry(LinkedList3<T> list)
    {
        Entry<T> first = list.head;
        Entry<T> second = list.head;

        while (first != null && first.next != null)
        {
            first = first.next.next;
            second = second.next;
            if (first == second)
                break;
        }

        if (first == null || first.next == null)
            return null;

        second = list.head;
        while (first != second)
        {
            first = first.next;
            second = second.next;
        }
        return first;
    }

    // 8. 已知一个单链表中存在环,求进入环中的第一个节点 HashMap实现
    public static <T> Entry<T> getFirstEnterLoopEntry2(LinkedList3<T> list)
    {
        HashMap<Entry<T>, Boolean> storage = new HashMap<Entry<T>, Boolean>();
        Entry<T> curEntry = list.head;

        while (curEntry != null)
        {
            if (storage.get(curEntry) == Boolean.TRUE)
                return curEntry;
            else
            {
                storage.put(curEntry, Boolean.TRUE);
                curEntry = curEntry.next;
            }
        }
        return null;
    }

    // 9. 判断两个单链表是否相交 HashMap实现
    public static <T> boolean isIntersect(LinkedList3<T> list1, LinkedList3<T> list2)
    {
        if (list1.isEmpty() || list2.isEmpty())
            return false;

        HashMap<Entry<T>, Boolean> storage = new HashMap<Entry<T>, Boolean>();
        Entry<T> curEntry1 = list1.head;
        while (curEntry1 != null)
        {
            storage.put(curEntry1, Boolean.TRUE);
            curEntry1 = curEntry1.next;
        }

        Entry<T> curEntry2 = list2.head;
        while (curEntry2 != null)
        {
            if (storage.get(curEntry2) == Boolean.TRUE)
                return true;
            curEntry2 = curEntry2.next;
        }
        return false;
    }

    // 9. 判断两个单链表是否相交 如果相交 让第一个链表的next指向第二个链表的头指针,可以构成一个环
    public static <T> boolean isIntersect2(LinkedList3<T> list1, LinkedList3<T> list2)
    {
        if (list1.isEmpty() || list2.isEmpty())
            return false;

        Entry<T> curEntry1 = list1.head;
        Entry<T> curEntry2 = list2.head;

        while (curEntry1.next != null)
            curEntry1 = curEntry1.next;

        curEntry1.next = list2.head;
        boolean exist = false;
        while (curEntry2.next != null)
        {
            if (curEntry2.next == list2.head)
            {
                exist = true;
                break;
            }
            curEntry2 = curEntry2.next;
        }
        curEntry1.next = null;
        return exist;
    }

    // 9. 判断两个单链表是否相交 如果相交 最后一个节点一定相等
    public static <T> boolean isIntersect3(LinkedList3<T> list1, LinkedList3<T> list2)
    {
        if (list1.isEmpty() || list2.isEmpty())
            return false;

        Entry<T> curEntry1 = list1.head;
        Entry<T> curEntry2 = list2.head;

        while (curEntry1.next != null)
            curEntry1 = curEntry1.next;

        while (curEntry2.next != null)
            curEntry2 = curEntry2.next;

        if (curEntry1 == curEntry2)
            return true;
        return false;
    }

    // 10. 求两个单链表相交的第一个节点
    public static <T> Entry<T> getFirstIntersectEntry(LinkedList3<T> list1, LinkedList3<T> list2)
    {
        int m = list1.size();
        int n = list2.size();

        Entry<T> curEntry1 = list1.head;
        Entry<T> curEntry2 = list2.head;
        int c;
        if (m > n)
        {
            c = m - n;
            while (c != 0)
            {
                curEntry1 = curEntry1.next;
                c--;
            }
        }
        else
        {
            c = n - m;
            while (c != 0)
            {
                curEntry2 = curEntry2.next;
                c--;
            }
        }

        while (curEntry1 != null)
        {
            if (curEntry1 == curEntry2)
                return curEntry1;
            curEntry1 = curEntry1.next;
            curEntry2 = curEntry2.next;
        }
        return null;
    }

    // 11. 给出一单链表头指针pHead和一节点指针pToBeDeleted,O(1)时间复杂度删除节点pToBeDeleted: delete
    public static <T> void deleteEntry(LinkedList3<T> list, Entry<T> entry)
    {
        if (entry == null)
            return;

        if (entry.next != null)
        {
            entry.element = entry.next.element;
            entry.next = entry.next.next;
        }
        else
        {
            if (entry == list.head)
                list.head = entry.next;
            else
            {
                Entry<T> preEntry = list.head;
                while (preEntry != null)
                {
                    if (preEntry.next == entry)
                        break;
                    preEntry = preEntry.next;
                }
                preEntry.next = preEntry.next.next;
            }
        }
    }

    public void setHead(Entry<T> head)
    {
        this.head = head;
    }

    public Entry<T> createEntry(T element)
    {
        return new Entry<T>(element);
    }

    public Entry<T> getEntry(int index)
    {
        if (index < 0)
            throw new IllegalArgumentException("index should be a positive number or zero");

        int c = 0;
        Entry<T> curEntry = head;
        while (curEntry != null && c < index)
        {
            c++;
            curEntry = curEntry.next;
        }

        if (curEntry == null)
            throw new IllegalStateException("less than " + (index + 1) + " elements, current is " + c);
        return curEntry;
    }

    @SuppressWarnings("unchecked")
    @Override
    public Object clone() throws CloneNotSupportedException
    {
        try
        {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            try
            {
                oos.writeObject(head);
                oos.flush();

                ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
                try
                {
                    LinkedList3<T> result = new LinkedList3<T>();
                    result.setHead(Entry.class.cast(ois.readObject()));
                    return result;
                }
                finally
                {
                    IOUtils.closeQuietly(ois);
                }
            }
            finally
            {
                IOUtils.closeQuietly(oos);
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
            return super.clone();
        }
    }

    @Override
    public String toString()
    {
        String result = "[";
        Entry<T> curEntry = head;
        while (curEntry != null)
        {
            result += curEntry.element;
            curEntry = curEntry.next;
            if (curEntry != null)
                result += ", ";
        }
        return result + "]";
    }

    public static class Entry<T> implements Serializable
    {
        private static final long serialVersionUID = 1L;
        T element;
        Entry<T> next;

        Entry(T element)
        {
            this(element, null);
        }

        Entry(T element, Entry<T> next)
        {
            this.element = element;
            this.next = next;
        }

        public void setElement(T element)
        {
            this.element = element;
        }

        public T getElement()
        {
            return element;
        }

        public void setNext(Entry<T> next)
        {
            this.next = next;
        }

        public Entry<T> getNext()
        {
            return next;
        }

        @Override
        public String toString()
        {
            return String.valueOf(element);
        }
    }
}
分享到:
评论

相关推荐

    数据结构:不带头结点单链表的实现及其一些基本操作.cpp

    不带头结点,不带头结点,不带头结点! 实现单链表及其一些基本操作函数(不带头结点) 1.头文件包含 2.宏定义及节点类型描述 3.初始化、判断是否为空 4.指定位置插入操作 5.在p节点后插入元素e 6.在p节点前...

    c++实现 不带头结点单链表基本操作

    不带头结点的单链表是指链表的第一个节点没有专门的头结点,而是直接由数据节点开始。这种链表的处理在某些特定场景下更方便,但需要特别注意对链表起始位置的处理。下面将详细解释如何用C++实现不带头结点单链表的...

    不带头结点单链表.cpp

    不带头结点单链表.cpp

    数据结构 不带头结点的单链表代码

    在这个主题中,我们重点关注不带头结点的单链表,以及如何用C++来实现它的遍历、插入、查询和删除功能。 首先,不带头结点的单链表意味着链表的第一个元素就是链表本身,没有额外的节点用于标识链表的起始位置。这...

    给定一个不带头结点的单链表,写出将链表倒置的算法

    给定一个不带头结点的单链表,写出将链表倒置的算法

    带头结点单链表操作C++的实现

    使用C++面向对象的方法实现带头结点的单链表的插入,删除等基本操作.

    带头结点单链表基本操作.doc

    带头结点的单链表是在链表的最前端添加一个额外的节点,这个节点不存储实际的数据,其作用主要是简化对链表的操作,比如插入、删除等,使得代码更简洁且易于理解。本文将详细介绍带头结点单链表的基本操作,包括初始...

    带头结点链表的各种操作(c语言)

    /*带头结点头文件 hlinklist.h*/ #include &lt;stdio.h&gt; typedef int datatype; typedef struct link_node { datatype data; struct link_node *next; }node; /*初始化链表*/ node *init() { node *head; head=...

    利用带头结点的单链表实现两个集合的并、交、差运算.docx

    利用带头结点的单链表实现两个集合的并、交、差运算 本文档的主要内容是使用带头结点的单链表实现两个集合的并、交、差运算。该文档共分为八个部分,分别是题目重述、题目功能描述、概要设计图、程序源代码及注释、...

    带头结点单链表.zip

    本压缩包“带头结点单链表.zip”提供的内容着重于如何在实际编程中实现带有头结点的单链表。 首先,我们需要理解单链表的基本概念。单链表是由一系列节点构成的,每个节点包含两部分:数据域和指针域。数据域用于...

    2,带头结点单链表的定义及基本操作源代码

    在单链表的开头,我们添加一个特殊的节点,称为头结点,它的数据域通常不存储任何有意义的信息,但它的指针域指向链表的第一个实际数据节点。这种设计使得对链表的遍历和操作更为方便。 首先,我们需要定义链表节点...

    数据结构作业带或不带头结点链表

    在本题目中,我们探讨的是两种常见的链表实现:带头结点和不带头结点的链表。这两种链表在C++编程语言中具有广泛的应用,是数据结构作业中的常见主题。 首先,链表是一种线性数据结构,其元素(节点)在内存中不是...

    C++分别创建和显示带头结点与不带头结点的单链表

    最近在学数据结构,自己写的很简单的小程序,积跬步、至千里。

    尾插法建立带头结点的单链表

    使用尾插法建立一个带头结点的单链表,然后输出结果

    带头结点的单链表

    ### 带头结点的单链表存储结构与基本操作 #### 一、概述 在计算机科学领域,数据结构是研究数据组织方式及其运算的重要工具。其中,单链表是一种常见的线性表存储结构,它通过一组节点来表示一个序列,每个节点...

    带头结点的单链表的c算法实现

    当我们谈论“带头结点”的单链表时,意味着在链表的第一个元素前还有一个特殊的节点,称为头结点。头结点不包含实际数据,而是用作链表的起点,并简化了对链表的操作。 在C语言中,实现带头结点的单链表涉及以下几...

    将带头结点的单链表实现线性表的功能

    将带头结点的单链表实现线性表的功能

    将不带头结点的单链表倒置

    《数据结构与算法》(张宪超)给定一个不带头结点的单链表,写出将单链表倒置的算法

    带头结点的单链表,反转并输出

    带头结点的单链表,将其翻转,输出。typedef struct lnode { int data; struct lnode *next;/*指针域*/ } lnode,*linklist; /**linklist表示struct lnode类型的指针;lnode是别名*/

    C++ 实现带头节点的单链表

    ### C++实现带头节点的单链表 #### 概述 本篇文章主要介绍如何使用C++来实现一个带有头节点的单链表。单链表是一种基本的数据结构,在计算机科学中有着广泛的应用,例如用于存储有序的数据集合或作为其他更复杂...

Global site tag (gtag.js) - Google Analytics