Лінійне сканування - це найкраще, що я знаю, як зробити, якщо набори представлені у вигляді відсортованих пов'язаних списків. Час роботи - .O(|A|+|B|)
Зауважте, що вам не потрібно порівнювати кожен елемент проти кожного елемента B , попарно. Це призвело б до часу виконання O ( |AB , що значно гірше. Натомість для обчислення симетричної різниці цих двох множин можна використовувати техніку, аналогічну операції "злиття" в об'єднанні, відповідним чином модифіковану для опущення значень, спільних для обох наборів.O(|A|×|B|)
Більш детально, ви можете побудувати рекурсивний алгоритм, як описано нижче для обчислення A∖B , припускаючи, що і B представлені як пов'язані списки зі своїми значеннями у відсортованому порядку:AB
difference(A, B):
if len(B)=0:
return A # return the leftover list
if len(A)=0:
return B # return the leftover list
if A[0] < B[0]:
return [A[0]] + difference(A[1:], B)
elsif A[0] = B[0]:
return difference(A[1:], B[1:]) # omit the common element
else:
return [B[0]] + difference(A, B[1:])
Я представляв це в псевдо-Python. Якщо ви не читаєте Python, він A[0]
є головою пов'язаного списку A
, A[1:]
є рештою списку і +
являє собою конкатенацію списків. З міркувань ефективності, якщо ви працюєте в Python, ви, мабуть, не хотіли б реалізувати його саме так, як вище - наприклад, може бути краще використовувати генератори, щоб уникнути створення багатьох тимчасових списків - але я хотів покажіть ідеї у найпростішій можливій формі. Мета цього псевдокоду - просто проілюструвати алгоритм, а не запропонувати конкретну реалізацію.
Я не думаю, що зробити це краще, якщо ваші набори представлені у вигляді відсортованих списків і ви хочете, щоб результат був наданий у вигляді відсортованого списку. Ви принципово повинні дивитися на кожен елемент і B . Неформальний ескіз обгрунтування: Якщо є якийсь елемент, який ви не переглянули, ви не можете його вивести, тому єдиний випадок, коли ви можете опустити погляд на елемент, це якщо ви знаєте, що він присутній в обохAB і в В , але як ви могли знати, що він присутній, якщо ви не подивилися на його значення?AB