Löschen Sie die doppelten Knoten aus einer unsortierten verlinkten Liste

Löschen Sie die doppelten Knoten aus einer unsortierten verlinkten Liste

In diesem Artikel werden die verschiedenen Ansätze zum Löschen der doppelten Knoten aus der verknüpften Liste mithilfe der C ++ - Programmierung angezeigt. Beginnen wir mit einer Erläuterung, was die „doppelten Knoten“ in einer verknüpften Liste bedeuten.

In dieser Herausforderung erhalten wir eine ungeortierte verknüpfte Liste und forderten, alle doppelten Mitglieder aus der Liste zu löschen. Lassen Sie uns einige Beispiele verwenden, um zu versuchen, das Problem zu erfassen.

Die nicht abgebrochene Eingangsliste lautet wie folgt:

Die Elemente 8, 10 und 9 erscheinen mehr als einmal in der verlinkten Liste, wie in der vorherigen Liste zu sehen ist. Dies zeigt an, dass in der verknüpften Liste 8, 10 und 9 Duplikate vorhanden sind, die wir beseitigen müssen. Die ausgaberabte Liste lautet wie folgt, sobald die doppelten Einträge aus der Liste entfernt wurden:

Eine schnelle und einfache Möglichkeit, herauszufinden, besteht darin, alle möglichen Knotenpaare in der Liste zu vergleichen, um festzustellen, ob sie die gleichen Informationen haben. Wenn ihre Informationen übereinstimmen, werden wir den zweiten Knoten los, indem wir ihn löschen. Dieser Ansatz ist jedoch zeitaufwändiger.

Bessere Effizienz ist möglich mit Verwendung Hashing. Ziel ist es, die angegebene Liste durchzuarbeiten und jeden Knoten zu einem Satz hinzuzufügen, während Sie gehen. Wenn der aktuell angezeigte Knoten im vorherigen Satz angezeigt wird, kann er sicher ignoriert werden. Wenn der Vorgang abgeschlossen ist, enthält die Liste keine doppelten Knoten mehr.

Lassen Sie uns jeden Ansatz im Detail verstehen.

Ansatz 1: Verwenden Sie zwei Schleifen

Algorithmusschritte

  1. Erstellen Sie eine verknüpfte Listenfunktion “,“CreatelinkedList„, Das eine verknüpfte Liste erstellen kann.
  2. Erstellen Sie eine Funktion namens “LöschungeduplikateNodesDas kann den doppelten Knoten aus der verknüpften Liste löschen.
  3. Erstellen Sie zwei lokale Zeiger, PTR1 und PTR2, innerhalb des “LöschungeduplikateNodes”Funktion.
  4. Zuweisen Sie die ptr1 = headnode Und ptr2 = null Werte, wobei PTR1 verwendet wird, um den Knoten zu verfolgen, dessen Duplikate überprüft werden müssen, und PTR2 wird verwendet, um jeden Knoten der verknüpften Liste zu durchqueren, um zu prüfen, ob Knotendaten mit den PTR1 -Knotendaten die gleichen sind.
  5. Der verschachtelte Schleifenzeiger PTR2 durchquert den gesamten Knoten des gesamten verknüpften Listen, bis er null findet.
  6. Wenn die PTR1 -Knotendaten den verschachtelten Schleifen -PTR2 -Knotendaten ähnlich sind, löschen Sie diesen Knoten aus der verknüpften Liste.
  7. Wenn nicht, erhöhen Sie die PTR1-> Weiter und überprüfen Sie die Daten des nächsten Knotens auf Duplikate.
  8. Die Schritte 4 bis 7 werden wiederholt, bis PTR1 nicht gleich Null ist, was darauf hinweist, dass es das Ende der verknüpften Liste erreicht hat.
  9. Schließlich drucken wir die verknüpfte Liste.
  10. Ende des Algorithmus.

C ++ Code -Implementierung (unter Verwendung von zwei Schleifen)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#enthalten
Verwenden von Namespace STD;
/* Der Knoten hat Daten Und Adressteil *///
Klassenknoten
öffentlich:
int Daten;
Knoten* Weiter;
;
/* Das untere Ist Eine Methode zum Erstellen eines neuen Knotens des verknüpften
Liste */
Knoten* newnode (int value)
Node* tempnode = neuer Knoten;
tempnode-> data = value;
tempnode-> next = null;
Tempnode zurückgeben;

/*
Diese Funktion fügt dem vorhandenen verknüpften neuen Knoten einen neuen Knoten hinzu
Liste und wenn die verknüpfte Liste leer ist, dann wird dies
Erstellen Sie einen neuen Knoten als Ein Headerknoten. Darin gehen wir vorbei
Zeiger auf Zeiger als Ein Verweis auf den Kopf einer verknüpften Liste.
*/
void createLinkedList (Knoten ** Headnode, int value)
/* Erstellen Sie einen neuen Knoten*/
Node* newnode = new node ();
Node * lastnode = * headnode;
newnode-> data = value; / * Hinzufügen der Daten */
/* Adresse dieses neuen Knoten
newnode-> next = null;
/* Überprüfen der Headnode -Referenz ist null oder nicht.
Wenn ja, dann wird der Newnode der Headnode*/
if (*headnode == null)
*headnode = newnode;
zurückkehren;

/* Wenn nicht, Dann wird dies, während die Schleife wird
Führen Sie den Nachnode des verlinkten aus und finden Sie
List, damit neu erstellt wurde
während (Nachnode-> Weiter != Null)
Nachnode = Nachnode-> Weiter;

/* Fügen Sie die Adresse des Newnode zu dem hinzu
Lastnode als nächstes
*/
LastNode-> next = newnode;
zurückkehren;

/*
Diese Funktion löscht die Duplikate des Knotens
*/
Hohlraum deleteduplicateSnodes (Knoten* Headnode)
Knoten *ptr1, *ptr2, *dopplicate;
ptr1 = headnode;
while (ptr1 != Null && ptr1-> Weiter != Null)
ptr2 = ptr1;
während (PTR2-> Weiter != Null)
/* Wenn gefunden wird, löscht der Code unter dem Code
Duplikatiert den Knoten*/
if (ptr1-> data == ptr2-> next-> data)
Duplicate = ptr2-> Weiter;
PTR2-> Weiter = PTR2-> NEXT-> NEXT;
löschen (doppelt);
else /* Wenn nicht gefunden wird, wird PTR2 auf aktualisiert
zum nächsten Knoten*/
PTR2 = PTR2-> Weiter;

PTR1 = PTR1-> Weiter;


/* Diese Funktion druckt die verlinkte Liste*/drucken
void Display (Knoten* Knoten)
while (node-> next)
printf ("%d ->", Knoten-> Daten);
node = node-> Weiter;

printf ("%d", Knoten-> Daten);

/* Die Hauptfunktion des Programms*/
int main ()
/* Leere Liste*/
Node* headnode = null;
int n; / * Arraygröße */
Cout << "Enter the size (N) of the array : " << endl;
Cin >> n;
int arr [n];
Cout << "Enter elements in the array : " << endl;
für (int k = 0; k < N; k++)
cin >> arr [k];
createLinkedList (& headnode, arr [k]);

printf ("Original verlinkte Liste: \ n");
Anzeige (Headnode);
DeleteduplicateSnodes (Headnode);
printf ("\ nLinked list nach dem Löschen von Duplikaten Knoten: \ n");
Anzeige (Headnode);
Rückkehr 0;

Ausgang:

1
2
3
4
5
6
7
8
9
10
11
12
Geben Sie die Größe (n) des Arrays ein:
5
Geben Sie Elemente in das Array ein:
2
2
0
8
0
Originalverbindete Liste:
2 -> 2 -> 0 -> 8 -> 0
Linked List nach dem Löschen von Duplikatenknoten:
2 -> 0 -> 8

Erläuterung:

Zeilen 21 bis 52: Wir erstellen eine Funktion mit dem Namen "CreateLinkedList". Wir geben in dieser Funktion zwei Parameter (einen Headnode -Zeiger an Zeiger und einen Wert) über. Wie im vorhergehenden Programm gezeigt, erstellt sie, wenn diese Funktion aufgerufen wird.

/* Erstellen Sie einen neuen Knoten*/
Node* newnode = new node ();
Node * lastnode = * headnode;
newnode-> data = value; / * Hinzufügen der Daten */
/* Adresse dieses neuen Knoten
newnode-> next = null;

Dann prüft es, ob die Headnode -Referenz null ist. Wenn ja, wird der neu erstellte Knoten zum Kopf.

/* Überprüfen der Headnode -Referenz ist null oder nicht.
Wenn ja, dann wird der Newnode der Headnode*/
if (*headnode == null)
*headnode = newnode;
zurückkehren;

Wenn die Headnode -Referenz nicht null ist, endet sie an den Nachnode der verknüpften Liste an. Die Adresse dieses neu erstellten Newnode ist dem Nachnode zugeordnet, damit sie auf den neu erstellten NewNode hinweisen kann.

/* Wenn nicht, dann wird dies, während die Schleife wird
Führen Sie den Nachnode des verlinkten aus und finden Sie
List, damit neu erstellt wurde
während (Nachnode-> Weiter != Null)
Nachnode = Nachnode-> Weiter;

Jetzt wird der neu erstellte Newnode zum Nachnode. Dieser Prozess wird bis zu diesem Zeitpunkt fortgesetzt, wenn wir diese Funktion nennen.

Die vorherigen Schritte erstellen die verknüpfte Liste gemäß unseren Anforderungen. Jetzt löschen wir die doppelten Knoten aus der verknüpften Liste.

Zeilen 57 bis 75: Wir erstellen eine Funktion namens "DeleteduplicateSnodes", die einen Parameter akzeptiert, der der Headnode -Zeiger der verknüpften Liste ist. Wir erstellen zwei Variablen auf lokaler Ebene, PTR1 und PTR2, um die verknüpfte Liste zu verfolgen, wenn wir sie verfolgen, um die Duplikate in der verknüpften Liste herauszufinden. Wir initialisieren den PTR1 mit dem Headnode, da dies die obere Schleife und der PTR2 mit dem Nullwert sein wird.

ptr1 = headnode;

PTR1: Diese Variable befindet sich an der äußeren Schleife und verfolgt die Elemente, deren Duplikate wir überprüfen werden.

ptr2: Diese Variable befindet sich in der Schleife und überprüft weiterhin die Daten jedes Knoten. Wenn es übereinstimmt, werden seine Duplikate aus der verknüpften Liste entfernt. Dies wird überprüft und dauert fort, bis es nicht den letzten Knoten erreicht, dessen Wert null ist.

Wenn ptr2-> next == null, das verschachtelte während der Schleife endet und die äußere, während die Schleife inkrementiert wird PTR1 = PTR1-> Weiter mit den nächsten Knotendaten.

Notiz: Der ptr2 endet, wenn die PTR1 Schleife ist vorbei, weil ptr2 ist innerhalb der PTR1 -Schleife.

while (ptr1 != Null && ptr1-> Weiter != Null)
ptr2 = ptr1;
während (PTR2-> Weiter != Null)
/* Wenn gefunden wird, löscht der Code unter dem Code
Duplikatiert den Knoten*/
if (ptr1-> data == ptr2-> next-> data)
Duplicate = ptr2-> Weiter;
PTR2-> Weiter = PTR2-> NEXT-> NEXT;
löschen (doppelt);
else /* Wenn nicht gefunden wird, wird PTR2 auf aktualisiert
zum nächsten Knoten*/
PTR2 = PTR2-> Weiter;

PTR1 = PTR1-> Weiter;

Zeilen 78 bis 84: Dies zeigt die endgültige verknüpfte Liste ohne Vervielfältigung an. In diesem Fall übergeben wir den Headnode als Parameter, der die Adresse der verknüpften Liste ist.

/* Diese Funktion druckt die verlinkte Liste*/drucken
void Display (Knoten* Knoten)
while (node-> next)
printf ("%d ->", Knoten-> Daten);
node = node-> Weiter;

printf ("%d", Knoten-> Daten);

Ansatz 2: Hashing -Methode

Algorithmusschritte

  1. Erstellen Sie eine verknüpfte Listenfunktion, "createLinkedList", mit der eine verknüpfte Liste erstellt werden kann.
  2. Erstellen Sie eine Funktion namens "DeleteduplicateSnodes", mit der der doppelte Knoten aus der verknüpften Liste löschen kann.
  3. Erstellen Sie zwei lokale Zeiger, CurrentNode und Vorgängernode, innerhalb der Funktion „DeleteduplicateSnodes“.
  4. Erstellen Sie einen unsortierten Hash, der in den "DeleteduplicateSnodes" eingestellt ist.
  5. Weisen Sie die Werte currentNode = headnode und vorhernode = null zu, wobei der Currentnode zum Verfolgen des Knoten.
  6. Die while -Schleife durchquert den gesamten verlinkten Listenknoten, bis CurrentNode == NULL.
  7. Wenn sich die CurrentNode -Daten bereits im Hash -Set befinden, wird der Knoten gelöscht.
  8. Wenn nicht, werden die Daten dieses Knotens zum Hash -Set hinzugefügt.
  9. Die Schritte 5 bis 8 werden wiederholt, bis der Stromnode nicht gleich Null ist, was angibt, dass er das Ende der verknüpften Liste erreicht hat.
  10. Schließlich drucken wir die verknüpfte Liste.
  11. Ende des Algorithmus.

C ++ Code -Implementierung (mit der Hash -Methode)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#enthalten
Verwenden von Namespace STD;
/ * Der Knoten hat einen Daten- und Adressteil */
Klassenknoten
öffentlich:
int Daten;
Knoten* Weiter;
;
/* Das folgende ist eine Methode zum Erstellen eines neuen Knotens des verlinkten
Liste */
Knoten* newnode (int value)
Node* tempnode = neuer Knoten;
tempnode-> data = value;
tempnode-> next = null;
Tempnode zurückgeben;

/*
Diese Funktion fügt dem vorhandenen verknüpften neuen Knoten einen neuen Knoten hinzu
Liste und wenn die verknüpfte Liste leer ist, dann wird dies
Erstellen Sie einen neuen Knoten als Kopf. Darin gehen wir vorbei
Zeiger auf Zeiger als Verweis auf den Kopf einer Liste.
*/
void createLinkedList (Knoten ** Headnode, int value)
/* Erstellen Sie einen neuen Knoten*/
Node* newnode = new node ();
Node * lastnode = * headnode;
newnode-> data = value; / * Hinzufügen der Daten */
/* Adresse dieses neuen Knoten
newnode-> next = null;
/* Überprüfen der Headnode -Referenz ist null oder nicht.
Wenn ja, dann wird der Newnode der Headnode*/
if (*headnode == null)
*headnode = newnode;
zurückkehren;

/* Wenn nicht, dann wird dies, während die Schleife wird
Führen Sie den Nachnode des verlinkten aus und finden Sie
List, damit neu erstellt wurde
während (Nachnode-> Weiter != Null)
Nachnode = Nachnode-> Weiter;

/* Fügen Sie die Adresse des Newnode zu dem hinzu
Lastnode als nächstes
*/
LastNode-> next = newnode;
zurückkehren;

/*
Diese Funktion löscht die Duplikate des Knotens
*/
Hohlraum deleteduplicateSnodes (Knoten* Headnode)
/* Dies speichert die besuchte Knotenliste*/
Under Ordered_set Hash;
struct node* currentNode = headnode;
struct node* vorhernode = null;
while (currentNode != Null)
/* Wenn die bereits besuchten CurrentNode -Daten, dann ist dies
Code löscht diesen Knoten
*/
if (Hash.find (currentNode-> data) != Hash.Ende())
Voreinheit-> next = currentNode-> Weiter;
löschen (currentNode);

/*
Wenn Sie keine CurrentNode -Daten besuchen, dann dann
In den Hash einfügen
*/
anders
Hash.insert (currentNode-> data);
vorhernode = currentNode;

currentNode = vorhernode-> Weiter;


/* Diese Funktion druckt die verlinkte Liste*/drucken
void Display (Knoten* Knoten)
while (node-> next)
printf ("%d ->", Knoten-> Daten);
node = node-> Weiter;

printf ("%d", Knoten-> Daten);

/* Die Hauptfunktion des Programms*/
int main ()
/* Leere Liste*/
Node* headnode = null;
int n; / * Arraygröße */
Cout << "Enter the size (N) of the array : " << endl;
Cin >> n;
int arr [n];
Cout << "Enter elements in the array : " << endl;
für (int k = 0; k < N; k++)
cin >> arr [k];
createLinkedList (& headnode, arr [k]);

printf ("Original verlinkte Liste: \ n");
Anzeige (Headnode);
DeleteduplicateSnodes (Headnode);
printf ("\ nLinked list nach dem Löschen von Duplikaten Knoten: \ n");
Anzeige (Headnode);
Rückkehr 0;

Ausgang:

1
2
3
4
5
6
7
8
9
10
11
12
Geben Sie die Größe (n) des Arrays ein:
5
Geben Sie Elemente in das Array ein:
8
9
1
10
1
Originalverbindete Liste:
8 -> 9 -> 1 -> 10 -> 1
Linked List nach dem Löschen von Duplikatenknoten:
8 -> 9 -> 1 -> 10

Zeilen 26 bis 52: Wir erstellen eine Funktion mit dem Namen "CreateLinkedList". In dieser Funktion übergeben wir zwei Parameter (ein Headnode -Zeiger an Zeiger und einen Wert). Wie im vorhergehenden Programm gezeigt, erstellt sie zuerst einen neuen Knoten mit einem Wert (den wir übergeben haben) und einer Adresse mit einem Nullwert zuerst erstellt.

/* Erstellen Sie einen neuen Knoten*/
Node* newnode = new node ();
Node * lastnode = * headnode;
newnode-> data = value; / * Hinzufügen der Daten */
/* Adresse dieses neuen Knoten
newnode-> next = null;

Dann prüft es, ob die Headnode -Referenz null ist. Wenn ja, wird der neu erstellte Knoten zum Kopf.

/* Überprüfen der Headnode -Referenz ist null oder nicht.
Wenn ja, dann wird der Newnode der Headnode*/
if (*headnode == null)
*headnode = newnode;
zurückkehren;

Wenn die Headnode -Referenz nicht null ist, endet sie an den Nachnode der verknüpften Liste an. Die Adresse dieses neu erstellten Newnode ist dem Nachnode zugeordnet, damit sie auf den neu erstellten NewNode hinweisen kann.

/* Wenn nicht, dann wird dies, während die Schleife wird
Führen Sie den Nachnode des verlinkten aus und finden Sie
List, damit neu erstellt wurde
während (Nachnode-> Weiter != Null)
Nachnode = Nachnode-> Weiter;

Jetzt wird der neu erstellte Newnode zum Nachnode. Dieser Prozess wird bis zu diesem Zeitpunkt fortgesetzt, wenn wir diese Funktion nennen.

Die vorherigen Schritte erstellen die verknüpfte Liste gemäß unseren Anforderungen. Jetzt löschen wir die doppelten Knoten aus der verknüpften Liste.

Zeilen 57 bis 75: Wir erstellen eine Funktion namens "DeleteduplicateSnodes", die einen Parameter akzeptiert, der der Headnode -Zeiger der verknüpften Liste ist. Wir erstellen einen ungeortierten Hashset -Hash. Wir erstellen auch zwei Variablen auf lokaler Ebene, Stromnode Und VorherigesNode, Um die verlinkte Liste zu verfolgen, wenn wir sie verfolgen, um die Duplikate in der verknüpften Liste zu finden. Wir initialisieren den CurrentNode mit dem Headnode, da dies die obere Schleife und der vorherigeNode mit dem Nullwert sein wird.

struct node* currentNode = headnode;
struct node* vorhernode = null;

Stromnode: Diese Variable befindet sich an der äußeren Schleife und verfolgt die Elemente, deren Duplikate wir überprüfen werden.

VorherigesNode: Dadurch wird der vorherige Knoten des Currentnode behandelt. Wir erstellen eine Weile Schleife, die ausgeführt wird, bis der CurrentNode den Nullwert nicht findet, was am Ende der verknüpften Liste bedeutet. Wenn sich die CurrentNode -Daten bereits in der Hash -Karte befinden, weisen Sie den Wert der zu CurrentNode's Nächster Zeiger auf die VorherigeNode Nächster Zeiger.

Voreinheit-> next = currentNode-> Weiter;

Wenn nicht, fügen Sie die Daten des CurrentNode zur Hash -Karte hinzu und erstellen Sie die VorherigesNode gleich dem Stromnode.

anders
Hash.insert (currentNode-> data);
vorhernode = currentNode;

Weisen Sie am Ende den Wert des nächsten Zeigers des vorherigenNode dem currentNode zu.

while (currentNode != Null)
/* Wenn die bereits besuchten CurrentNode -Daten, dann ist dies
Code löscht diesen Knoten
*/
if (Hash.find (currentNode-> data) != Hash.Ende())
Voreinheit-> next = currentNode-> Weiter;
löschen (currentNode);

/*
Wenn Sie keine CurrentNode -Daten besuchen, dann dann
In den Hash einfügen
*/
anders
Hash.insert (currentNode-> data);
vorhernode = currentNode;

currentNode = vorhernode-> Weiter;

Zeilen 84 bis 90: Dies zeigt die endgültige verknüpfte Liste ohne Vervielfältigung an. In diesem Fall übergeben wir den Headnode als Parameter, der die Adresse der verknüpften Liste ist.

/* Diese Funktion druckt die verlinkte Liste*/drucken
void Display (Knoten* Knoten)
while (node-> next)
printf ("%d ->", Knoten-> Daten);
node = node-> Weiter;

printf ("%d", Knoten-> Daten);

Abschluss

In der ersten Methode, um die Duplikate loszuwerden, verwenden wir zwei Schleifen: eine äußere Schleife, die über die verknüpfte Liste iteriert und ein Element auswählt, und eine zweite Schleife, die über dieses Element iteriert, um nach möglichen Duplikaten zu suchen. Sobald ein Duplikat erkannt wird, wird es aus der Liste gelöscht. Diese Methode verwendet eine verschachtelte Schleife, um Duplikate aus einer ungeortierten verknüpften Liste zu untersuchen und zu beseitigen, die die zeitliche Komplexität des Prozesses erhöht. Zeitkomplexität ist o (n2).

In der zweiten Methode kann Hashing verwendet werden. In diesem Fall ist es eine Duplikation, wenn der Knoten zweimal im HashMap erscheint, und das erste Ereignis sollte gelöscht werden. Wenn ein Knoten auf der Karte fehlt, muss es eine neue gibt, die hinzugefügt werden muss. Es dauert durchschnittlich O (n) Zeit, um eine verknüpfte Liste der Länge „N“ zu überschreiten und zu prüfen, ob sich die Knoten in der Karte befinden. Die zeitliche Komplexität, um einen Wert in einer Hash -Tabelle nachzuschlagen, lautet O (1). In Anbetracht der oben genannten Voraussetzungen gemeinsam ist die Gesamtzeitkomplexität O (N).