Kürzlich sah ich zwei Beiträge mit der Aufschrift "Ich habe eine Linkliste in C-Sprache geschrieben". Alle wurden in C-Sprache geschrieben, daher habe ich den objektorientierten Schreibstil kommentiert.
Ich beschloss, diesen Artikel zu schreiben, in der Hoffnung, dass das Schreiben in einem objektorientierten Stil mir helfen würde, objektorientiert zu verstehen. Ohne die schwierige objektorientierte Denkweise verwenden wir Klassen als erweiterte Version der Struktur = benutzerdefinierter Typ.
In anderen Artikeln und Websites finden Sie eine Liste der Links. Referenz: https://ja.wikipedia.org/wiki/ Verknüpfte Liste
Bereiten Sie zunächst zwei Arten von Strukturen vor, die für die Linkliste verwendet werden sollen.
struct node
: Listenelementestruct list
: Linklistenverwaltung für node
Verwenden Sie die folgenden Regeln, um in einem objektorientierten Stil zu schreiben.
typedef
der Zeiger auf die Struktur ** als ** Klassenname **new
**#include <stdio.h>
#include <stdlib.h>
typedef const char *String;
void *new(size_t size)
{
void *memory = malloc(size);
if (memory == NULL) {
fprintf(stderr, "Out of memory\n");
exit(8);
}
return memory;
}
/*
* class Node {
*/
typedef struct node {
int data;
struct node *next;
} *Node;
Node Node_new(int data)
{
Node node = new(sizeof(*node));
node->data = data;
node->next = NULL;
return node;
}
void Node_output(Node node, String separator) {
printf("%d%s", node->data, separator);
}
void Node_free(Node node)
{
node->next = NULL;
free(node);
}
/* } */
/*
* class List {
*/
typedef struct list {
Node head;
Node tail;
} *List;
List List_new()
{
List list = new(sizeof(*list));
list->head = NULL;
list->tail = NULL;
return list;
}
void List_add(List list, int data)
{
Node node = Node_new(data);
if (list->head == NULL) {
list->head = node;
list->tail = node;
} else {
list->tail->next = node;
list->tail = node;
}
}
void List_input(List list)
{
int size;
if (scanf("%d", &size) != 1) {
fprintf(stderr, "Invalid size\n");
exit(1);
}
for (int i = 0; i < size; i++) {
int data;
if (scanf("%d", &data) != 1) {
fprintf(stderr, "Invalid data\n");
exit(2);
}
List_add(list, data);
}
}
void List_output(List list)
{
for (Node node = list->head; node != NULL; node = node->next) {
Node_output(node, " ");
}
printf("\n");
}
void List_free(List list)
{
Node node = list->head;
while (node != NULL) {
Node next = node->next;
Node_free(node); // cannot access node members after here
node = next;
}
list->head = NULL;
list->tail = NULL;
free(list);
}
/* } */
int main(void)
{
List list = List_new();
List_input(list);
List_output(list);
List_free(list);
}
Die folgende Tabelle zeigt die Unterschiede zwischen C-Sprache und Python.
C Sprache | Python |
---|---|
Variable Aussage | Nicht notwendig Wenn Sie eine Variable zuweisen, wird sie zu einem Variablenwörterbuch {Variablennamen:Wert} Variablen werden in Form von registriert. |
Strukturdefinition | Nicht notwendig Sie können der Instanz frei Variablen zuweisen |
Typdefinitiontypedef |
Klassendefinition Ganze Zahl 123 Automatischint Von der Form123 Eine Instanz wird erstellt. |
Zugriffsoperator für Zeigermitglieder-> |
Zugriffsoperator für Instanzmitglieder. |
NULL | None |
Der Verarbeitungsblock ist{ Wann} Umgeben mit |
Der Verarbeitungsblock senkt den Einzug |
printf Funktion |
print FunktionEs wird jedoch automatisch unterbrochen. Wenn kein Zeilenumbruch vorliegt end Geben Sie im Argument anstelle des Zeilenvorschubzeichens an. |
malloc Funktion |
Name der Klasse() class定義するとメモリ確保Funktion(コンストラクタ)が自動的に作られる Name der Klasseがメモリ確保Funktion名になる。 |
free Funktion |
Nicht notwendig Nicht mehr verwendete Speicherbereiche werden automatisch zurückgegeben. del Sie können es auch zwangsweise mit einem Satz zurückgeben. |
scanf Funktion| inputFunktion<br>Lesen Sie eine Zeile der Zeichenfolge.<br>Ganzzahlige Konvertierung intFunktion。<br>Blank Split split`Methode. |
Zum Vergleich haben wir eine "neue" Klasse definiert, die einen leeren Speicherbereich (Instanz) reserviert.
class new:
pass
#
# class Node {
#/
def Node_new(data):
node = new()
node.data = data
node.next = None
return node
def Node_output(node, separator):
print(node.data, end=separator)
# }
#
# class List {
#/
def List_new():
list = new()
list.head = None
list.tail = None
return list
def List_add(list, data):
node = Node_new(data)
if list.head is None:
list.head = node
list.tail = node
else:
list.tail.next = node
list.tail = node
def List_input(list):
size = int(input()) #Wird in Python nicht verwendet
for data in input().split():
List_add(list, int(data))
def List_output(list):
node = list.head
while node is not None:
Node_output(node, " ")
node = node.next
print()
# }
def main():
list = List_new()
List_input(list)
List_output(list)
del list
if __name__ == '__main__':
main()
Durch Definieren von Knoten und Liste als Klassen wird jeder Klasse Speicher zugewiesen, sodass die neue Klasse nicht mehr benötigt wird. Der Initialisierungsprozess wird in der Methode __init __ geschrieben. Es wird automatisch aufgerufen, nachdem der Konstruktor Speicher zugewiesen hat.
Ein Namespace wird durch Definieren einer Klasse erstellt, und die in der Klasse definierten Funktionen können als unterschiedliche Funktionen verwendet werden, auch wenn die Namen mit den Funktionen anderer Klassen in Konflikt stehen. "** Klassenname und Unterstrich **" Entfernen.
Ich habe class name_method name (Instanz, andere Argumente)
geschrieben
Wenn Sie "instance.method (anderes Argument)" schreiben,
Es ruft class name.method name (Instanz, andere Argumente)
auf.
Es ist üblich, die Instanzvariable als erstes Argument der Methode zu "self" zu benennen.
class Node:
def __init__(self, data):
self.data = data
self.next = None
def output(self, separator):
print(self.data, end=separator)
class List:
def __init__(self):
self.head = None
self.tail = None
def add(self, data):
node = Node(data)
if self.head is None:
self.head = node
self.tail = node
else:
self.tail.next = node
self.tail = node
def input(self):
size = int(input()) #Wird in Python nicht verwendet
for data in input().split():
self.add(int(data))
def output(self):
node = self.head
while node is not None:
node.output(" ")
node = node.next
print()
def main():
list = List()
list.input()
list.output()
del list
if __name__ == '__main__':
main()
Die grundlegende Grammatik entspricht der C-Sprache. Stellen Sie sich eine Klasse als erweiterte Version einer Struktur vor. Sie können Funktionsdefinitionen in die Struktur schreiben und Elemente und Methoden frei definieren, ohne sich um Namenskonflikte mit anderen Klassen sorgen zu müssen. Das Instanzargument des ersten Arguments der Methode muss nicht beschrieben werden, und das implizite erste Argument "this" wird automatisch definiert und die Instanz zugewiesen. Die gleiche Methode wie der Klassenname ist der Konstruktor. Da die Instanz implizit definiert ist, muss der Rückgabetyp oder die Rückgabe nicht beschrieben werden. scanf wird durch die Scannerklasse ersetzt.
LinkedList.java
import java.util.Scanner;
class Node {
int data;
Node next;
Node(int data) {
this.data = data;
this.next = null;
}
void output(String separator) {
System.out.print(this.data + separator);
}
}
class List {
Node head;
Node tail;
List() {
this.head = null;
this.tail = null;
}
void add(int data) {
Node node = new Node(data);
if (this.head == null) {
this.head = node;
this.tail = node;
} else {
this.tail.next = node;
this.tail = node;
}
}
void input() {
Scanner scanner = new Scanner(System.in);
int size = scanner.nextInt();
for (int i = 0; i < size; i++) {
int data = scanner.nextInt();
add(data);
}
}
void output() {
for (Node node = this.head; node != null; node = node.next) {
node.output(" ");
}
System.out.print("\n");
}
}
public class LinkedList {
public static void main(String[] args) {
List list = new List();
list.input();
list.output();
}
}
Recommended Posts