【问题标题】:Regarding finding the middle element of linked list关于查找链表的中间元素
【发布时间】:2013-02-20 08:37:56
【问题描述】:

我正在按照以下方法从 linked list 计算中间元素,但我想有任何内置方法或任何其他方法也可以轻松找到相同的方法,我遵循的方法如下所示..

import test.LinkedList.Node;
public class LinkedListTest {


    public static void main(String args[]) {
        //creating LinkedList with 5 elements including head
      LinkedList linkedList = new LinkedList();
      LinkedList.Node head = linkedList.head();
      linkedList.add( new LinkedList.Node("1"));
      linkedList.add( new LinkedList.Node("2"));
      linkedList.add( new LinkedList.Node("3"));
      linkedList.add( new LinkedList.Node("4"));

      //finding middle element of LinkedList in single pass
      LinkedList.Node current = head;
      int length = 0;
      LinkedList.Node middle = head;

      while(current.next() != null){
          length++;
          if(length%2 ==0){
              middle = middle.next();
          }
          current = current.next();
      }

      if(length%2 == 1){
          middle = middle.next();
      }

      System.out.println("length of LinkedList: " + length);
      System.out.println("middle element of LinkedList : " + middle);

    } 

}

class LinkedList{
    private Node head;
    private Node tail;

    public LinkedList(){
        this.head = new Node("head");
        tail = head;
    }

    public Node head(){
        return head;
    }

    public void add(Node node){
        tail.next = node;
        tail = node;
    }

    public static class Node{
        private Node next;
        private String data;

        public Node(String data){
            this.data = data;
        }

        public String data() {
            return data;
        }

        public void setData(String data) {
            this.data = data;
        }

        public Node next() {
            return next;
        }

        public void setNext(Node next) {
            this.next = next;
        }

        public String toString(){
            return this.data;
        }
    }
}

输出:-

length of LinkedList: 4
middle element of LinkedList : 2

【问题讨论】:

标签: java


【解决方案1】:

基本算法是

  • 取两个指针

  • 使两者都指向第一个节点

  • 第一次增加两个节点,第二次增加一个,一次。

  • 循环直到第一个循环到达终点。此时,第二个将在中间。

例子:-

while ( p2.next != null ) {
    p2 = p2.next;
    if (p2.next != null) {
        p2 = p2.next;
        p1 = p1.next;
    }
}

它肯定会在奇数情况下工作,对于偶数情况,如果第一个点被允许移动到下一个但不是下一个,那么你需要再检查一个条件,那么两个指针都在中间你需要决定哪个作为中间.

【讨论】:

  • @R.J 我想通过链接跳跃找到中间,但我不知道究竟什么是“链接跳跃”。这种方式叫Link Hopping吗??
  • 杜克灵的评论是对的,但这个答案是最有效的。它不需要长度变量,这在严格的嵌入式系统中非常有用。
【解决方案2】:

我会推荐使用内置的 Java

LinkedList<Object e>

它为您提供了所需的所有功能,例如获取长度:list.size(),以及中间对象:

list.get((list.size())/2);

【讨论】:

  • 我认为这是错误的答案,尽管它在现实世界中有效。当问这个问题时,通常假设长度是未知的。假设您获得的是根节点,而不是 LinkedList 类。
【解决方案3】:

选项:

  • 有一个双链表,同时从后面和前面走,直到你到达一个共同点。
  • 存储列表的大小并在达到此大小的一半时停止(类似于标准 API 的 LinkedList 所做的)。

除此之外,我认为你不能比你的算法做得更好。

【讨论】:

  • 如果我没有count,那么我可以通过遍历列表来获取count,然后这个值的一半将是中间的。我说的对吗?
【解决方案4】:
public Node getMiddleElement(Node head) {
    Node slow_pointer=head;
    Node fast_pointer=head;
    while(fast_pointer.next!=null && fast_pointer.next.next!=null)
    {
        slow_pointer=slow_pointer.next;
        fast_pointer=fast_pointer.next.next;
    }
    return slow_pointer;
}

Node mid_elem=PrintMiddleElement(head);
System.out.println(mid_elem.data);

I/P:5 10 15 25 35 25 40 O/P:25

【讨论】:

    【解决方案5】:

    这个问题的解答:

    • 使用两个索引,firstsecond,均初始化为 0
    • first 增加1,将second 增加2 * first
    • first的值设置为中间
    • 循环将一直执行,直到second 的值小于列表大小

    这里是获取列表或链表中间元素的代码sn-p:

    private int getMiddle(LinkedList<String> list) {
    
       int middle = 0;
       int size = list.size();
    
       for (int i = 0, j = 0; j < size; j = i * 2) {
           middle = i++;
       }
    
       return middle;
    }
    
    LinkedList<String> list = new LinkedList<>();
    list.add("1");
    list.add("2");
    list.add("3");
    list.add("4");
    list.add("5");
    list.add("6");
    list.add("7");
    int middle = getMiddle(list);
    System.out.println(list.get(middle));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-28
      • 1970-01-01
      相关资源
      最近更新 更多