Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C++로 두 이중 연결 리스트에서 공통 노드 개수 구하기

두 개의 이중 연결 리스트(doubly linked list)가 주어졌을 때, 두 리스트에 공통으로 존재하는 노드의 총 개수를 구하는 것이 이번 글의 목표입니다.

예를 들어 첫 번째 리스트가 [15, 16, 10, 9, 7, 17]이고, 두 번째 리스트가 [15, 16, 40, 6, 9]라면, 값이 15, 16, 9인 노드 세 개가 양쪽에 모두 존재하므로 공통 노드의 개수는 3이 됩니다.

접근 방법

가장 직관적인 방법은 중첩 반복문(nested loop)을 사용하는 것입니다.

  • 바깥쪽 반복문으로 첫 번째 리스트의 각 노드를 순회합니다.
  • 안쪽 반복문으로 두 번째 리스트 전체를 탐색하며, 현재 노드와 데이터 값이 일치하는 노드가 있는지 확인합니다.
  • 일치하는 노드를 찾으면 카운터를 1 증가시키고 안쪽 반복문을 종료한 뒤 다음 노드로 넘어갑니다.
  • 모든 순회가 끝나면 카운터 값을 반환합니다.

이 방식의 시간 복잡도는 O(N×M)으로, N은 첫 번째 리스트의 길이, M은 두 번째 리스트의 길이입니다. 리스트가 짧거나 단순한 경우에는 충분히 효율적입니다.

C++ 구현 예제

#include<iostream>
using namespace std;
class Node {
   public:
      int data;
   Node *back, *front;
};
void append(Node** start, int new_data) {
   Node* new_node = new Node;
   new_node->data = new_data;
   new_node->back = NULL;
   new_node->front = (*start);
   if ((*start) != NULL)
      (*start)->back = new_node;
   (*start) = new_node;
}
int countCommonNodes(Node** start1, Node** start2) {
   Node* ptr = *start1;
   Node* ptr1 = *start2;
   int count = 0;
   while (ptr != NULL) {
      while (ptr1 != NULL) {
         if (ptr->data == ptr1->data) {
            count++;
            break;
         }
         ptr1 = ptr1->front;
      }
      ptr1 = *start2;
      ptr = ptr->front;
   }
   return count;
}
int main() {
   Node* first = NULL;
   Node* second = NULL;
   append(&first, 15);
   append(&first, 16);
   append(&first, 10);
   append(&first, 9);
   append(&first, 7);
   append(&first, 17);
   append(&second, 15);
   append(&second, 16);
   append(&second, 40);
   append(&second, 6);
   append(&second, 9);
   cout << "공통 노드 개수:" << countCommonNodes(&first, &second);
}

실행 결과

공통 노드 개수:3

코드 설명

append() 함수는 새 노드를 리스트의 맨 앞에 삽입하는 역할을 합니다. 새 노드의 front 포인터가 기존 시작 노드를 가리키도록 하고, 기존 시작 노드의 back 포인터가 새 노드를 가리키게 함으로써 이중 연결 구조를 유지합니다.

countCommonNodes() 함수는 앞서 설명한 중첩 반복문 방식으로 두 리스트를 비교합니다. 주목할 점은 안쪽 반복문이 한 번 끝날 때마다 ptr1을 두 번째 리스트의 시작점으로 초기화해준다는 부분입니다. 이렇게 해야 매번 처음부터 두 번째 리스트를 다시 탐색할 수 있습니다.

참고로 append()가 항상 맨 앞에 삽입하기 때문에, 실제 메모리상의 리스트는 입력 순서의 역순으로 저장됩니다. 다만 공통 노드의 개수를 구하는 데는 순서가 영향을 주지 않으므로 결과는 동일합니다.