簡體   English   中英

java中的單鏈表

[英]Singly linked list in java

我剛剛在網上找到了這個困難的面試問題,我希望有人可以幫助我理解它。 這是一個通用的問題......給定一個單鏈表,將列表中的每個元素成對交換,使1-> 2-> 3-> 4成為2-> 1-> 4-> 3。

您必須交換元素,而不是值。 答案應該適用於循環列表,其中尾部指向列表的頭部。 您不必檢查尾部是否指向中間(非頭部)元素。

所以我認為:

public class Node
{
     public int n;     // value
     public Node next; // pointer to next node
}

實現這個的最佳方法是什么? 有人可以幫忙嗎?

Java中的簡單遞歸解決方案:

public static void main(String[] args)
{
    Node n = new Node(1);
    n.next = new Node(2);
    n.next.next = new Node(3);
    n.next.next.next = new Node(4);
    n.next.next.next.next = new Node(5);

    n = swap(n);
}
public static Node swap(Node n)
{
    if(n == null || n.next == null)
        return n;
    Node buffer = n;
    n = n.next;
    buffer.next = n.next;
    n.next = buffer;
    n.next.next = swap(buffer.next);
    return n;
 }

public static class Node
{
    public int data; // value
    public Node next; // pointer to next node

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

我同意@Stephen沒有給出答案(完全),但我想我應該給你提示。

要理解的一件重要事情是Java沒有顯式指定指針 - 相反,只要非基元(例如,不是charbyteintdoublefloatlongbooleanshort )傳遞給函數,它就會被傳遞為一個參考。 因此,您可以使用臨時變量來交換值。 嘗試自己編寫代碼或查看以下內容:

 public static void swapNodeNexts(final Node n1, final Node n2) {  
    final Node n1Next = n1.next;  
    final Node n2Next = n2.next;  
    n2.next = n1Next;  
    n1.next = n2Next;  
 }  

然后,您將需要一個數據結構來保存Node 重要的是只有偶數個Node (奇數不必要地使事情變得復雜)。 還需要初始化節點。 你應該把它放在你的main方法中。

  public static final int NUMPAIRS = 3;
 public static void main(final String[] args) {
    final Node[] nodeList = new Node[NUMPAIRS * 2];
    for (int i = 0; i < nodeList.length; i++) {
        nodeList[i] = new Node();
        nodeList[i].n = (i + 1) * 10;
        // 10 20 30 40
    }
    // ...
 } 

重要的是設置Node下一個值。 你不能只是通過一個循環for回路所有的人,因為這樣最后一個人的next會拋出IndexOutOfBoundsException 試着自己制作一個,或偷看我的。

  for (int i = 0; i < nodeList.length - 1; i++) {
    nodeList[i].next = nodeList[i + 1];
 }
 nodeList[nodeList.length - 1].next = nodeList[0];

然后使用for循環在它們上運行swap函數。 但請記住,你不想在每個節點上運行它......想一想。

如果你無法弄清楚,這是我的最終代碼:

 // Node
 class Node {
    public int n; // value
    public Node next; // pointer to next node

    @Override
    public String toString() {
        return "Node [n=" + n + ", nextValue=" + next.n + "]";
    }

 }

 // NodeMain
 public class NodeMain {
    public static final int NUMPAIRS = 3;

    public static void main(final String[] args) {
        final Node[] nodeList = new Node[NUMPAIRS * 2];
        for (int i = 0; i < nodeList.length; i++) {
            nodeList[i] = new Node();
            nodeList[i].n = (i + 1) * 10;
            // 10 20 30 40
        }
        for (int i = 0; i < nodeList.length - 1; i++) {
            nodeList[i].next = nodeList[i + 1];
        }
        nodeList[nodeList.length - 1].next = nodeList[0];

        // This makes 1 -> 2 -> 3 -> 4 -> 1 etc.
        printNodes(nodeList);

        for (int i = 0; i < nodeList.length; i += 2) {
            swapNodeNexts(nodeList[i], nodeList[i + 1]);
        }

        // Now: 2 -> 1 -> 4 -> 3 -> 1 etc.
        printNodes(nodeList);

    }

    private static void printNodes(final Node[] nodeList) {
        for (int i = 0; i < nodeList.length; i++) {
            System.out.println("Node " + (i + 1) + ": " + nodeList[i].n
                    + "; next: " + nodeList[i].next.n);
        }
        System.out.println();
    }

    private static void swapNodeNexts(final Node n1, final Node n2) {
        final Node n1Next = n1.next;
        final Node n2Next = n2.next;
        n2.next = n1Next;
        n1.next = n2Next;
    }
 } 

我希望你能夠在指導下弄清楚其中的一部分。 但更重要的是,了解這里的概念非常重要。 如果您有任何疑問,請發表評論。

運行此程序所需的方法:

public static void main(String[] args) {
    int iNoNodes = 10;
    System.out.println("Total number of nodes : " + iNoNodes);
    Node headNode = NodeUtils.createLinkedListOfNElements(iNoNodes);
    Node ptrToSecondNode = headNode.getNext();
    NodeUtils.printLinkedList(headNode);
    reversePairInLinkedList(headNode);
    NodeUtils.printLinkedList(ptrToSecondNode);
}

方法幾乎相同,其他人正試圖解釋。 代碼是自我解釋的。

private static void reversePairInLinkedList(Node headNode) {
    Node tempNode = headNode;
    if (tempNode == null || tempNode.getNext() == null)
        return;
    Node a = tempNode;
    Node b = tempNode.getNext();
    Node bNext = b.getNext(); //3
    b.setNext(a);
    if (bNext != null && bNext.getNext() != null)
        a.setNext(bNext.getNext());
    else
        a.setNext(null);
    reversePairInLinkedList(bNext);
}

Algo(節點n1) -

在當前的2個節點保留2個指針n1和n2。 n1 - > n2 ---> ......

  • if(n1和n2相互鏈接)返回n2;

  • if(n1為NULL)返回NULL;

  • if(n2為NULL)返回n1;

  • if(n1和n2不相互鏈接且不為空)

  • 將n2的指針更改為n1。

  • 在n2.next上遞歸調用algorthm

  • 返回n2;

用c ++編寫代碼(工作)

#include <iostream>
using namespace std;

class node
{
public:
int value;
node* next;
node(int val);
};

node::node(int val)
{
value = val;
}

node* reverse(node* n)
{

if(n==NULL) return NULL;
node* nxt = (*n).next;
if(nxt==NULL) return n;

if((*nxt).next==n) return nxt;
else
    {
node* temp = (*nxt).next;
(*nxt).next = n;
 (*n).next   = reverse(temp);
}
return nxt;

}
void print(node* n)
{
node* temp = n;
while(temp!=NULL)
    {
    cout<<(*temp).value;
    temp = (*temp).next;
    }
cout << endl;

}

int main()
{
node* n = new node(0);
node* temp = n;

for(int i=1;i<10;i++)
{

node* n1 = new node(i);
(*temp).next = n1;
temp = n1;
}
print(n);
node* x = reverse(n);
print(x);

}

//2.1 , 2.2 Crack the code interview

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>

struct Node{
    int info;
    struct Node *next;
};




 struct Node *insert(struct Node *head,int data){
    struct Node *temp,*ptr;

     temp = (struct Node*)malloc(sizeof(struct Node));
     temp->info=data;
     temp->next=NULL;

     if(head==NULL)
        head=temp;

     else{
        ptr=head;
        while(ptr->next!=NULL)
        {
        ptr=ptr->next;
        }
        ptr->next=temp;
     }
    return head;
 }


 struct Node* reverse(struct Node* head){
    struct Node *current,*prev,*next;
    current = head;
    prev=NULL;
    while(current!=NULL){
        next=current->next;
        current->next = prev;
        prev=current;
        current=next;
    }
    head=prev;
    return head;
}
/*nth till last element in linked list*/

void nthlastElement(struct Node *head,int n){
    struct Node *ptr;
    int last=0,i;
    ptr=head;

    while(ptr!=NULL){
        last++;
        //printf("%d\n",last);
        ptr=ptr->next;
    }

    ptr=head;
    for(i=0;i<n-1;i++){
        ptr=ptr->next;      
    }

    for(i=0;i<=(last-n);i++){
        printf("%d\n",ptr->info);
        ptr=ptr->next;
    }
}

 void display(struct Node* head){
      while(head!=NULL){
        printf("Data:%d\n",head->info);
        head=head->next;
      }
 }



 void deleteDup(struct Node* head){
    struct Node *ptr1,*ptr2,*temp;

    ptr1=head;

    while(ptr1!=NULL&&ptr1->next!=NULL){
            ptr2=ptr1;
          while(ptr2->next!=NULL){
            if(ptr1->info==ptr2->next->info){
                temp=ptr2->next;
                ptr2->next=ptr2->next->next;
                free(temp);
            }
            else{
              ptr2=ptr2->next;
              }

          }  
          ptr1=ptr1->next;
    }
}

 void main(){
    struct Node *head=NULL;
    head=insert(head,10);
    head=insert(head,20);
    head=insert(head,30);
    head=insert(head,10);
    head=insert(head,10);
    printf("BEFORE REVERSE\n"); 
    display(head);
    head=reverse(head);
    printf("AFTER REVERSE\n");
    display(head);
    printf("NTH TO LAST\n");
    nthlastElement(head,2);
     //printf("AFTER DUPLICATE REMOVE\n");
    //deleteDup(head);
    //removeDuplicates(head);
     //display(head);
 }

采用的一般方法是逐步執行列表,並在每個其他步驟中通過分配node值對列表節點重新排序。

但是,如果您自己設計,實施和測試,我認為您將從中獲得更多(即了解更多)。 (你在面試時沒有得到免費的“打電話給朋友”或“問SO”)

是的,編寫一個迭代例程,在每次迭代中前進兩個鏈接。 記住上一次迭代的鏈接,以便您可以對其進行補丁,然后交換當前的兩個鏈接。 棘手的部分是開始(在很小程度上)並知道何時完成(更大的),特別是如果你最終有一個奇數個元素。

public static Node swapInPairs(Node n)
{
    Node two;
    if(n ==null ||n.next.next ==null)
    {
        Node one =n;
        Node twoo = n.next;
        twoo.next = one;
        one.next =null;
        return twoo;            
    }
    else{
        Node one = n;
        two = n.next;   
        Node three = two.next;
        two.next =one;
        Node res = swapInPairs(three);
        one.next =res;          
    }
    return two;
}

我在原子級寫了代碼。 所以我希望它是自我解釋的。 我測試了它。 :)

public static Node swapPairs(Node start)
{
    // empty or one-node lists don't need swapping
    if (start == null || start.next == start) return start;

    // any list we return from here on will start at what's the second node atm
    Node result = start.next;

    Node current = start; 
    Node previous = null;     // so we can fix links from the previous pair

    do
    {
        Node node1 = current;
        Node node2 = current.next;

        // swap node1 and node2 (1->2->? ==> 2->1->?)
        node1.next = node2.next;
        node2.next = node1;

        // If prev exists, it currently points at node1, not node2.  Fix that
        if (previous != null) previous.next = node2;

        previous = current;

        // only have to bump once more to get to the next pair;
        // swapping already bumped us forward once
        current = current.next;

    } while (current != start && current.next != start);

    // The tail needs to point at the new head
    // (if current == start, then previous is the tail, otherwise current is)
    ((current == start) ? previous : current).next = result;

    return result;
}
public class Node
{
     public int n;     // value
     public Node next; // pointer to next node
}

Node[] n = new Node[length];

for (int i=0; i<n.length; i++)
{
    Node tmp = n[i];
    n[i] = n[i+1];
    n[i+1] = tmp;
    n[i+1].next = n[i].next; 
    n[i].next = tmp;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM