Рубрики

Чередование раскола данного односвязного списка | Комплект 1

Напишите функцию AlternatingSplit (), которая берет один список и разделяет его узлы, чтобы сделать два меньших списка: «a» и «b». Подсписки должны быть сделаны из чередующихся элементов в исходном списке. Таким образом, если исходный список 0-> 1-> 0-> 1-> 0-> 1, тогда один подсписок должен быть 0-> 0-> 0, а другой — 1-> 1-> 1.

Способ 1 (простой)
Простейший подход перебирает список источников, вытягивает узлы из источника и поочередно помещает их в начало (или начало) «a» и «b». Единственная странная часть состоит в том, что узлы будут в обратном порядке, в котором они встречались в списке источников. Метод 2 вставляет узел в конце, отслеживая последний узел в подсписках.

C ++

/ * C ++ Программа для альтернативного разделения
связанный список на две половины * /
#include <bits/stdc++.h>

using namespace std;

  
/ * Узел списка ссылок * /

class Node 

    public:

    int data; 

    Node* next; 

}; 

  
/ * снять передний узел
источник и поместите его в dest * /

void MoveNode(Node** destRef, Node** sourceRef) ; 

  
/ * Учитывая список источников, разделить его
узлы в два более коротких списка. Если мы номер
элементы 0, 1, 2, ... тогда все четные
элементы должны идти в первом списке, и
все нечетные элементы во втором.
Элементы в новых списках могут быть в любом порядке. * /

void AlternatingSplit(Node* source, Node** aRef, 

                            Node** bRef) 

    / * разделить узлы источника

    в эти списки 'a' и 'b' * /

    Node* a = NULL; 

    Node* b = NULL; 

          

    Node* current = source; 

    while (current != NULL) 

    

        MoveNode(&a, &current); / * Переместить узел в список 'a' * /

        if (current != NULL) 

        

            MoveNode(&b, &current); / * Переместить узел в список 'b' * /

        

    

    *aRef = a; 

    *bRef = b; 

  
/ * Возьмите узел спереди
источник, и переместите его на передний план
судьбы Это ошибка звонить
это с исходным списком пустым.

      
Перед вызовом MoveNode ():
источник == {1, 2, 3}
dest == {1, 2, 3}

          
Аффтер, вызывающий MoveNode ():
источник == {2, 3}
dest == {1, 1, 2, 3}
* /

void MoveNode(Node** destRef, Node** sourceRef) 

    / * передний исходный узел * /

    Node* newNode = *sourceRef; 

    assert(newNode != NULL); 

          

    / * Продвигать указатель источника * /

    *sourceRef = newNode->next; 

          

    / * Свяжите старый dest с новым узлом * /

    newNode->next = *destRef; 

          

    / * Переместить dest, чтобы указать на новый узел * /

    *destRef = newNode; 

  
/ * ПОЛЕЗНЫЕ ФУНКЦИИ * /
/ * Функция для вставки узла в
появление связанного списка * /

void push(Node** head_ref, int new_data) 

    / * выделить узел * /

    Node* new_node = new Node();

      

    / * вставить данные * /

    new_node->data = new_data; 

      

    / * связать старый список с новым узлом * /

    new_node->next = (*head_ref);     

      

    / * переместить голову, чтобы указать на новый узел * /

    (*head_ref) = new_node; 

  
/ * Функция для печати узлов
в данном связанном списке * /

void printList(Node *node) 

    while(node!=NULL) 

    

    cout<<node->data<<" "

    node = node->next; 

    

  
/ * Код водителя * /

int main() 

    / * Начнем с пустого списка * /

    Node* head = NULL; 

    Node* a = NULL; 

    Node* b = NULL; 

      

    / * Давайте создадим отсортированный связанный список для проверки функций

    Созданный связанный список будет 0-> 1-> 2-> 3-> 4-> 5 * /

    push(&head, 5); 

    push(&head, 4); 

    push(&head, 3); 

    push(&head, 2); 

    push(&head, 1);                                 

    push(&head, 0); 

      

    cout<<"Original linked List: "

    printList(head); 

      

    / * Удалить дубликаты из связанного списка * /

    AlternatingSplit(head, &a, &b); 

      

    cout<<"\nResultant Linked List 'a' : "

    printList(a);         

      

    cout<<"\nResultant Linked List 'b' : "

    printList(b);         

      

    return 0; 

  
// Этот код предоставлен rathbhupendra

С

/ * Программа для альтернативного разделения связанного списка на две половины * /
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

  
/ * Узел списка ссылок * /

struct Node

{

    int data;

    struct Node* next;

};

  
/ * вытащить передний узел источника и поместить его в dest * /

void MoveNode(struct Node** destRef, struct Node** sourceRef) ;

  
/ * Учитывая исходный список, разделите его узлы на два более коротких списка.

  Если мы нумеруем элементы 0, 1, 2, ... тогда все четные элементы

  должен идти в первом списке, а все нечетные элементы во втором.

  Элементы в новых списках могут быть в любом порядке. * /

void AlternatingSplit(struct Node* source, struct Node** aRef, 

                            struct Node** bRef) 

{

  / * разделить узлы источника на эти списки 'a' и 'b' * /

  struct Node* a = NULL; 

  struct Node* b = NULL;

    

  struct Node* current = source;

  while (current != NULL) 

  {

    MoveNode(&a, &current); / * Переместить узел в список 'a' * /

    if (current != NULL) 

    {

       MoveNode(&b, &current); / * Переместить узел в список 'b' * /

    }

  }

  *aRef = a;

  *bRef = b;

}

  
/ * Возьмите узел с передней части источника и переместите его к передней части Dest.

   Ошибочно называть это с пустым списком источников.

     

   Перед вызовом MoveNode ():

   источник == {1, 2, 3}

   dest == {1, 2, 3}

        

   Аффтер, вызывающий MoveNode ():

   источник == {2, 3}

   dest == {1, 1, 2, 3}

* /

void MoveNode(struct Node** destRef, struct Node** sourceRef) 

{

  / * передний исходный узел * /

  struct Node* newNode = *sourceRef; 

  assert(newNode != NULL);

    

  / * Продвигать указатель источника * /

  *sourceRef = newNode->next;

    

  / * Свяжите старый dest с новым узлом * /

  newNode->next = *destRef; 

    

  / * Переместить dest, чтобы указать на новый узел * /

  *destRef = newNode; 

}

  
/ * ПОЛЕЗНЫЕ ФУНКЦИИ * /
/ * Функция для вставки узла при порождении связанного списка * /

void push(struct node** head_ref, int new_data)

{

  / * выделить узел * /

  struct Node* new_node =

            (struct Node*) malloc(sizeof(struct Node));

  

  / * вставить данные * /

  new_node->data  = new_data;

  

  / * связать старый список с новым узлом * /

  new_node->next = (*head_ref);     

  

  / * переместить голову, чтобы указать на новый узел * /

  (*head_ref)    = new_node;

}

  
/ * Функция для печати узлов в заданном связанном списке * /

void printList(struct Node *node)

{

  while(node!=NULL)

  {

   printf("%d ", node->data);

   node = node->next;

  }

  
/ * Программа драйвера для проверки вышеуказанных функций * /

int main()

{

  / * Начнем с пустого списка * /

  struct Node* head = NULL;

  struct Node* a = NULL;

  struct Node* b = NULL;  

  

  / * Давайте создадим отсортированный связанный список для проверки функций

   Созданный связанный список будет 0-> 1-> 2-> 3-> 4-> 5 * /

  push(&head, 5);

  push(&head, 4);

  push(&head, 3);

  push(&head, 2);

  push(&head, 1);                                    

  push(&head, 0);  

  

  printf("\n Original linked List:  ");

  printList(head); 

  

  / * Удалить дубликаты из связанного списка * /

  AlternatingSplit(head, &a, &b); 

  

  printf("\n Resultant Linked List 'a' ");

  printList(a);            

  

  printf("\n Resultant Linked List 'b' ");

  printList(b);            

  

  getchar();

  return 0;

}


Выход:

Original linked List: 0 1 2 3 4 5 
Resultant Linked List 'a' : 4 2 0 
Resultant Linked List 'b' : 5 3 1 

Сложность времени: O (n) где n — номер узла в данном связанном списке.

Метод 2 (Использование фиктивных узлов)
Вот альтернативный подход, который строит подсписки в том же порядке, что и список источников. Код использует временные фиктивные заголовочные узлы для списков «a» и «b» по мере их построения. Каждый подсписок имеет «хвостовой» указатель, который указывает на его текущий последний узел — таким образом, новые узлы могут быть легко добавлены в конец каждого списка. Пустые узлы дают указателям на хвост что-то, на что нужно указать изначально. В этом случае фиктивные узлы эффективны, поскольку они являются временными и размещаются в стеке. Альтернативно, локальные «ссылочные указатели» (которые всегда указывают на последний указатель в списке, а не на последний узел) могут быть использованы, чтобы избежать фиктивных узлов.

C ++

void AlternatingSplit(Node* source, 

                      Node** aRef, Node** bRef) 

    Node aDummy; 

      

    / * указывает на последний узел в 'a' * /

    Node* aTail = &aDummy; 

    Node bDummy; 

      

    / * указывает на последний узел в 'b' * /

    Node* bTail = &bDummy; 

    Node* current = source; 

    aDummy.next = NULL; 

    bDummy.next = NULL; 

    while (current != NULL) 

    

        MoveNode(&(aTail->next), ¤t); / * добавить в 'а' хвост * /

        aTail = aTail->next; / * продвигать "а" хвост * /

        if (current != NULL) 

        

            MoveNode(&(bTail->next), ¤t); 

            bTail = bTail->next; 

        

    

    *aRef = aDummy.next; 

    *bRef = bDummy.next; 

  
// Этот код добавлен
// ратбхупендра

С

void AlternatingSplit(struct Node* source, struct Node** aRef, 

                            struct Node** bRef) 

{

  struct Node aDummy;

  struct Node* aTail = &aDummy; / * указывает на последний узел в 'a' * /

  struct Node bDummy;

  struct Node* bTail = &bDummy; / * указывает на последний узел в 'b' * /

  struct Node* current = source;

  aDummy.next = NULL;

  bDummy.next = NULL;

  while (current != NULL) 

  {

    MoveNode(&(aTail->next), &current); / * добавить в 'а' хвост * /

    aTail = aTail->next; / * продвигать "а" хвост * /

    if (current != NULL) 

    {

      MoveNode(&(bTail->next), &current);

      bTail = bTail->next;

    }

  }

  *aRef = aDummy.next;

  *bRef = bDummy.next;

}

Сложность времени: O (n) где n — номер узла в данном связанном списке.

Источник: http://cslibrary.stanford.edu/105/LinkedListProblems.pdf

Пожалуйста, пишите комментарии, если вы обнаружите, что приведенный выше код / алгоритм неверен, или найдете лучшие способы решения той же проблемы.

Рекомендуемые посты:

Чередование раскола данного односвязного списка | Комплект 1

0.00 (0%) 0 votes