📜  双链表中已连接组件的数量

📅  最后修改于: 2021-06-26 18:15:26             🧑  作者: Mango

给定双向链表“ L”和对双向链表“ L”的节点的引用数组“ refArr”。数组’refArr’不包含任何重复的引用,并且这些引用不是ORDERED
m <=总编号双链列表中的节点数,其中m =参考数组的大小。
任务是在链接列表“ L”中找到已连接组件的总数。
链接列表“ L”中的“连接组件”定义为列表中的一组节点,它们的引用存储在数组“ refArr”中,并且在列表中彼此相邻。
例子:

解释:

天真的方法:涉及遍历喜欢列表“ L”的每个节点的数组“ refArr”,并检查该元素是否存在于数组中。同样,维护一个布尔变量,该变量跟踪链接列表中的前一个节点是否在数组中。取变量“ cc”,将其初始化为0并表示否。链表中已连接组件的数量。
现在,让我们考虑遍历时发生的多种情况:

  • 情况1:如果前一个节点在数组中,并且当前遍历的当前节点也在数组中,则布尔变量将保持为1,表示当前节点在数组中,但由于当前节点而不会增加变量“ cc”构成上一个节点已经存在的组件的一部分。
  • 情况2:如果前一个节点不在数组中,而当前遍历的节点在数组中,则将布尔变量更新为“ 1”,表示当前节点在数组中,并将变量cc递增1,因为当前节点构成一个新组件。
  • 情况3:如果前一个节点在数组中,而当前遍历的节点不在数组中,则将布尔变量更新为0,表示当前节点不在数组中,并且不递增变量“ cc”因为当前节点不是任何组件的一部分。
  • 情况4:如果前一个节点不在数组中,而当前遍历的节点也不在数组中,则布尔变量将保持为0,表示当前节点不在数组中,并且不对变量cc进行递增,因为当前节点不属于任何组件。

现在,在执行4种情况之一之后,移至链接列表中的下一个节点,并对该节点也执行相同的操作。
时间复杂度: O(n * m),其中n =链表’L’的大小。m =参考数组’refArr’的大小。
空间复杂度:O(1)
更好的方法:这种方法涉及unordered_set的使用。使用变量“ connectedComponents”,该变量初始化为0。connectedComponents表示链表中已连接组件的数量。
现在,对于引用数组’refArr’中的每个元素:

  1. 将存储在数组中的引用添加到unordered_set’refSet’。
    • 如果同时存在上一个和下一个同级,则将变量“ connectedComponents”减1,这意味着我们已经缩小了两个组件之间的间隙,因此我们必须减少不正确计数的组件。
    • 如果该集中只有前一个和下一个同级中的一个,则不会对no进行任何更新。组件。
    • 如果集合中没有上一个和下一个同级,则我们必须增加不正确计数的组件,因为现在,当前节点形成了一个新组件。

下面是上述方法的实现:

CPP
// A C++ program to find number
// of Connected Components in a doubly linked list.
#include 
using namespace std;
 
// Node of the doubly linked list
struct Node {
    int data;
    struct Node* next;
    struct Node* prev;
};
 
// Function to find number of connected
// components using a doubly linked list
// and a reference array
int func_connComp(struct Node** head_ref,
                  vector refArr, int n)
{
    // Base case when the doubly
    // linked list is empty
    if (head_ref == NULL) {
        return 0;
    }
 
    // Initialise connectedComponents to zero
    int connectedComponents = 0;
 
    // Initialise an unordered set
    unordered_set refSet;
 
    // Push the first element of the
    // refArr in the refSet and
    // set the connectedComponents to 1
    refSet.insert(refArr[0]);
    connectedComponents++;
 
    // Loop over all the elements of the refArr
    for (int i = 1; i < n; i++) {
 
        // insert each reference node to the refSet
        refSet.insert(refArr[i]);
 
        // If the reference node is the head of the linked list
        if (refArr[i]->prev == NULL) {
 
            // when next sibling of the head node is
            // not in the refSet
            if (refSet.find(refArr[i]->next) == refSet.end()) {
                connectedComponents++;
            }
        }
 
        // If the reference node is the
        // last node of the linked list*/
        else if (refArr[i]->next == NULL) {
 
            // when previous sibling of the
            // node is not in the refSet
            if (refSet.find(refArr[i]->next) == refSet.end()) {
                connectedComponents++;
            }
        }
 
        // the case when both previous and
        // next siblings of the current node
        // are in the refSet
        else if (refSet.find(refArr[i]->prev) != refSet.end()
                 && refSet.find(refArr[i]->next) != refSet.end()) {
            connectedComponents--;
        }
 
        /*the case when previous and next
        // siblings of the current node
        // are not in the refSet*/
        else if (refSet.find(refArr[i]->prev) == refSet.end()
                 && refSet.find(refArr[i]->next) == refSet.end()) {
            connectedComponents++;
        }
    }
    return connectedComponents;
}
 
// Function to insert a node at the
// beginging of the Doubly Linked List
Node* push(struct Node** head_ref, int new_data)
{
    /* allocate node */
    struct Node* new_node = new Node;
 
    struct Node* current_node = new_node;
    /* put in the data */
    new_node->data = new_data;
 
    /* since we are adding at the beginning,
    prev is always NULL */
    new_node->prev = NULL;
 
    /* link the old list off the new node */
    new_node->next = (*head_ref);
 
    /* change prev of head node to new node */
    if ((*head_ref) != NULL)
        (*head_ref)->prev = new_node;
 
    /* move the head to point to the new node */
    (*head_ref) = new_node;
 
    return current_node;
}
 
// Function to print nodes in a given
// doubly linked list
void printList(struct Node* node)
{
    while (node != NULL) {
        printf("%d ", node->data);
        node = node->next;
    }
}
 
// Driver code
int main()
{
 
    // Start with the empty list
    struct Node* head = NULL;
 
    // Let us create a linked list to test
    // the functions so as to find number
    // of Connected Components Created a
    // doubly linked list: 1 <-> 7 <-> 10 <-> 5 <-> 4 <-> 2
    struct Node* ref_to_nodeN2 = push(&head, 2);
    struct Node* ref_to_nodeN4 = push(&head, 4);
    struct Node* ref_to_nodeN5 = push(&head, 5);
    struct Node* ref_to_nodeN10 = push(&head, 10);
    struct Node* ref_to_nodeN7 = push(&head, 7);
    struct Node* ref_to_nodeN1 = push(&head, 1);
 
    vector refArr{ ref_to_nodeN5,
                                         ref_to_nodeN2, ref_to_nodeN7, ref_to_nodeN1 };
 
    // This function will return the number
    // of connected components of doubly linked list
    int connectedComponents = func_connComp(&head, refArr, 4);
 
    cout << "Total number of connected components are "
         << connectedComponents << endl;
 
    return 0;
}


Python3
# A Python3 program to find number
# of Connected Components in a doubly linked list.
  
# Node of the doubly linked list
class Node:  
    def __init__(self):      
        self.data = 0
        self.next = None
        self.prev = None
         
# Function to find number of connected
# components using a doubly linked list
# and a reference array
def func_connComp(head_ref, refArr, n):
     
    # Base case when the doubly
    # linked list is empty
    if (head_ref == None):
        return 0;
  
    # Initialise connectedComponents to zero
    connectedComponents = 0;
  
    # Initialise an unordered set
    refSet = set()
  
    # Push the first element of the
    # refArr in the refSet and
    # set the connectedComponents to 1
    refSet.add(refArr[0]);
    connectedComponents += 1
  
    # Loop over all the elements of the refArr
    for i in range(1, n):
  
        # add each reference node to the refSet
        refSet.add(refArr[i]);
  
        # If the reference node is the head of the linked list
        if (refArr[i].prev == None):
  
            # when next sibling of the head node is
            # not in the refSet
            if (refArr[i].next not in refSet):
                connectedComponents += 1
  
        # If the reference node is the
        # last node of the linked list'''
        elif (refArr[i].next == None):
  
            # when previous sibling of the
            # node is not in the refSet
            if (refArr[i].next not in refSet):
                connectedComponents += 1
              
        # the case when both previous and
        # next siblings of the current node
        # are in the refSet
        elif (refArr[i].prev in refSet
              and refArr[i].next in refSet):
            connectedComponents -= 1
             
        # the case when previous and next
        # siblings of the current node
        # are not in the refSet'''
        elif (refArr[i].prev not in refSet
              and refArr[i].next not in refSet):
            connectedComponents += 1
           
    return connectedComponents;
  
# Function to add a node at the
# beginging of the Doubly Linked List
def push(head_ref, new_data):
 
    ''' allocate node '''
    new_node = Node()
    current_node = new_node;
     
    ''' put in the data '''
    new_node.data = new_data;
  
    ''' since we are adding at the beginning,
    prev is always None '''
    new_node.prev = None;
  
    ''' link the old list off the new node '''
    new_node.next = (head_ref);
  
    ''' change prev of head node to new node '''
    if ((head_ref) != None):
        (head_ref).prev = new_node;
  
    ''' move the head to point to the new node '''
    (head_ref) = new_node;
    return current_node, head_ref;
  
# Function to print nodes in a given
# doubly linked list
def printList(node):
    while (node != None):
        print(node.data, end = ' ');
        node = node.next;
         
# Driver code
if __name__=='__main__':
  
    # Start with the empty list
    head = None;
  
    # Let us create a linked list to test
    # the functions so as to find number
    # of Connected Components Created a
    # doubly linked list: 1 <. 7 <. 10 <. 5 <. 4 <. 2
    ref_to_nodeN2, head = push(head, 2);
    ref_to_nodeN4, head = push(head, 4)
    ref_to_nodeN5, head = push(head, 5)
    ref_to_nodeN10, head = push(head, 10)
    ref_to_nodeN7, head = push(head, 7)
    ref_to_nodeN1, head = push(head, 1)  
    refArr = [ref_to_nodeN5, ref_to_nodeN2, ref_to_nodeN7, ref_to_nodeN1]
  
    # This function will return the number
    # of connected components of doubly linked list
    connectedComponents = func_connComp(head, refArr, 4);
    print("Total number of connected components are ", connectedComponents)
 
  # This code is contributed by rutvik_56


输出:
Total number of connected components are 3

时间复杂度: O(m)
空间复杂度: O(m)其中,m =参考数组’refArr’的大小

如果您希望与行业专家一起参加现场课程,请参阅《 Geeks现场课程》和《 Geeks现场课程美国》。