Algorithmen und Programmierung

Algorithmen sind systematische Schritt-für-Schritt-Anweisungen, die ein Computer ausführt, um ein Problem zu lösen, und bilden die Grundlage der Programmierung. Programmierung ist der Prozess, diese Algorithmen in einer Programmiersprache wie Python oder Java in ausführbaren Code umzusetzen. Durch das Verständnis von Algorithmen und Programmierung kannst Du kreative Softwarelösungen entwickeln und alltägliche Aufgaben automatisieren.

Los geht’s

Lerne mit Millionen geteilten Karteikarten

Leg kostenfrei los

Review generated flashcards

Leg kostenfrei los
Du hast dein AI Limit auf der Website erreicht 😱

Erstelle unlimitiert Karteikarten auf StudySmarter 🥹🤝

StudySmarter Redaktionsteam

Team Algorithmen und Programmierung Lehrer

  • 13 Minuten Lesezeit
  • Geprüft vom StudySmarter Redaktionsteam
Erklärung speichern Erklärung speichern
Inhaltsverzeichnis
Inhaltsverzeichnis
Inhaltsangabe

    Jump to a key chapter

      Algorithmen und Programmierung einfach erklärt

      Algorithmen und Programmierung sind die Grundlagen der Informatik, die es ermöglichen, Probleme systematisch zu lösen und computerbasierte Lösungen zu entwickeln.

      Grundlagen der Programmierung und Algorithmik

      Programmierung dient dazu, Anweisungen an einen Computer zu geben, um bestimmte Aufgaben zu erfüllen. Algorithmen sind Schritt-für-Schritt-Anleitungen zur Lösung eines Problems.

      Ein Algorithmus besteht aus einer endlichen Folge von Anweisungen, die in einer bestimmten Reihenfolge ausgeführt werden, um ein Ergebnis zu erzielen. Diese Anweisungen können in verschiedenen Programmiersprachen wie Python, Java oder C++ geschrieben werden.

      Beim Erstellen von Algorithmen und beim Programmieren sind folgende Schritte entscheidend:

      • Problem verstehen und definieren
      • Algorithmus entwerfen
      • Programmcode schreiben
      • Programm testen und verifizieren
      • Code optimieren und dokumentieren

      Angenommen, Du möchtest einen Algorithmus schreiben, der die Summe der Zahlen von 1 bis n berechnet. Ein einfacher Algorithmus könnte folgendermaßen aussehen:

      def summe_bis_n(n):   summe = 0   for i in range(1, n+1):       summe += i   return summe

      Hierbei wird eine Schleife verwendet, die von 1 bis n läuft und die Variable summe bei jedem Schritt um den aktuellen Wert von i erhöht.

      Ein tieferes Verständnis der Algorithmik umfasst komplexe Konzepte wie Pseudocode, der verwendet wird, um Algorithmen zu beschreiben, ohne sich auf die Syntax einer bestimmten Programmiersprache festzulegen. So kannst Du dich mehr auf die Logik des Problems konzentrieren. Darüber hinaus spielen Big-O-Notation und Komplexitätsanalysen eine Schlüsselrolle bei der Bewertung von Algorithmen hinsichtlich ihrer Effizienz und Leistung.

      Wichtige Datenstrukturen in Algorithmen und Programmierung

      Datenstrukturen sind entscheidend für die Speicherung, Organisation und Verwaltung von Daten in einem Programm. Einige wichtige Datenstrukturen sind:

      • Arrays: Einfache, feste Sammlungen von Elementen eines bestimmten Typs.
      • Listen: Dynamische Sammlungen von Elementen, die flexibel vergrößert oder verkleinert werden können.
      • Stacks: Datenstrukturen mit LIFO-Prinzip (Last In, First Out).
      • Queues: Datenstrukturen mit FIFO-Prinzip (First In, First Out).
      • Graphen: Datennetze, die Knoten und Kanten zur Darstellung von Verbindungen zwischen Objekten verwenden.

      Ein Stack ist eine Datenstruktur, die Zugriff auf nur das zuletzt eingefügte Element erlaubt. Dies wird als Last In, First Out (LIFO) bezeichnet.

      Ein einfaches Beispiel eines Stacks lässt sich mit Python realisieren:

      stack = []# Elemente hinzufügenstack.append(1)stack.append(2)stack.append(3)# Elemente entfernenprint(stack.pop())  # Ausgabe: 3

      Hierbei wird das zuletzt hinzugefügte Element mit der pop()-Methode entfernt.

      Ein spannender Einblick in die Welt der Datenstrukturen sind selbstbalancierende Bäume wie AVL-Bäume, die sich automatisch ausgleichen, um eine effiziente Leistung beim Einfügen, Suchen und Löschen zu gewährleisten. Diese ermöglichen es, dass pro Operation nur logarithmische Zeit in Anspruch genommen wird, was für viele Anwendungen extrem effizient ist.

      Algorithmen und Programmierung Beispiele

      Um die Konzepte der Algorithmen und Programmierung besser zu verstehen, ist es hilfreich, praktische Beispiele zu betrachten, die typische Probleme lösen.

      Ein Beispiel dafür ist der Sortieralgorithmus, wie der QuickSort, der eine durchschnittliche Laufzeit von \(O(n \log n)\) aufweist und effizient große Datenmengen sortiert.

      QuickSort verwendet das Teile-und-Herrsche-Prinzip, indem er ein Pivot-Element wählt, das Array in zwei Teile teilt (die Elemente kleiner und größer als das Pivot) und die Teile rekursiv sortiert.

      Um einen Algorithmus effizient zu gestalten, ist es entscheidend, geeignete Datenstrukturen zu wählen, die das Problem auf einfache Art und Weise lösen.

      Übungen Algorithmen und Programmierung

      Übungen zu Algorithmen und Programmierung sind entscheidend, um das Verständnis der theoretischen Konzepte zu vertiefen und die Anwendung in der Praxis zu erlernen. Sie helfen Dir, Deine logischen Denkfähigkeiten zu schulen und wertvolle Erfahrungen im Lösen von Problemen zu sammeln.

      Einfache Übungen zu Algorithmen und Programmierung

      Ein einfacher Einstieg in die Welt der Algorithmen und Programmierung erfolgt mit Übungen, die grundlegende Konzepte vermitteln. Diese können viele gängige Algorithmen, Datenstrukturen oder Kontrollstrukturen beinhalten.

      • Fibonacci-Serie: Implementiere einen Algorithmus, um die Fibonacci-Serie bis zu einem vorgegebenen Wert zu berechnen.
      • Lineare Suche: Entwickle einen Algorithmus zum Suchen eines Elements in einer Liste.
      • Summenberechnung: Erstelle ein Programm, das die Summe von Zahlen in einem gegebenen Bereich berechnet.

      Hier ist ein einfaches Beispiel für einen linearen Suchalgorithmus in Python:

      def lineare_suche(liste, ziel):   for index, element in enumerate(liste):       if element == ziel:           return index   return -1

      In dieser Funktion wird die Liste durchlaufen, um das gesuchte Element (ziel) zu finden. Ist es vorhanden, wird der Index des Elements zurückgegeben, andernfalls wird -1 zurückgegeben.

      Vermeide es, die Lösung beim ersten Durchlauf zu erzwingen. Verwende stattdessen Debugging-Tools, um den Programmlauf Schritt für Schritt zu überprüfen.

      Komplexe Übungen Algorithmen und Programmierung

      Nachdem Du die Grundlagen geübt hast, kannst Du zu komplexeren Übungen voranschreiten, die eine tiefere Auseinandersetzung mit Algorithmen erfordern. Solche Herausforderungen beinhalten oft effizientere Lösungen und das Verständnis von fortgeschrittenen Datenstrukturen.

      • Quicksort: Implementiere einen Quicksort-Algorithmus zur effizienten Sortierung einer Liste von Zahlen.
      • Dijkstra's Algorithmus: Entwickle einen Algorithmus zur Berechnung der kürzesten Wege in einem Graphen.
      • Backtracking: Löse das n-Damen-Problem mithilfe von Backtracking-Strategien.

      Hier ist ein Beispiel zur Verwendung von Quicksort:

      def quicksort(array):   if len(array) <= 1:       return array   else:       pivot = array[0]       weniger = [x for x in array[1:] if x <= pivot]       größer = [x for x in array[1:] if x > pivot]       return quicksort(weniger) + [pivot] + quicksort(größer)

      Dieser Quicksort-Algorithmus wählt das erste Element des Arrays als Pivot, organisiert die verbleibenden Elemente um dieses herum und sortiert die Teilarrays rekursiv.

      Ein fortgeschrittener Aspekt der Algorithmen ist die Analyse ihrer Komplexität. Beispielsweise hat der Quicksort eine durchschnittliche Laufzeit von \(O(n \log n)\), was ihn für große Datenmengen effizienter macht als einfache Sortiermethoden wie Bubble Sort, das \(O(n^2)\) Zeit benötigt. Solche Analysen sind wichtig, um den geeignetsten Algorithmus für spezifische Anwendungen auszuwählen.

      Algorithmen und Programmierung praxisnah anwenden

      In der Praxis angewandte Algorithmen und Programmierungsfähigkeiten sind essenziell für die Entwicklung realer Softwarelösungen und das Verständnis der Funktionsweise komplexer Systeme. Sie helfen Dir, theoretisches Wissen in praktische Ergebnisse umzusetzen.

      • Webentwicklung: Nutze Algorithmen, um die Effizienz von Serverantworten zu verbessern.
      • Datenanalyse: Implementiere Algorithmen zur Verarbeitung und Analyse großer Datenmengen.
      • Maschinelles Lernen: Verstehe die grundlegenden Algorithmen hinter Modellen und bereite Daten entsprechend auf.

      Zum Beispiel kann in einem Datenanalysekontext ein Algorithmus zur Datenbereinigung die Effizienz von Machine-Learning-Algorithmen deutlich verbessern, indem er ungenaue oder irrelevante Daten entfernt, was zu genaueren Vorhersagen führt.

      Datenstrukturen Algorithmen und Programmierung

      Effizientes Speichern und Verarbeiten von Daten ist das Herzstück der Programmierung. Datenstrukturen spielen eine wesentliche Rolle, indem sie den optimalen Zugriff und die Verwaltung von Informationen ermöglichen.

      Lineare Datenstrukturen Algorithmen und Programmierung

      Lineare Datenstrukturen sind essentielle Komponenten in Algorithmen und der Programmierung, die es ermöglichen, Daten in einer festen Reihenfolge zu speichern und darauf zuzugreifen. Sie umfassen folgende Typen:

      • Arrays: Eine Sammlung von Elementen des gleichen Typs, die über Indizes angesteuert werden können.
      • Listen: Flexible Datenstrukturen, die dynamisch in ihrer Größe sind.
      • Stacks: LIFO-Datenstruktur (Last In, First Out) für das Zugreifen auf die zuletzt eingefügten Daten.
      • Queues: FIFO-Datenstruktur (First In, First Out) für das Zugreifen auf die zuerst eingefügten Daten.

      Ein Array ist eine lineare Datenstruktur, bei der eine Sammlung von gleichartigen Elementen in zusammenhängenden Speicherplätzen gespeichert wird und über Indizes einzeln zugänglich ist.

      Ein einfaches Beispiel zur Verwendung eines Arrays in Python sieht so aus:

      array = [1, 2, 3, 4, 5]print(array[2])  # Ausgabe: 3

      Hierbei wird ein Array erstellt und das dritte Element mit dem Index 2 ausgegeben.

      Die Wahl der richtigen Datenstruktur kann die Effizienz eines Programms erheblich beeinflussen.

      Nicht-Lineare Datenstrukturen Algorithmen und Programmierung

      Nicht-lineare Datenstrukturen sind Datenmodelle, bei denen die Elemente nicht in einer sequentiellen Reihenfolge gespeichert werden, sondern in einem hierarchischen oder vernetzten Muster. Dazu zählen:

      • Bäume: Hierarchie von Knoten, bei der jeder Knoten abhängige Kinderknoten hat.
      • Graphen: Sammlung von Knoten, die durch Kanten miteinander verbunden sind und beliebige Konnektivitätsmuster darstellen können.

      Ein Baum ist eine nicht-lineare Datenstruktur, die aus Knoten besteht, die durch Kanten verbunden sind, wobei ein Knoten als Wurzel dient, und jeder Knoten null oder mehr Kinder hat.

      Ein Beispiel für einen binären Suchbaum (BST) ist eine hilfreiche Datenstruktur für das effiziente Speichern und Suchen von geordneten Daten:

      class Knoten:   def __init__(self, wert):       self.wert = wert       self.links = None       self.rechts = None 

      Dieser Code zeigt die Grundstruktur eines Knoten für einen BST, die zwei Verweise auf Kinder (links und rechts) enthält.

      Eine interessante Anwendung von nicht-linearen Datenstrukturen ist die Darstellung sozialer Netzwerke durch Graphen. In solchen Graphen stellen die Knoten die Benutzer dar, und die Kanten repräsentieren die Verbindungen (Freundschaften). Diese können komplexe Netzwerkanalysen mit Algorithmen wie PageRank zur Bewertung der Knotenbedeutung ermöglichen.

      Anwendungsbeispiele für Datenstrukturen in Algorithmen und Programmierung

      Datenstrukturen finden Anwendung in vielerlei Projekten und Algorithmen, die reale Probleme lösen. Hier einige Beispiele:

      • Sortieralgorithmen: Implementiere Algorithmen wie Mergesort oder Heapsort, die sich stark auf Arrays und Listen stützen, um Elemente effizient zu sortieren.
      • Graphenalgorithmen: Verwendes Verfahren wie Dijkstras Algorithmus, um die kürzesten Wege in einem Netzwerk von Straßendaten (Graph) zu ermitteln.
      • Datenbanken: Nutze B-Bäume für Indizes, um schnellen Zugriff auf große Datenmengen zu ermöglichen, was in modernen Datenverwaltungssystemen üblich ist.

      Dijkstras Algorithmus ist ein kürzester Wege-Algorithmus, der für Graphen mit nicht-negativen Gewichten verwendet wird, um den kürzesten Pfad von einem Startknoten zu allen anderen Knoten im Graphen zu finden.

      Ein Python-Snippet, das die Implementation von Dijkstras Algorithmus zeigt:

      import heapqdef dijkstra(graph, start):   kürzeste_wege = {start: 0}   priorität_schlange = [(0, start)]   while priorität_schlange:       (abstand, aktueller_knoten) = heapq.heappop(priorität_schlange)       for nachbar, gewicht in graph[aktueller_knoten]:           entfernung = abstand + gewicht           if entfernung < kürzeste_wege.get(nachbar, float('inf')):               kürzeste_wege[nachbar] = entfernung               heapq.heappush(priorität_schlange, (entfernung, nachbar))   return kürzeste_wege

      Dieser Code verwendet eine Prioritätswarteschlange, um die effizienteste Route durch den Graphen zu bestimmen.

      Algorithmen und Programmierung Best Practices

      Beim Erstellen und Implementieren von Algorithmen und Programmierung ist es entscheidend, effektive Strategien und Best Practices zu befolgen, um qualitativ hochwertigen, stabilen und effizienten Code zu gewährleisten.

      Effiziente Algorithmen und Programmierung Strategien

      Um Algorithmen effizient zu gestalten, sollten einige grundlegende Strategien angewandt werden:

      • Verwendung von Datenstrukturen, die optimal für das spezifische Problem geeignet sind.
      • Beachtung der Komplexität von Algorithmen (Zeit- und Raumkomplexität), um die Auswirkungen auf die Leistung korrekt einzuschätzen.
      • Optimierung der Speicherverwendung durch das Vermeiden von unnötigen Datenkopien.
      • Einsatz rekursiver Algorithmen, wo dies die Klarheit und Effizienz nicht beeinträchtigt.

      Ein klassisches Beispiel für effiziente Algorithmen ist der Binary Search Algorithmus, der in einer sortierten Liste nach einem Element sucht:

      def binary_search(liste, ziel):   links, rechts = 0, len(liste) - 1   while links <= rechts:       mitte = (links + rechts) // 2       if liste[mitte] == ziel:           return mitte       elif liste[mitte] < ziel:           links = mitte + 1       else:           rechts = mitte - 1   return -1

      Dieser Suchalgorithmus halbiert die Suchfläche mit jedem Durchlauf, was ihn sehr effizient macht (\(O(\log n)\)).

      Bevorzugen rekursive Ansätze bei Algorithmen wie Divide and Conquer, da sie durch das Teilen des Problems oft effizientere Lösungen bieten.

      Fehlervermeidung in Algorithmen und Programmierung

      Fehlervermeidung beim Programmieren ist entscheidend, um stabile und zuverlässige Software zu entwickeln. Hier sind einige Tipps zur Minimierung von Fehlern:

      • Regelmäßige Code Reviews zur Erkennung von Problembereichen durch andere Teammitglieder nutzen.
      • Verwende Unit Tests, um sicherzustellen, dass jeder Teil Deines Codes wie erwartet funktioniert.
      • Halte Deinen Code gut kommentiert und dokumentiert, um die Verständlichkeit für andere (und für Dein zukünftiges Ich!) zu erhöhen.
      • Nutze Fehlerbehandlungsmechanismen, um Ausnahmen und unerwartete Zustände korrekt zu handhaben.

      Ein gutes Beispiel für Fehlervermeidung ist die Verwendung von Try-Except-Blöcken in Python:

      try:   with open('datei.txt', 'r') as datei:       inhalt = datei.read()except FileNotFoundError:   print('Datei nicht gefunden!')

      Dieses Beispiel zeigt, wie Du potenzielle Fehler beim Arbeiten mit Dateien erkennen und behandeln kannst.

      Dokumentiere sorgfältig die Eingabe- und Ausgabewerte für Funktionen, um Missverständnisse zu minimieren und die Fehlersuche zu erleichtern.

      Algorithmen und Programmierung optimieren

      Optimierung ist ein fortlaufender Prozess, um Algorithmen schneller, sicherer oder speicherfreundlicher zu machen. Hier sind einige Möglichkeiten zur Optimierung:

      • Profiling, um die langsamen Teile des Codes zu identifizieren.
      • Verwendung von effizienten Algorithmen und Datenstrukturen, um die Gesamteffizienz zu steigern.
      • Code Refactoring zur Verbesserung der Lesbarkeit und Wartbarkeit.
      • Nutzung von Concurrency und Parallelismus bei der Bearbeitung von Aufgaben, die dies unterstützen.

      Möglicherweise möchtest Du eine Caching-Strategie anwenden, um den Zugriff auf häufig verwendete Daten zu beschleunigen. Dies kann besonders bei rekursiven Algorithmen nützlich sein, wie z.B. dem Fibonacci-Algorithmus, wo häufige Wiederholungen vermieden werden können:

      def fib_memo(n, memo={}):   if n in memo:       return memo[n]   if n <= 2:       return 1   memo[n] = fib_memo(n-1, memo) + fib_memo(n-2, memo)   return memo[n]

      Hier wird ein Memoization-Ansatz verwendet, um wiederholte Berechnungen zu vermeiden und damit den rechnerischen Aufwand stark zu reduzieren.

      Algorithmen und Programmierung - Das Wichtigste

      • Algorithmen und Programmierung sind die Basis für das systematische Lösen von Problemen und die Entwicklung computerbasierter Lösungen.
      • Ein Algorithmus ist eine finite Abfolge von Anweisungen zur Lösung eines Problems; er kann in verschiedenen Programmiersprachen wie Python, Java oder C++ verfasst werden.
      • Wichtige Schritte beim Entwickeln von Algorithmen: Problem verstehen, Algorithmus entwerfen, Code schreiben, testen und optimieren.
      • Datenstrukturen wie Arrays, Listen, Stacks und Queues sind entscheidend für die Organisation und Verwaltung von Daten in Programmen.
      • Beispiel: Quicksort ist ein effizienter Sortieralgorithmus mit einer durchschnittlichen Laufzeit von O(n log n), der das Prinzip 'Teile und Herrsche' verwendet.
      • Übungen Algorithmen und Programmierung sind wichtig, um die theoretischen Konzepte zu vertiefen und in praktischen Anwendungen anzuwenden.
      Häufig gestellte Fragen zum Thema Algorithmen und Programmierung
      Welche Programmiersprachen sind am besten geeignet, um Algorithmen zu lernen?
      Python ist ideal zum Lernen von Algorithmen, da es eine einfache Syntax und umfassende Bibliotheken bietet. Java ermöglicht solides Verständnis durch strikte Typisierung und Objektorientierung. C++ ist hilfreich für tiefere Einsichten in Speicherverwaltung und Effizienz. Jede dieser Sprachen hat ihre Vorzüge, abhängig von den Lernzielen.
      Wie kann ich die Effizienz eines Algorithmus analysieren?
      Die Effizienz eines Algorithmus analysierst Du hauptsächlich durch die Untersuchung seiner Zeit- und Speicherkomplexität, oft mittels Big-O-Notation. Dadurch kannst Du abschätzen, wie sich der Algorithmus in Bezug auf die Eingabegröße verhält. Auch empirische Tests durch Implementierung und Messung der Laufzeit können nützlich sein.
      Wie finde ich den richtigen Algorithmus für ein bestimmtes Problem?
      Um den richtigen Algorithmus zu finden, identifiziere erstmal das Problem klar. Analysiere die Anforderungen bezüglich Zeit- und Speicherkomplexität. Suche nach bekannten Algorithmus-Mustern oder -Kategorien, die dein Problem adressieren. Vergleiche verschiedene Algorithmen durch Testen und Analysieren ihrer Effizienz.
      Wie kann ich mit dem Debuggen von Algorithmen beginnen?
      Um mit dem Debuggen von Algorithmen zu beginnen, prüfe zunächst den Code auf Syntaxfehler. Verwende Debugger-Tools, um den Code schrittweise auszuführen und Variablenwerte zu überwachen. Füge Log-Ausgaben hinzu, um den Programmfluss zu verstehen. Teste den Algorithmus mit verschiedenen Eingaben, um Fehler zu identifizieren.
      Welche Online-Ressourcen eignen sich am besten zum Selbststudium von Algorithmen und Programmierung?
      Plattformen wie Coursera, edX und Udemy bieten eine Vielzahl von Kursen an. Der Online-Ratgeber "GeeksforGeeks" und die Community "Stack Overflow" sind ebenfalls wertvolle Ressourcen. Codecademy und Khan Academy bieten interaktive Lernmöglichkeiten. Bücher wie "Introduction to Algorithms" von Cormen et al. ergänzen das Studium.
      Erklärung speichern

      Teste dein Wissen mit Multiple-Choice-Karteikarten

      Was ist eine wesentliche Funktion von Datenstrukturen in der Programmierung?

      Was sind Beispiele für einfache Übungen in der Programmierung?

      Welche lineare Datenstruktur wird verwendet, wenn die Reihenfolge LIFO (Last In, First Out) ist?

      Weiter

      Entdecken Lernmaterialien mit der kostenlosen StudySmarter App

      Kostenlos anmelden
      1
      Über StudySmarter

      StudySmarter ist ein weltweit anerkanntes Bildungstechnologie-Unternehmen, das eine ganzheitliche Lernplattform für Schüler und Studenten aller Altersstufen und Bildungsniveaus bietet. Unsere Plattform unterstützt das Lernen in einer breiten Palette von Fächern, einschließlich MINT, Sozialwissenschaften und Sprachen, und hilft den Schülern auch, weltweit verschiedene Tests und Prüfungen wie GCSE, A Level, SAT, ACT, Abitur und mehr erfolgreich zu meistern. Wir bieten eine umfangreiche Bibliothek von Lernmaterialien, einschließlich interaktiver Karteikarten, umfassender Lehrbuchlösungen und detaillierter Erklärungen. Die fortschrittliche Technologie und Werkzeuge, die wir zur Verfügung stellen, helfen Schülern, ihre eigenen Lernmaterialien zu erstellen. Die Inhalte von StudySmarter sind nicht nur von Experten geprüft, sondern werden auch regelmäßig aktualisiert, um Genauigkeit und Relevanz zu gewährleisten.

      Erfahre mehr
      StudySmarter Redaktionsteam

      Team Informatik Lehrer

      • 13 Minuten Lesezeit
      • Geprüft vom StudySmarter Redaktionsteam
      Erklärung speichern Erklärung speichern

      Lerne jederzeit. Lerne überall. Auf allen Geräten.

      Kostenfrei loslegen

      Melde dich an für Notizen & Bearbeitung. 100% for free.

      Schließ dich über 22 Millionen Schülern und Studierenden an und lerne mit unserer StudySmarter App!

      Die erste Lern-App, die wirklich alles bietet, was du brauchst, um deine Prüfungen an einem Ort zu meistern.

      • Karteikarten & Quizze
      • KI-Lernassistent
      • Lernplaner
      • Probeklausuren
      • Intelligente Notizen
      Schließ dich über 22 Millionen Schülern und Studierenden an und lerne mit unserer StudySmarter App!
      Mit E-Mail registrieren