给出一个链接的数字列表。交换每2个相邻的链接

时间:2010-05-15 04:27:53

标签: algorithm linked-list

给出一个链接的数字列表。交换每2个相邻的链接。例如,如果给您的链接列表是:

a->b->c->d->e->f 

预期输出:

b->a->d->c->f->e

必须交换每2个备用链接。

我在这里写了一个解决方案。你能给我一些其他解决方案吗?你能评论一下我的解决方案并帮助我更好地写出来吗?

void SwapAdjacentNodes (Node head)
{
    if (head == null) return; 

    if (head.next == null) return; 
    Node curr = head;
    Node next = curr.Next;
    Node temp = next.Next;

    while (true)
    {
        temp = next.Next;
        next.Next = curr;
        curr.Next = temp;

        if  (curr.Next != null)
            curr = curr.Next;
        else
            break;
        if (curr.Next.Next!=null)
            next = curr.Next.Next;
        else
            break;
    }   
}

16 个答案:

答案 0 :(得分:2)

这是一个更简单版本的草图,假设Node有“Next”和“Data”成员:

  for (Node n = head; n && n.Next; n = n.Next.Next) {
    void* tmp = n.Data;
    n.Data = n.Next.Data;
    n.Next.Data = tmp;
  }

换句话说,停止列表中的每个其他节点并将其数据与下一个节点(一个)交换。简单。

编辑:以上解决方案在节点内交换数据,但不交换节点本身。如果要交换实际节点,解决方案需要更多逻辑。

答案 1 :(得分:2)

看看这个C ++解决方案:

public void exchangeAdjElements(){
    LLMain backup=current.next;
    LLMain temp = current.next;
    LLMain previous=current;
    while(current!=null && current.next!=null){
        previous.next=current.next;
        current.next=temp.next;
        temp.next=current;
        if(current.next!=null){
            previous=current;
            current=current.next;
            temp=current.next;
        }
    }
    current=backup;
}

此处当前是头节点。

答案 2 :(得分:0)

@dkamins:你正在改变这些值,但在这些类型的问题中,采访者一般会要求指针改组。

<强> My attempt for the problem:

void swap (struct list **list1)
{
    struct list *cur, *tmp, *next;
    cur = *list1;

    if(!cur || !cur->next)
              return;

    *list1 = cur->next;

    while(cur && cur->next)
    {
              next = cur->next;
              cur->next = next->next;
              tmp = cur->next;
              next->next = cur;
              if(tmp && tmp->next)
                  cur->next = cur->next->next;
              cur = tmp;                                  
    }
}

答案 3 :(得分:0)

这是完全可运行的Java。这纯粹是指针播放。

public class ListSwap {
    // the swap algorithm
    static void swap(Node current) {
        while (true) {
            Node next1 = current.next;
            if (next1 == null) break;
            Node next2 = next1.next;
            if (next2 == null) break;
            Node next3 = next2.next;
            current.next = next2;
            next2.next = next1;
            next1.next = next3;
            current = next1;
        }
    }
    // the rest is infrastructure for testing
    static class Node {
        Node next;
        final char data; // final! Only pointer play allowed!
        Node(char data, Node next) {
            this.data = data;
            this.next = next;
        }
        @Override public String toString() {
            return data + (next != null ? next.toString() : "");
        }
    }

(续)

    static class List {
        Node head;
        List(String data) {
            head = null;
            String dataReversed = new StringBuilder(data).reverse().toString();
            for (char ch : dataReversed.toCharArray()) {
                head = new Node(ch, head);
            }
            head = new Node('@', head);
        }
        @Override public String toString() {
            return head.toString();
        }
        void swapPairs() {
            swap(head);
        }
    }
    public static void main(String[] args) {
        String data = "a1b2c3d4e5";
        for (int L = 0; L <= data.length(); L++) {
            List list = new List(data.substring(0, L));
            System.out.println(list);
            list.swapPairs();
            System.out.println(list);
        }
    }
}

see full output

答案 4 :(得分:0)

我在某种程度上改编了@dkamins的解决方案。我没有接收指向指针的指针,而是返回新的head。我也加强了它。

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

typedef struct Node * NodePtr;
NodePtr swapEveryTwo(NodePtr head)
{
   NodePtr newHead = (head && head->next) ? head->next : head;
   NodePtr n = head;
   while(n && n->next)
   {
      NodePtr tmp = n;     // save (1)
      n = n->next;         // (1) = (2)
      tmp->next = n->next; // point to the 3rd item
      n->next = tmp;       // (2) = saved (1)
      n = tmp->next;       // move to item 3

      // important if there will be further swaps
      if(n && n->next) tmp->next = n->next;
   }

   // return the new head
   return newHead;
}

基本上,列表的新头部是NULL或长度为1的当前头部,或者是第二个元素。

在交换循环中,tmp最终将成为第二个元素,但最初它是第一个元素。因此,我们需要它指向第3个元素,这是tmp->next = n->next;的目的。我不使用for循环,因为如果我们这样做,它就不那么直观了 - 重新评估表达式似乎每次迭代只跳过1个节点。在while循环结束时,n = tmp->next;具有直观意义 - 我们将其指向tmp之后的元素,即第二个元素。

最重要的部分是最后一行。因为我们正在向前迈进,所以我们必须记住,前一个迭代的第二个元素几乎肯定会指向当前迭代的最终 4th 元素,因为这个迭代将交换3和4所以在迭代结束时,如果我们意识到我们将再次交换下一次迭代,我们会悄悄地将第二个元素指向当前的第四个元素,知道下一次迭代它将是第三个元素,并且所有都在世界上

例如,如果列表为2 -> 7 -> 3 -> 5

n = 2
tmp = 2
n = 7
tmp->next = 3 (2 -> 3)
n->next = 2 (7 -> 2)
n = 3
7 -> 2 -> 3 -> 5

but then there will be swaps, so the last statement says
7 -> 2 -> 5      3?

这是好的,因为n = 3,所以我们没有丢失那个节点。下一次迭代:

n = 3
tmp = 3
n = 5
tmp->next = NULL (3 -> NULL)
n->next = 3  (5 -> 3)
n = NULL

导致最终的7 -> 2 -> 5 -> 3回答。

答案 5 :(得分:0)

我想要提高效率,最好在函数中使用另一个参数n。 该n用于计数,即在需要更改节点的计数之后。在上述情况下,n = 2。 然后继续迭代,直到你点击n并使用反向链接列表alog或递归反向链接列表算法来做。

void ReverseLinkList(struct node * head,int n) {     if(head == null || null&lt; = 0)         返回;

struct node* start = head;
struct node* next = null;
struct node* end = head;

int count = 1;

while(end->next != null)
{
    if(count == n)
    {
        next = end->next;
        count = 1;
        //Use ReverseLinklist From start to end
        end->next = next;
        end = next;
        start = next;
    }
    else
    {
        end = end->next;
        count++;
    }
}

}

答案 6 :(得分:0)

void SwapAdjacentNodes (Node head)
{
    if (head == null) return; 

    if (head.next == null) return; 
    Node curr = head;
    Node next = curr.Next;
    Node temp = next.Next;

    while (true)
    {
        temp = next.Next;
        next.Next = curr;
        curr.Next = temp;

        if  (curr.Next != null)
            curr = curr.Next;
        else
            break;
        if (curr.Next.Next!=null)
            next = curr.Next.Next;
        else
            break;
    }   
}

是否有用!?
因为。
说:

1[cur] -> 2[next] -> 3 [temp]-> 4

循环后

2 -> 1 -> 3[cur] -> 4[next] -> NULL [temp]

然后。

2 -> 1 -> 4 -> 3 ->  NULL

这是我们的期望吗? 但是你知道。真实的东西就像。

2 -> (1,4) -> 3  -> NULL

因为你没有将1-&gt;下一个链接更改为4!它仍然指向3!
我的版本:Click here

答案 7 :(得分:0)

这是我的c ++代码:它将返回指向交换链表的指针

Node* swap_list(Node* node) {
if(node == NULL)
    return NULL;

Node* ret = node->next;
Node* pre_a = NULL;
Node* a = node;
Node* b = node->next;   

while(a!=NULL && b!=NULL) {     
    a->next = b->next;
    b->next = a;
    if(pre_a!=NULL)
        pre_a->next = b;
    pre_a = a;
    a = a->next;
    if(a==NULL) break;
    b = a->next;        
}

return ret;
}

答案 8 :(得分:0)

private static SList swapAlternateElements(SList n){

    if(n == null)
        return n;
    SList head = swap(n);
    SList tail = head;

    while(tail == null || tail.next != null){
        tail.next.next = swap(tail.next.next);
        tail = tail.next.next;
    }

    return head;

}

private static SList swap(SList n){

    if(n.next == null || n==null){
        return n;
    }
    SList current = n.next;
    SList next = current.next;
    n.next = next;
    current.next = n;
    return current;

}

答案 9 :(得分:0)

在这里,&#39; head&#39;是指向Linked-List第一个节点的指针,该函数返回新的头指针。

node* swapPairs(node *head) {
if(head==NULL || head->next==NULL) {
    return head;
}

node *ptr1=head->next;
node *ptr2=ptr1->next;
ptr1->next=head;
head->next=swapPairs(ptr2);
return ptr1;

}

答案 10 :(得分:0)

我试图解决它,这是解决方案。

public Node swapAdjacentNodes() {
    if (head == null)
        return null;
    if (head.nextNode == null)
        return head;
    Node previous = null;
    Node current = head;
    Node next = head.nextNode;
    while (next != null && next != current) {
        current.nextNode = next.nextNode;
        next.nextNode = current;
        if (previous == null) {
            previous = next;
            head = previous;
            previous = previous.nextNode;
        } else {
            previous.nextNode = next;
            previous = previous.nextNode.nextNode;
        }
        current = current.nextNode;
        if (current == null)
            break;
        next = next.nextNode.nextNode.nextNode;

    }
    return head;

}

答案 11 :(得分:0)

这是我的C函数来交换链表中备用节点的链接。我在代码中包含了注释。为了更好地理解,请举例并通过使用笔和纸制作图表来完成这些步骤。

 void swap_alternate_nodes(struct node **head)
    {
        if(*head==NULL)
            return;
        if((*head)->next==NULL)
            return;

        struct node *prev = *head;
        struct node *curr = (*head)->next;
        struct node *temp = NULL;
        *head = (*head)->next; // new head will be second node
        while(curr!=NULL && prev!=NULL)
        {
            if(temp!=NULL)
                temp->next = curr; // previous prev node pointer should point to curr pointer

            prev->next = curr->next; // update prev node pointer

            curr->next = prev; // update curr node pointer

            temp = prev; //store prev pointer

            prev = prev->next; // forward prev pointer

            if(prev)
                curr = prev->next; // forward curr pointer
        }
    }

答案 12 :(得分:0)

我对解决方案的看法: -

public Node exchangeAdjacentNodes(Node head){
     Node curr = head;
     Node temp=null,next=null;
     if(curr==null||curr.next==null){
         return curr;
     Node head = curr.next;
     while(curr!=null && curr.next!=null){
           next = curr.next;
           curr.next=next.next;
           temp = curr.next;
           next.next = curr;
           if(temp!=null && temp.next!=null)
                 curr.next = curr.next.next;
           curr=temp;
      }
      return head;
}

答案 13 :(得分:0)

from bs4 import BeautifulSoup 
    import urllib2 
    import csv
    soup = BeautifulSoup(urllib2.urlopen('http://www.dekel.co.il/madad-lazarchan').read(), 'html') 
    data = []
    table = soup.find("table", attrs={"class" : "medadimborder"}) 
    table_body = table.find('tbody')
    rows = table_body.findAll('tr')
    for row in rows:
        cols = row.findAll('td')
        cols = [ele.text.strip() for ele in cols]
        print cols

答案 14 :(得分:0)

可能会有所帮助:     public static void main(String [] args){

    String arr[] = { "a", "b", "c", "d", "e", "f" };
    int i = 0;
    int k = 1;
    String temp;

    while (k <= arr.length - 1 && arr[i] != null && arr[k] != null) {

        temp = arr[i];
        arr[i] = arr[k];
        arr[k] = temp;

        k++;
        i = k;
        k++;
    }
    for (int j = 0; j < arr.length; j++) {

        System.out.print(arr[j]+"->");
    }

}
// Input  ->  a->b->c->d->e->f->
// Output -> b->a->d->c->f->e->

答案 15 :(得分:0)

交换相邻的C代码

node *SwapAdjacent(node *root)
{
    *NextNode = NULL;
    node * result = root->next;
    node *prev = NULL;
    while (root != NULL && root->next!=NULL)
    {
        if(prev!=NULL)
            prev->next= root->next;
        NextNode = root->next->next;
        root->next->next = root;
        root->next = NextNode;
        prev = root;
        root = NextNode;
    }
    return result;
}