Mindmap-Galerie C-Sprache und Datenstrukturen
Die Grundkenntnisse in Bezug auf die C-Sprache und die Datenstruktur wurden organisiert und die Grammatik wurde durch Beispiele ergänzt und erklärt, um das Verständnis zu erleichtern. Es kann als Nachschlagewerk zum Finden von Grammatiken verwendet werden und kann auch zum Erlernen und Verstehen dieser verwendet werden zwei Teile.
Bearbeitet um 2023-08-16 21:39:05Welche Preismethoden gibt es für Projektunteraufträge im Rahmen des EPC-Generalvertragsmodells? EPC (Engineering, Procurement, Construction) bedeutet, dass der Generalunternehmer für den gesamten Prozess der Planung, Beschaffung, Konstruktion und Installation des Projekts verantwortlich ist und für die Testbetriebsdienste verantwortlich ist.
Die Wissenspunkte, die Java-Ingenieure in jeder Phase beherrschen müssen, werden ausführlich vorgestellt und das Wissen ist umfassend. Ich hoffe, es kann für alle hilfreich sein.
Das Software-Anforderungs-Engineering ist ein Schlüsselkapitel für Systemanalytiker. Zu den Kapiteln „Anforderungserhebung“ und „Anforderungsanalyse“ gehören häufig Veröffentlichungen.
Welche Preismethoden gibt es für Projektunteraufträge im Rahmen des EPC-Generalvertragsmodells? EPC (Engineering, Procurement, Construction) bedeutet, dass der Generalunternehmer für den gesamten Prozess der Planung, Beschaffung, Konstruktion und Installation des Projekts verantwortlich ist und für die Testbetriebsdienste verantwortlich ist.
Die Wissenspunkte, die Java-Ingenieure in jeder Phase beherrschen müssen, werden ausführlich vorgestellt und das Wissen ist umfassend. Ich hoffe, es kann für alle hilfreich sein.
Das Software-Anforderungs-Engineering ist ein Schlüsselkapitel für Systemanalytiker. Zu den Kapiteln „Anforderungserhebung“ und „Anforderungsanalyse“ gehören häufig Veröffentlichungen.
C-Sprache und Datenstrukturen
Fragmentierung der C-Sprache
Gängige Escape-Zeichen
Bild
system("cls") und system("pause") [Bildschirmlöschfunktion und Pausenfunktion]
Betreiberauftrag
Zeiger
Zeigerbezogene Konzepte
Zeigervariable: Die C-Sprache schreibt vor, dass zum Speichern der Adresse (der Anzahl der Bytes im Speicher) nur eine spezielle [Variable] verwendet werden kann. Dieser Typ wird als Zeigertyp bezeichnet.
Zeiger: Bei einer Speichereinheit ist die Adresse der Speichereinheit der Zeiger.
Hinweis: Da die erforderliche Variable über die Adresse gefunden werden kann, nennt die C-Sprache die Adresse anschaulich einen Zeiger.
Persönliche Beschreibung von Zeigervariablen: Zeigervariablen sind eine spezielle Art von Variablen, die [nur] die [Adresse] von [Variablen desselben Typs] oder 0 speichern können. Auf den Wert der Variablen kann [indirekt zugegriffen] werden Adresse und [Zugriff auf den Speicher] Die Adresse dient zur bequemeren Bedienung der Adresse in der Speichereinheit.]
Verwendung: Weisen Sie [Zeigervariable] die erste Adresse der Variablen und die erste Adresse anderer Datenstrukturen zu.
Definition und Initialisierung von Zeigervariablen
Die Definition der Zeigervariablen: sollte [Datentypname] und [Name der Zeigervariablen] enthalten.
Format: Datentypname * Zeigervariablenname 1, * Zeigervariablenname 2 oder definieren Sie einen separat und definieren Sie ihn dann zum Abschluss mehrmals.
Hinweis: Die in Zeigervariablen gespeicherten Daten müssen die [Adresse] von [Variablen desselben Typs] sein. Dies ist auch der Grund, warum bei der Definition ein Datentypname erforderlich ist gleich]. Wenn wir definieren, dass der Typ der Variablen mit dem Typ des Zeigers übereinstimmt, kann dem Zeiger die erste Adresse der in der Variablen gespeicherten Daten zugewiesen werden.
Initialisierung von Zeigervariablen: Zuerst definieren und dann initialisieren oder beim Definieren initialisieren. Andernfalls ist es falsch.
Format: Datentypname * Zeigervariablenname = Anfangswert;
Hinweis: Der Anfangswert ist die Adresse. Wenn Sie also die Variablenadresse einer Zeigervariablen zuweisen, müssen Sie den Adressoperator verwenden.
Zusammenfassung: Während der Definition und Initialisierung nennt das Buch viele Probleme, die Aufmerksamkeit erfordern, aber diese Probleme drehen sich alle um Definitionen und Konzepte. Solange Sie [die von Ihnen selbst zusammengefasste Erzählung] im Auge behalten, können diese Probleme durch Konzepte gelöst werden.
Zeigervariablenreferenz
Methode: In der C-Sprache kann der Verweis auf Zeigervariablen durch [* Wertoperator] und [& Adressoperator] vervollständigt werden.
Hinweis: Beim Definieren muss auf die Priorität, die Reihenfolge der Operationen und das Verständnis der speziellen *Adressoperation geachtet werden [sie dient bei der Definition nicht als Wert]
Kernpunkt: Bei der Anwendung von zwei- und mehrdimensionalen Arrays wird es einige Besonderheiten geben, die in [Darstellung von Zeigern und mehrdimensionalen Arrays] erlernt werden können.
Zusammenfassung: Nachdem eine Zeigervariable korrekt definiert und initialisiert wurde und die Zeigervariable p ist, ist „p“, wenn sie zu diesem Zeitpunkt verwendet wird, eine Variable, die die Adresse speichert (z. B. den Wert von p drucken und als Adresse anzeigen). , und durch Annehmen des Werts Der [*]-Operator kann den Wert von [die Adresse zeigt auf die Variable] erhalten.
Hinweis: Wenn die Definition der Zeigervariablen abgeschlossen ist und die Operation nicht die auf die Variable verweisenden Daten, sondern nur die Adresse in der Zeigervariablen betrifft, fügen Sie bitte kein *-Zeichen hinzu und umgekehrt. (Weitere Informationen finden Sie im Abschnitt [Zeigeroperationen].
Beispiel:
Zeigerarithmetik [Spezialität]
Methode: Die Operationen von Zeigervariablen werden im Allgemeinen in Addition und Subtraktion unterteilt. Zeiger können ganze Zahlen addieren oder subtrahieren, diese Operation von Zeigern unterscheidet sich jedoch von den üblichen Operationen.
Zusammenfassung: Aufgrund der Beziehung zwischen Speichereinheiten und Zeigern handelt es sich bei dieser Operation nicht nur um die Addition und Subtraktion von Adressen, sondern um die „Addition und Subtraktion des Produkts“ von [Anzahl] und [Bytegröße des entsprechenden Datentyps]. Gleichzeitig wird aufgrund der Adresse der Variablen die Startadresse der Speichereinheit verwendet. Daher werden die durch Zeigeroperationen generierten Ergebnisse der Adressaddition und -subtraktion durch die Bytegröße des entsprechenden Datentyps bestimmt direkter Adresswert plus oder minus einer Ganzzahl.
Beispiel: [Es ist ersichtlich, dass sich der Wert der Variablen im Zeiger um 16 geändert hat, was das Produkt der subtrahierten 4 und der grundlegenden ganzzahligen Anzahl von Bytes 4 ist]
Zeiger und Arrays
Beachten
Die Verbindung zwischen Zeigern und Arrays: Der Array-Name ist weder eine Zeigerkonstante noch ein konstanter Zeiger. Irgendwann kann er zu einem Zeiger degenerieren, der auf das erste Element des Arrays zeigt in einen Zeigertyp umgewandelt.
Beispiel: Wenn Sie einen Array-Namen an eine Funktion übergeben, die Zeigertypparameter akzeptiert, wird der Array-Name in den entsprechenden Zeigertyp konvertiert.
Vorteile: Da Array-Indizes während der Kompilierung in Zeiger umgewandelt werden müssen, kann die direkte Verwendung von Zeigern die Systemkompilierungszeit verkürzen.
Hinweis: Sie müssen bei der Verwendung berücksichtigen, ob das Array außerhalb der Grenzen liegt, und Sie müssen dies auch bei der Verwendung von Zeigern berücksichtigen.
Verweis auf Array-Element
Indexmethode: Wird durch einen Array-Index ausgedrückt. Einzelheiten finden Sie im Abschnitt „Array“.
Zeigermethode: Alle Elemente des Arrays werden durch Zeigeroperationen dargestellt. Dabei ist auf die Besonderheit der Zeigeroperation zu achten, die in der Zeigeroperation zusammengefasst wurde.
Ergänzung: Es ist ersichtlich, dass bei einfachen Ganzzahltypen jede Variable 4 Bytes belegt. Wenn Sie Zeigeroperationen verwenden, um auf Array-Variablen zu zeigen, können Sie Ganzzahlen direkt addieren oder subtrahieren, ohne die Anzahl der Bytes zu addieren.
Kernpunkt: Die Indexmethode und die Zeigermethode sind in nachfolgenden Studien eng miteinander verbunden, insbesondere in der Verbindung zwischen Zeigern und mehrdimensionalen Arrays. Detaillierte Beispiele für die Darstellung der Zeigermethode finden Sie in [Darstellung von Zeigern und mehrdimensionalen Arrays].
Darstellung von Zeigern und mehrdimensionalen Arrays
Eigenschaften mehrdimensionaler Arrays: In allen Arrays verwenden wir Indizes, um Arrays mit unterschiedlichen Dimensionen darzustellen. Wenn der Index kleiner als die Dimension ist, stellt er die Adresse dieser Dimension anstelle dieser Dimension dar. Der Wert der Zahl. Bei mehrdimensionalen Array-Zeigeroperationen gibt der Array-Name beim Addieren oder Subtrahieren die erste Adresse des hinzugefügten Werts an, und der Wertoperator muss zweimal verwendet werden.
Beispiel:
Zeiger und eindimensionale Arrays
Format: Zeigervariablenname = Array-Name
Zusammenfassung: Eindimensionale Arrays und Zeiger sind eng miteinander verbunden. Der Array-Name wird der definierten Zeigervariablen zugewiesen, sodass die Array-Elemente durch Zeigeroperationen dargestellt werden.
Zeiger und zweidimensionale Arrays
Zusammenfassung: Es gibt zwei Möglichkeiten, zweidimensionale Arrays darzustellen. Die erste Möglichkeit besteht darin, die erste Hälfte des Indexes als Adresse zu verwenden und Adressoperationen zu verwenden, um andere Elemente im Array darzustellen Elemente dargestellt werden. Der zweite Typ wird durch den Array-Namen und den Wertoperator dargestellt. Wenn * zum ersten Mal verwendet wird, stellt es immer noch die Adresse dar. Nur wenn * zweimal gleichzeitig verwendet wird Zeit kann es die Adresse darstellen, auf die verwiesen wird.
Hinweis: In der obigen Erklärung unterscheidet sich die Verwendung von Array-Namen plus Zeigern zur Darstellung von Array-Elementen völlig von der Verwendung von Zeigervariablen zur Darstellung von Array-Elementen. Eine falsche Verwendung führt zu Programmfehlern. [Später gibt es spezielle Zeigervariablen zur Darstellung von Arrays]
Zeigervariable, die auf ein zweidimensionales Array zeigt
Grund: Bei einem zweidimensionalen Array kann der Array-Name nicht wie bei einem eindimensionalen Array direkt der definierten Zeigervariablen zugewiesen werden. Daher wurde eine Zeigervariable geboren, die speziell auf ein zweidimensionales Array zeigt.
Definitionsformular: Datentypname (*Zeigervariablenname)[Anzahl der Elemente]
Formale Erklärung: [Anzahl der Elemente] gibt an, dass die Zielvariable ein eindimensionales Array ist, und gibt die Anzahl der Elemente im eindimensionalen Array an. Die Klammern sind darauf zurückzuführen, dass die Priorität der Operation genau angegeben werden muss, andernfalls wird dies der Fall sein führen zur Definition einer Zeigervariablen, die nicht auf ein zweidimensionales Array zeigt.
Merkmale: Nachdem dieser Variablen ein Wert zugewiesen wurde, entspricht dies der Darstellung der Array-Elemente in einem zweidimensionalen Array durch den Array-Namen und den Wertoperator. [Die Anzahl der folgenden Elemente stellt die Anzahl der Array-Spalten dar]. Dies entspricht der Zuweisung des Arrays mit der ersten Hälfte des Indexes, also der Adresse des ersten Elements jeder Dimension des Arrays, zu dieser Variablen. [Der letzte Satz wird im Abschnitt „Zeiger und zweidimensionale Arrays“ ausführlich erläutert.]
Erläuterung zu [Anzahl der Elemente]: Die Zahl gibt die Anzahl der Spalten an, die dem Array entsprechen
Array von Zeigern
Hinweis: Array-Elemente sind alle Elemente vom Zeigertyp, das heißt, jedes Element im Zeiger-Array speichert eine Zeigervariable.
Deklarationsformat
Allgemeines Deklarationsformat: <Speichertyp><Datentyp>*<Array-Name>[<Array-Länge>];
Vollständiges Deklarationsformat: <Speichertyp><Datentyp>*<Array-Name>[<Array-Länge>]={Anfangswertliste};
Hinweis: Definition und Zuordnung sollten trennbar sein und werden hier nicht im Detail erläutert.
Wichtig: Die Elemente in einem Array von Zeigern sind sowohl Array-Elemente als auch Zeiger. Achten Sie daher bei der Referenzierung sowohl auf die Eigenschaften ihrer Array-Elemente als auch auf ihre Zeigereigenschaften. [Sie können Indizes verwenden, um auf Array-Elemente zu verweisen, oder Sie können Array-Namen verwenden, um auf die Adressen entsprechender Speicherorte zu verweisen. Wenn das Array-Element selbst ein Zeiger ist, achten Sie darauf, den Wertoperator zu verwenden, um auf die Variable zuzugreifen, auf die der Zeiger zeigt.]
Vergleich zwischen Zeichenzeiger-Array und zweidimensionalem Array
Der Unterschied: Letzteres belegt beim Speichern kontinuierlich Speicherplatz. Ersteres ist ein verstreuter Speicherraum.
Merkmale zweidimensionaler Zeichenarrays: Wenn ein zweidimensionales Array eine Zeichenfolge darstellt, muss es einen kontinuierlichen Speicherplatz belegen, aber ein Großteil des Speicherplatzes in der Mitte kann leer sein. Daher müssen Sie beim Definieren die Anzahl der Spalten als längste Zeichenfolge plus eins angeben.
Zeiger und Strings
Zeiger auf String
Vorteile: Wenn einem Zeiger eine Adresse zugewiesen wird, ändert sich der Zeiger des Zeigers entsprechend. Wenn wir Zeichenzeigervariablen verwenden, ist es daher bequemer, Zeichenfolgen zu verarbeiten.
Referenzmethode: Definieren Sie einen Zeichenzeiger und verwenden Sie ihn, um auf die Startadresse der Zeichenfolge zu verweisen, um auf die Zeichenfolge zu verweisen. Zu diesem Zeitpunkt ist die Verwendung des Adressoperators nicht erforderlich.
Format definieren
char *Zeigervariablenname;
char *Zeiger-Variablenname = String-Konstante;
Hinweis: Sie können es zuerst definieren und dann initialisieren, oder Sie können es gleichzeitig tun.
Ausgabemethode: Geben Sie die Zeichenfolge über %s und den Namen der Zeichenzeigervariablen aus. Wenn Sie ein bestimmtes Zeichen in einer Zeichenfolge ausgeben möchten, können Sie mithilfe der Zeigerarithmetik die Adresse, auf die der Zeichenzeiger zeigt, in die Adresse des bestimmten Zeichens ändern.
Der Unterschied zwischen Zeichenzeigern und Zeichenarrays
Erstens: Der Name der Zeichenzeigervariablen kann mehrfach zugewiesen werden, der Name des Zeichenarrays ist jedoch eine Adresskonstante und kann nicht zugewiesen werden. Zweitens ist die Größe des Arrays festgelegt und es muss im Voraus Speicherplatz zugewiesen werden.
Zweitens: Der Typ und die belegte Speichereinheit sind unterschiedlich. Ersteres ist die erste Adresse der Zeichenfolge und letzteres ist der zugewiesene Speicherplatz.
Drittens: Die Elemente im Array können neu zugewiesen werden, aber wir können den Wert der Zeichenkonstanten nicht indirekt über einen Zeichenzeiger ändern, da sonst die Folgen unvorhersehbar sind.
Zusammenfassung: Der Zeichenzeiger ist eine Variable, die mehrfach direkt zugewiesen werden kann und auf die erste Adresse der Zeichenfolge zeigt. Die Größe des Zeichenarrays ist fest und die Elemente im Array werden mehrfach zugewiesen. Bei der direkten Zuweisung von Werten müssen diese während der Initialisierung zugewiesen werden. Sie können für die Zuweisung auch Eingabefunktionen verwenden, aber keine Zuweisungsanweisungen.
Zeiger und Funktionen
Zeigervariable als Funktionsparameter übergeben
Zweck: Verwenden Sie Zeiger als Funktionsparameter, um sicherzustellen, dass die an den formalen Parameter übergebene Adresse die Adresse ist. Da von der aufgerufenen Funktion an Parametern vorgenommene Änderungen nicht an die Hauptfunktion übergeben werden, werden manchmal Zeigervariablen als Funktionsparameter verwendet, um solche Änderungen zu speichern.
Zu den Funktionen gehören: gemeinsam genutzter Speicher, bidirektionale Übertragung
Erläuterung dieser Methode: Um diese Methode zu implementieren, müssen Sie sicherstellen, dass die übergebenen formalen Parameter Zeiger sind, und zweitens müssen Sie die formalen Parameter verwenden, um an der Funktion teilzunehmen. Sie müssen wissen, dass beim Ausführen einer Anweisung in einer Funktion nicht die Adresse des formalen Parameters an der Funktion beteiligt ist, sondern der formale Parameter. Aufgrund der Besonderheit des Zeigers erfolgt zu diesem Zeitpunkt die Transformation des formalen Parameters ist eigentlich die Transformation der Variablen in die Speicheradresse. Um die Richtigkeit sicherzustellen, habe ich es überprüft und unten ein Beispiel gegeben
Beispiele:
Zeiger auf Funktion (Funktionszeiger)
Grund: Funktionsnamen und Array-Namen haben ähnliche Eigenschaften. Der Funktionsname stellt die Startadresse der Funktion dar. Der Compiler verwendet den Funktionsnamen, um die Eintragsadresse der Funktion zu indizieren.
Definition des Funktionszeigers
Definition: Um Funktionen mit denselben Typattributen zu betreiben, führt die C-Sprache den Funktionszeiger ein. Wenn die erste Adresse der Funktion der Zeigervariablen zugewiesen wird, können wir die entsprechende Variable finden und aufrufen Funktion durch die Zeigervariable.
Definitionsformular: Datentypname (*Funktionszeigername)();
Erläuterung: Der Datentyp definiert den Rückgabewerttyp der Funktion. (*Name des Funktionszeigers) bestimmt die Zeigervariable, die auf die Funktion zeigt. () gibt an, dass das Objekt, auf das gezeigt wird, eine Funktion ist.
Initialisierung und Verwendung von Funktionszeigern
Funktionszeiger haben keinen unabhängigen Funktionscode und müssen initialisiert werden. Es gibt zwei Formen der Initialisierung: Eine besteht darin, den Funktionsnamen direkt zuzuweisen, und die andere darin, den Funktionsnamen über den Adressoperator zuzuweisen. Natürlich können Sie es auch gleichzeitig mit der Definition initialisieren und dann zwei Initialisierungsmethoden anwenden.
Initialisierungsmethode
Funktionszeigername = Funktionsname oder Funktionszeigername = & Funktionsname
Datentypname (*Funktionszeigername)( )=Funktionsname
Die allgemeine Form des Aufrufs einer Funktion mithilfe einer Funktionszeigervariablen
(*Name des Funktionszeigers)(aktuelle Parameterliste);
Funktion, die einen Zeigerwert zurückgibt
Der Funktionstyp wird durch den Rückgabewert bestimmt. Diese Funktion, deren Rückgabewert ein Zeiger ist, wird als Zeigerfunktion bezeichnet.
Definitionsformular: Datentyp * Funktionsname (Parameterliste);
Hinweis: Der Rückgabewert muss ein Variablenzeiger und Arrayzeiger einer externen oder statischen Speicherklasse sein.
Zeiger auf Zeiger
Definition: Wenn eine Zeigervariable die Adresse einer anderen Zeigervariablen speichert, wird die Zeigervariable als Zeigervariable bezeichnet, die auf einen Zeiger zeigt.
Definitionsformular: Datentypname **S
Erläuterung: Die Anzahl der *-Zeichen bestimmt die Ebene der Zeigervariablen. Nur Zeigervariablen desselben Typs und derselben Ebene können einander Werte zuweisen. Gleichzeitig muss der höherwertige Zeiger durch den benachbarten niedrigpreisigen Zeiger zugewiesen werden.
Verständnis: Weisen Sie einer bestimmten Variablen Ebene für Ebene Zeigervariablen zu. Sie verweisen alle auf die ursprüngliche Variable. Die Verwendung ähnelt der Zeigervariablen erster Ordnung.
Beispiele:
Zeiger und dynamische Speicherzuweisung
Da der Prototyp der dynamischen Speicherverwaltungsfunktion in der Standard-Header-Datei <stdlib.h> definiert ist, muss er bei Verwendung hinzugefügt werden.
Malloc-Funktion
Funktion: Malloc weist dem dynamischen Speicherbereich des Speichers einen kontinuierlichen Speicherplatz mit einer Länge zu. Der Parameter der Malloc-Funktion ist eine vorzeichenlose Ganzzahl und der Rückgabewert ist ein Zeiger, der auf die Startadresse des zugewiesenen dynamischen Speichers zeigt Bereich. Es ist zu beachten, dass die Malloc-Funktion einen Nullzeiger zuweist, wenn der Speicherplatz nicht erfolgreich zugewiesen werden kann. Wenn wir ihn also verwenden, müssen wir erkennen, ob der Rückgabewert ein Nullzeiger ist, und entsprechende Vorgänge ausführen. In der folgenden Abbildung kann der auszuführende Vorgang beispielsweise darin bestehen, Zuordnungsfehler anzuzeigen.
Prototyp: void *malloc(unsigned int size)
Erläuterung: void * ist der Typ des Rückgabewerts, unsigned int wird als vorzeichenlose Ganzzahl geschrieben und size wird zur Berechnung der Größe verwendet, z. B. size(int), das Ergebnis ist 4.
Beispiele:
Calloc-Funktion
Wichtiger Punkt: Der Unterschied zur Malloc-Funktion besteht darin, dass die Calloc-Funktion den zugewiesenen Speicherplatz zuerst auf Null initialisiert und die anderen im Grunde gleich sind.
Prototyp: void *calloc(num, size)
Erläuterung: Die Verwendung ist die gleiche wie bei der Funktion malloc. Wenn eine oder mehrere der Variablen num und size gleich Null sind, tritt ein Zuordnungsfehler auf.
Verwendung und Beispiele:
kostenlose Funktion
Grund: Da Speicher nicht unbegrenzt zugewiesen werden kann, müssen wir Ressourcen sparen. Daher muss nach Verwendung der dynamischen Speicherverwaltungsfunktion der zugewiesene Speicherplatz freigegeben werden, um die Verwendung anderer Variablen zu erleichtern.
Prototyp: void free (void *ptr)
Vorsichtsmaßnahmen
Undefiniertes Verhalten tritt auf, wenn free nicht auf zuvor zugewiesenen Speicherplatz verweist.
free gibt den zugewiesenen Speicherplatz frei, ändert jedoch nicht den ursprünglichen Wert von ptr. Das heißt, ptr zeigt immer noch auf die ursprüngliche Adresse, aber die Adresse ist nicht mehr gültig.
Wenn ptr ein Nullzeiger ist, führt diese Funktion nichts aus
Nach der Freigabe muss ptr leer gesetzt werden, ptr=NULL, andernfalls kommt es zu einem Fehler, wenn erneut auf die Variable ptr zugegriffen wird.
Free kann nicht wiederholt freigegeben werden, da sonst Fehler auftreten
Verwendung und Beispiele
Kostenlos: Unter der Voraussetzung, dass die Korrektheit gewährleistet ist, wird der von malloc und calloc zurückgegebene Nicht-Null-Zeiger nur einmal freigegeben. Nach der Freigabe muss er leer gemacht werden und die Ausrichtung des ursprünglichen Zeigers wird nicht geändert.
Die oben genannten drei Funktionen dienen nur als Referenz, sodass etwaige Mängel online gesucht werden können.
Beispiel für die Zusammenarbeit der Malloc-Funktion und der freien Funktion
Zeiger auf Strukturvariable
Erläuterung: Nachdem die Strukturvariable deklariert wurde, wird Speicherplatz im Speicher zugewiesen, und die Startadresse dieses Speicherplatzes ist die Adresse (Zeiger) der Strukturvariablen. Daher können wir über Zeiger darauf zugreifen, indem wir Zeigern Werte zuweisen. Achten Sie zu diesem Zeitpunkt auf die Definition von Zeigervariablen, die „nur [gleichen Typ] speichern können“, sodass dies bei unserer benutzerdefinierten Struktur nicht möglich ist direkt zugeordnet werden. Wir müssen zuerst einen Zeiger desselben Typs über diese Struktur definieren und dann dem Zeiger die Adresse der Strukturvariablen zuweisen.
Allgemeine Form: Strukturstrukturname * Zeigervariablenname oder (Name nach Typdefinition) * Zeigervariablenname
Erläuterung: Das Wesentliche ist die Definition von Zeigern, daher entspricht dies der Verwendung grundlegender Typdefinitionen. Daher hat der Name nach typedef auch den gleichen Effekt.
Hinweis: Wenn Sie einen Wert zuweisen, ermitteln Sie bitte die Adresse der Strukturvariablen. Der Zuweisungsprozess gehört zur Initialisierung der Zeigervariablen. Machen Sie sich also keine Sorgen.
Wichtiger Punkt: Sie können Zeigeroperationen verwenden, um auf die erste Adresse des Strukturarrays zu zeigen und dann indirekt auf die Variablen im Array zuzugreifen. Beispiel: Array a - a[1]=*(a 1), a[1][1]=*(*(a 1) 1). [Wenn Sie eine Zeigervariable verwenden, ist die Methode dieselbe wie die Array-Namensmethode und Sie müssen sie nur einfach ersetzen.]
Erkennung: Sie können den Strukturnamen direkt verwenden, um Variablen zu definieren, die auf die Struktur in der Struktur verweisen. 【Zweifelhaft】
Form: Strukturname * Zeigervariablenname; [zu diesem Zeitpunkt ohne Struktur]
Umfassendes Diagramm von Zeigern, Arrays, Funktionen und Strukturen
Zeigerkonstante [Variante des Zeigertyps, die verwendet wird, um die Änderung der Adresse zu begrenzen, auf die gezeigt wird]
Definition: Die Essenz ist eine Konstante und wird mit einem Zeiger modifiziert. Der Wert einer Zeigerkonstante ist ein Zeiger. Da dieser Wert eine Konstante ist, kann er nicht zugewiesen werden.
Codeform: int* const p;
Wirkung: Es handelt sich um eine Konstante. Der Zeiger kann nur auf die angegebene Adresse zeigen und kann nicht geändert werden, aber der Wert in der Adresse kann geändert werden [ähnlich dem Array-Namen, aber anders].
Konstanter Zeiger [Variante des Zeigertyps, die verwendet wird, um die Änderung des Werts, auf den gezeigt wird, zu begrenzen]
Definition: Wird auch als Konstantenzeiger bezeichnet und kann als Konstantenzeiger verstanden werden, dh es handelt sich um einen Zeiger, der jedoch auf eine Konstante zeigt die Adresse.
Codeform: int const* p;
Wirkung: Adressen einschließlich Variablen können akzeptiert und beliebig auf eine Adresse verwiesen werden. Der Variablenwert kann jedoch nicht durch Ändern des Zeigers geändert werden.
Häufig verwendete Eingabe- und Ausgabefunktionen
Über das Konzept der Eingabe- und Ausgabefunktionen
Die sogenannte Eingabe und Ausgabe basiert hauptsächlich auf dem Computerhost und wird über Eingabegeräte und Ausgabegeräte vervollständigt.
Die C-Sprache selbst verfügt über keine Eingabe- und Ausgabefunktionsanweisungen, bietet jedoch eine Fülle von Eingabe- und Ausgabefunktionsbibliotheksfunktionen. Die Standard-Eingabe- und Ausgabe-Standardbibliotheksfunktionen sind in der Header-Datei stdio.h definiert (englische Abkürzung, keine weiteren Details). ). Wenn Sie diese Bibliotheksfunktionen verwenden, müssen Sie den Makrobefehl #include verwenden, um die Header-Datei in die Quelldatei einzubinden.
So verwenden Sie #include
#include <stdio.h>
Erläuterung: Suchen Sie die angegebene Datei im Include-Verzeichnis.
#include „stdio.h“
Erläuterung: Suchen Sie zuerst in dem Verzeichnis, in dem sich die Quelldatei befindet, und suchen Sie dann auf die Standardmethode.
Zeicheneingabe und -ausgabe
Zeicheneingabefunktion
Einschränkung: Kann nur auf die Eingabe von [einzelnem Zeichen] angewendet werden.
So verwenden Sie die drei: Weisen Sie die Eingabezeichen Zeichenvariablen oder Ganzzahlvariablen zu, die als Zuweisungsanweisungen dienen oder als Teil der Operation an Operationen teilnehmen können.
Verständnis: Die Zeicheneingabefunktionen sind in stdio.h definiert und haben keine Parameter.
getchar (kann zum Löschen des Puffers verwendet werden, d. h. als Pausentaste fungieren)
Einschränkung: Es wird nur das erste Zeichen empfangen. Wird eine Zahl eingegeben, wird diese als Zeichen verarbeitet. Für eine erfolgreiche Eingabe müssen Sie die Eingabetaste drücken und werden auf dem Bildschirm angezeigt.
Format: getchar(); oder Variablenname=getchar();
getche
Erläuterung: Im Grunde ähnlich wie getchar, mit dem Unterschied, dass es ohne Wagenrücklauf auf dem Bildschirm angezeigt wird
getch
Erläuterung: Im Grunde ähnlich, der Unterschied zu Getche besteht darin, dass es nicht auf dem Bildschirm wiedergegeben wird.
Beispiele
Zeichenausgabefunktion
putchar
Verwendungsformat: putchar (formeller Parameter);
Erläuterung: Geben Sie ein einzelnes Zeichen auf dem Bildschirm aus, wobei die formalen Parameter Zeichenkonstanten, Zeichenvariablen und Ausdrücke sein können. Wenn der formale Parameter ein Steuerzeichen ist, wird die Steuerfunktion ausgeführt. Da das Steuerzeichen unsichtbar ist, können nur die Cursorposition geändert und Geräusche visuell beobachtet werden.
String-Verarbeitungsfunktion [definiert in der Header-Datei <string.h>]
String-Ausgabefunktion puts
Format: puts (Name/Zeichenfolge des Zeichenarrays)
Funktion: Geben Sie eine Zeichenfolge auf dem Computerbildschirm aus und brechen Sie die Zeichenfolge um, nachdem die Ausgabe abgeschlossen ist.
Hinweis: Das Zeichenarray muss mit „\0“ enden.
String-Eingabefunktion erhält
Format: erhält (Zeichenarray)
Funktion: Geben Sie über die Tastatur eine Zeichenfolge ein, die mit einem Wagenrücklauf endet, und fügen Sie sie in das Zeichenarray ein. Fügen Sie dann am Ende automatisch „\0“ hinzu, um einen Funktionswert zu erhalten, der die Startadresse des Zeichenarrays darstellt.
Beschreibung: Die Eingabezeichenfolge sollte kleiner sein als die Länge des Zeichenarrays.
String-Verkettungsfunktion strcat
Format: strcat (Zeichenarray 1, Zeichenarray 2)
Funktion: Verbinden Sie die Zeichenfolge in Zeichen-Array 2 mit Zeichen-Array 1, entfernen Sie „\0“ am Ende der Zeichenfolge in Zeichen-Array 1 und behalten Sie „\0“ am Ende von Zeichenfolge 2 bei.
Hinweis: Zeichenarray 1 muss groß genug sein. Der Rückgabewert dieser Funktion ist die erste Adresse von Zeichenarray 1.
String-Kopierfunktion strcpy
Format: strcpy (Zeichenarray 1, Zeichenarray 2)
Funktion: Weisen Sie die Zeichenfolge im Zeichenarray 2 dem Zeichenarray 1 zu, einschließlich des abschließenden „\0“. Das Zeichenarray 2 kann auch eine Zeichenfolgenkonstante sein, was der Zuweisung einer Zeichenfolge zu einem Zeichenarray entspricht.
Hinweis: Das Zeichenarray 1 muss groß genug sein und Zuweisungsanweisungen können nicht zum Zuweisen von Werten zum Zeichenarray verwendet werden.
String-Vergleichsfunktion strcmp
Format: strcmp (Zeichenarray 1, Zeichenarray 2)
Funktion: Vergleichen Sie zwei Zeichenfolgen von links nach rechts [das Zeichen ASCLL wird verglichen], bis sie auf Unterschiede oder „\0“ stoßen.
Ersteres ist gleich letzteres und der Rückgabewert ist 0
Ersteres ist größer als letzteres und der Rückgabewert ist eine positive Ganzzahl
Wenn ersterer kleiner als letzterer ist, ist der Rückgabewert eine negative ganze Zahl
Hinweis: Beim Vergleich von Zeichenfolgen kann nur strcmp verwendet werden. Es kann zwischen String-Konstanten und sogar zwischen Zeichen-Arrays und String-Konstanten verwendet werden.
Funktion zur Messung der Stringlänge strlen
Format: strlen (Zeichenarray)
Funktion: Messen Sie die tatsächliche Länge der Zeichenfolge [ohne „\0“] und verwenden Sie sie als Rückgabewert.
Andere Funktionen zur Zeichenfolgenverarbeitung
Format: strupr (Zeichenarray), Funktion: alle Zeichen in Großbuchstaben umwandeln
Format: strlwr (Zeichenarray), Funktion: alle Zeichen in Kleinbuchstaben umwandeln
Format: strset (Zeichenarray, Zeichen), Funktion: alle Zeichen in bestimmte Zeichen umwandeln
Eingabe- und Ausgabefunktionen zur Formatsteuerung
Ausgabefunktion zur Formatsteuerung
Definition: Die printf-Funktion wird als Ausgabefunktion zur Formatsteuerung bezeichnet
Definitionsort: <stdio.h>
Grundformat: printf("Format-Steuerzeichenfolge", Parameter 1, Parameter 2,...);
Erweiterung: Die Formatsteuerzeichenfolge besteht aus zwei Teilen, ein Teil ist eine normale Zeichenfolge oder eine Escape-Zeichenfolge. Der andere Teil ist die Formatdeklarationszeichenfolge. Ersteres wird so gedruckt, wie es ist, und letzteres ist entsprechend der Funktion wirksam.
Parameter: können Konstanten und Variablen, Ausdrücke oder Funktionsaufrufe sein
Die beiden müssen in einer Eins-zu-Eins-Entsprechung vorliegen, wird der falsche Wert ausgegeben oder kann nicht ausgegeben werden [da der Compiler nur das aufrufende Formular prüft und die Formatkontrollzeichenfolge nicht analysiert]. Gleichzeitig wird bei der Datenausgabe allen Datentypen entsprechend der Formatzeichen-Steuerzeichenfolge Priorität eingeräumt.
Deklaration des printf-Funktionsformats
Vollständiges Format: %[Flag][Ausgabe-Mindestbreite].[Präzision][Länge] Typ
%: Es ist das Startsymbol und unerlässlich
Flags: Ausfüllbare Optionen, -, 0, #, Leerzeichen [hauptsächlich Hilfsfunktionen für die Ausgabe]
Minimale Ausgabebreite: Dies bezieht sich auf die Feldbreite, also die Anzahl der angezeigten Zeichen. Wenn sie kleiner ist, wird standardmäßig die rechte Ausrichtung und die linke Auffüllung verwendet. Wenn es größer ist, geben Sie es unverändert aus.
Genauigkeit: Die Anzahl der angezeigten gültigen Dezimalstellen. Überschüssige Stellen werden abgerundet.
Länge: ll oder h, l ist long für Integer-Typen, double für Real-Typen, h wird verwendet, um Integer-Typen in Short-Typen zu ändern
Typ: Geben Sie den Typ der Ausgabedaten an. [Es wird empfohlen, die allgemeinen im Hinterkopf zu behalten]
Die Auswertungsreihenfolge von printf: Die Reihenfolge ist in verschiedenen Kompilierungssystemen unterschiedlich. In VC ist sie von rechts nach links [sehr wichtig, seien Sie klar].
Eingabefunktion zur Formatsteuerung
Definition: Die Scanf-Funktion wird als Formatsteuerungsausgabefunktion bezeichnet
Definitionsort: <stdio.h>
Grundformat: scanf("Format-Steuerzeichenfolge", Adresse 1, Adresse 2,...);
Erweiterung: Die Formatsteuerzeichenfolge enthält ein oder mehrere Formatsteuerzeichen, die mit % beginnen, und auf % folgen ein oder mehrere Formatsteuerzeichen, die zum Belegen von Stellen verwendet werden, damit sie den nachfolgenden Adressen entsprechen können. Verwenden Sie die Formatsteuerzeichen Bestimmen Sie das Dateneingabeformat
Deklaration der Scanf-Funktion
Vollständige Formatdeklaration: Typ %[*][Eingabebreite][Länge].
%: Das Startzeichen der Formatdeklaration, unverzichtbar.
[*]: Lesen, aber nicht zuweisen, beim Zuweisen überspringen
Eingabebreite: die Anzahl der eingegebenen gültigen Zeichen
Länge: l oder h. Wenn es sich um eine Ganzzahl handelt, ist erstere eine lange Ganzzahl und letztere eine kurze Ganzzahl. Wenn es sich um einen echten Typ handelt, handelt es sich um einen Doppeltyp.
Typ: ähnlich wie printf
Eine Beschreibung der Scanf-Funktion
Das Format ist sehr wichtig, bitte achten Sie darauf, es im vollständigen Format zu verwenden, sonst kommt es zu einem Fehler.
Die Formatsteuerzeichen und Adressen müssen übereinstimmen, sonst ist das Programm nicht erkennbar. Wenn Zeichen zwischen Formatsteuerzeichen stehen, müssen auch Zeichen zwischen Adressen hinzugefügt werden.
Datentyp (eine Sammlung von Werten und der Sammelname aller für diese Sammlung definierten Operationen)
Grund: In der Mathematik werden Daten nicht klassifiziert. Da der Speicherplatz in Computern jedoch durch die physische Hardware begrenzt ist, ist es unmöglich, unendlich große oder unendlich viele Dezimalzahlen zu speichern. Daher ist eine Klassifizierung der Daten erforderlich.
Grundtyp
ganze Zahl
Kenntnisse im Zusammenhang mit ganzzahligen Daten
Definition: durch int definierte Variable
Darstellungsmethode: In der C-Sprache kann sie dezimal, oktal und hexadezimal ausgedrückt werden.
Speichermethode: Im Computer werden positive Zahlen im Originalcode und negative Zahlen im Komplementformat gespeichert.
Einstufung
Umfang
kurz
Belegte Bytes: 2 Bytes
[Signiert] Darstellungsbereich: -2 bis 15. Potenz ~ 2 bis 15. Potenz -1
[Ohne Vorzeichen] Darstellungsbereich: 0~2 bis zur 16. Potenz
Grundlegender Ganzzahltyp (int)
Belegte Bytes: 4 Bytes
[Signiert] Darstellungsbereich: -2 hoch 31 ~ 2 hoch 31 -1
[Ohne Vorzeichen] Darstellungsbereich: 0~2 bis zur 32. Potenz
lang
Belegte Bytes: 4 Bytes
[Signiert] Darstellungsbereich: -2 hoch 31 ~ 2 hoch 31 -1
[Ohne Vorzeichen] Darstellungsbereich: 0~2 bis zur 32. Potenz
lang Lang
Belegte Bytes: 8 Bytes
[Signiert] Darstellungsbereich: -2 hoch 63 bis 2 hoch 63 -1
[Ohne Vorzeichen] Darstellungsbereich: 0~2 erhöht auf die 64. Potenz
Symbol
Vorzeichenbehaftete Ganzzahl (signed int): Das höchste Bit der Speichereinheit ist das Vorzeichenbit, 0 ist positiv, 1 ist negativ und die anderen sind numerische Bits.
Unsigned int (unsigned int): Alle Binärbits werden zum Speichern von Werten ohne Vorzeichenbit verwendet.
Der Unterschied zwischen den beiden: Erstens ist der Unterschied zwischen positiv und negativ, und zweitens haben die beiden definierten Variablen unterschiedliche Zahlenbereiche, die dargestellt werden können, was im Bereich der grundlegenden Ganzzahltypen ausführlich erläutert wird.
echter Typ
Kenntnisse über reale Daten (Gleitkommadaten)
Darstellungsmethode (reelle Konstante): In Computern können reelle Konstanten in dezimaler und exponentieller Form ausgedrückt werden.
Speichermethode: In Computern werden reale Daten in Exponentialform gespeichert und reale Daten in einen Dezimalteil und einen Exponentialteil unterteilt. Die C-Sprache gibt nicht an, wie viele Ziffern Dezimalstellen und wie viele Ziffern Exponenten sind. Dies wird durch das Kompilierungssystem bestimmt. Im Allgemeinen verwenden die meisten Kompilierungssysteme 24 Dezimalstellen und 8 Exponenten. Ersteres steht für Präzision und letzteres für Reichweite.
Voraussetzungen für die Verwendung der Exponentialform
1. Das Format ist aEn, zum Beispiel 123, was 1,23E2 bedeutet
2. Dem Buchstaben E oder e muss eine Zahl vorangestellt und eine ganze Zahl gefolgt werden.
3. Standardisierung (nicht obligatorisch), das heißt, links vom Dezimalpunkt vor e befindet sich nur eine Zahl ungleich 0, und die folgende muss eine ganze Zahl sein.
Genauigkeit realer Daten
Grund: Der durch die physische Hardware begrenzte Computerspeicher ist nicht unendlich und kann daher nicht unendlich viele Dezimalstellen speichern. Daher handelt es sich bei den tatsächlichen Daten im Computer um Näherungswerte. [Dies ist auch der Fall, wenn reale Daten verglichen werden, im Allgemeinen kommt es darauf an, ob sie nahe beieinander liegen, nicht ob sie gleich sind.]
Vorsichtsmaßnahmen
Wenn Sie reale Daten verwenden, müssen Sie je nach Bedarf zwischen realen Daten mit einfacher oder doppelter Genauigkeit wählen.
Verwenden Sie keine Daten vom realen Typ, um [größere Ganzzahlen] darzustellen, da die [Speicherform] der Daten vom realen Typ im Computer dazu führt, dass die Daten einige Ziffern verlieren, wenn sie den Bereich des realen Typs überschreiten, sodass der Wert verloren geht ändern. .
Versuchen Sie zu vermeiden, eine zu kleine Zahl von einer großen Zahl zu subtrahieren, da dies zum Verlust der Dezimalzahl führen kann.
Computerverarbeitung von Konstanten vom realen Typ: Der Computer verarbeitet Konstanten vom realen Typ als Daten vom realen Typ mit doppelter Genauigkeit. Der Nachteil besteht darin, dass die Operationen reduziert werden. Fügen Sie nach einer reellen Konstante den Buchstaben f oder F hinzu, und der Computer behandelt sie als reelle Daten mit einfacher Genauigkeit. Durch Hinzufügen von l oder L werden diese als lange reale Daten mit doppelter Genauigkeit behandelt.
Einstufung
Genauigkeit
Reale Variable mit einfacher Genauigkeit (Float)
Belegte Bytes: 4 Bytes
Effektive Ziffern: 6
Bereich: -3,4e bis zur 38. Potenz ~ 3,4e bis zur 38. Potenz
Reale Variable mit doppelter Genauigkeit (double)
Belegte Bytes: 8 Bytes
Effektive Ziffern: 15
Bereich: -1,7e hoch 308~1,7e hoch 308
langes Doppel
Belegte Bytes: 8 Bytes oder 16 Bytes
Effektive Ziffern: 15 oder 19
Bereich: -1,7e hoch 308~1,7e hoch 308 oder -3,4e hoch 4932~3,4e hoch 4932 [verursacht durch Unterschiede bei den Compilern]
Charakterdaten
Zeichenvariable
Zeichenvariablen werden mit dem Schlüsselwort char definiert und bei der Definition wird ihnen ein Anfangswert zugewiesen.
Format: char-Variablenname;
Zeichenkonstante
Erläuterung: Es gibt zwei Formen von Zeichenkonstanten: eine sind gewöhnliche Zeichenkonstanten und die andere sind maskierte Zeichenkonstanten
Gewöhnliche Zeichenkonstanten: Verwenden Sie [' 'einfache Anführungszeichen], um ein [einzelnes] [Zeichen] einzuschließen und die entsprechende Kodierung (ASCII) im Speicher zu speichern. Es kann entweder als Zeichen oder als Zahl verarbeitet werden.
Escapezeichenkonstante: eine Zeichenfolge, die mit [Backslash\] beginnt. [Es wird empfohlen, häufig verwendete Escape-Zeichen zu verstehen]
Operationen an Zeichendaten
Beim Einfügen von Zeichen in eine Zeichenvariable speichert die Zeichenvariable den entsprechenden ASCII-Code. Er kann sowohl zur Zeichenverarbeitung als auch zur Datenverarbeitung verwendet werden (zu diesem Zeitpunkt ist ASCII an der Operation beteiligt), sodass er als Ganzzahlvariable verwendet werden kann. zu handhaben. Gleichzeitig können über Ausgabeanweisungen zwei Arten von Daten ausgegeben werden.
String-Konstante
Definition: [Zeichenfolge], eingeschlossen in [doppelte Anführungszeichen] und endend mit [\0] (durch die C-Sprache angegeben)
Zeichenvariablen können keine Zeichenfolgekonstanten zugewiesen werden
Es gibt keine Zeichenvariablen, es können jedoch Zeichenarrays und Zeichenzeiger verwendet werden
Das \0 am Ende nimmt ebenfalls ein Byte Platz ein, nur zwei doppelte Anführungszeichen, auch String-Konstante genannt, auch Leerstring genannt, mit einer Größe von einem Byte.
Hinweis: Zeichendaten belegen nur ein Byte im Speicher.
abstrakter Datentyp
Es kann durch inhärente Datentypen dargestellt und implementiert werden, was der Struktur in der C-Sprache etwas ähnelt
Algorithmen (nur Definitionen) und Programmkontrollstrukturen
Algorithmus
Grund: Computer sind immer ein Werkzeug zur Lösung praktischer Probleme. Es ist unvermeidlich, auf bestimmte Probleme und die von Algorithmen generierten Schritte und Methoden zur Lösung dieser Probleme zu stoßen.
Definition: Es handelt sich um einen wohldefinierten und geordneten Satz von Anweisungen.
Problemgröße: Es handelt sich nicht um die Größe der Eingabedaten, sondern um das Wesen der Problemgröße.
Eigenschaften von Algorithmen
Endlichkeit: Der Algorithmus muss in der Lage sein, den Algorithmus in jeder darin enthaltenen Situation durch endliche Schritte im Rahmen der menschlichen Toleranz zu vervollständigen.
Machbarkeit: Der Algorithmus kann durch die identifizierten Grundoperationen und begrenzten Schritte vervollständigt werden.
Determinismus: Jede Aussage muss sicher sein und darf nicht mehrdeutig sein, um sicherzustellen, dass das Programm unter denselben Eingabebedingungen das gleiche Ergebnis liefert.
E/A: Der Algorithmus muss null oder mehr Eingänge und einen oder mehrere Ausgänge haben.
Gültigkeit: Jeder Schritt des Algorithmus muss effizient ausgeführt werden können
Darüber hinaus müssen bei der Bestimmung der Qualität eines Algorithmus auch Korrektheit, Lesbarkeit, Robustheit, Zeitkomplexität und Raumkomplexität (Effizienz) berücksichtigt werden.
Algorithmusdarstellung
Natürliche Sprache: Eine Sprache, die Menschen täglich verwenden, deren Verständnis jedoch anfällig für Unterschiede ist, was die Sicherheit des Programms verringert.
Flussdiagramm: Die Vorschriften sind relativ klar, aber zu viele Flusslinien können leicht Verwirrung stiften, Änderungen unpraktisch machen und das Zeichnen zeit- und mühsam machen.
N-S-Diagramm: Eine wirklich strukturierte Methode, die jedoch immer noch Faktoren aufweist, die das Ändern und Zeichnen erschweren.
Pseudocode: hat viele Vorteile, ist leicht zu ändern, verwendet Computersprache und natürliche Sprache und ist leicht zu verstehen.
Allgemeine Schritte: Um Probleme von oben zu lösen, muss man sich nicht mit allen Details befassen. Man muss in der Lage sein, große Probleme in kleine zu unterteilen.
Ausführungszeit des Algorithmus
Erläuterung: Die Ausführungszeit des Algorithmus entspricht der Summe der Ausführungszeit aller Anweisungen, und die Ausführungszeit aller Anweisungen entspricht der einmaligen Ausführungszeit und der Anzahl der Ausführungen.
Aussagehäufigkeit: Die Häufigkeit, mit der eine Aussage wiederholt wird.
(Asymptotische) Zeitkomplexität
Definition: Die Größenordnung der Ausführungszeit des Algorithmus wird als Zeitkomplexität bezeichnet, T(n)=Q(f(x))
Sortierung (Zeitkomplexität): konstante Ordnung < logarithmische Ordnung < lineare Ordnung < lineare logarithmische Ordnung < quadratische Ordnung < kubische Ordnung < k-te Potenzordnung < exponentielle Ordnung
Hinweis: Sie nimmt mit der Größe des Problems zu.
(Asymptotische) Raumkomplexität
Einschließlich: [Anweisungen, Konstanten, Variablen und Eingabedaten, wenn das Programm ausgeführt wird] und [zusätzlicher Speicherplatz, der für Datenoperationen benötigt wird]
Hinweis: Wenn der erforderliche Hilfsraum bei der Ausführung des Programms eine Konstante relativ zu den Eingabedaten ist, spricht man von einem „In-Place“-Arbeitsalgorithmus.
Hinweis: Die Definition befindet sich in den beiden obigen Sätzen
Erläuterung der Zeit- und Raumkomplexität: Die beiden Aspekte der Algorithmusanalyse sind hauptsächlich Zeitkomplexität und Raumkomplexität. [Wenn der Rechenraum ausreichend ist, ist die Analyse der Zeitkomplexität außerdem das Hauptziel.] Übermäßiges Verfolgen des einen und des anderen kann die Leistung verschlechtern.
Klassifizierung von C-Anweisungen
Ausdrucksanweisung: Ein Ausdruck plus Semikolon. Durch die Ausführung dieser Anweisung wird der Wert des Ausdrucks berechnet.
Funktionsaufrufanweisung: Funktionsname plus Parameterliste plus Semikolon
Steueranweisungen: Es gibt neun Arten von Steueranweisungen in der C-Sprache, die in drei Kategorien unterteilt sind: bedingte Beurteilungsanweisungen, Schleifenausführungsanweisungen und Sprunganweisungen. Detaillierte Erläuterungen werden später gegeben.
Zusammengesetzte Anweisung: Eine Anweisung, die aus mehreren in geschweiften Klammern eingeschlossenen Anweisungen besteht. Grammatisch wird sie als eine Anweisung betrachtet. Jede Anweisung in den geschweiften Klammern muss mit einem Semikolon hinzugefügt werden, es können jedoch keine weiteren Anweisungen nach den geschweiften Klammern hinzugefügt werden.
Leere Anweisung: Es wird keine Operation ausgeführt, sondern nur eine aus Semikolons bestehende Anweisung.
sequentielle Struktur
Sequentielles Strukturprogramm: In einem sequentiellen Programm wird das Programm von oben nach unten ausgeführt. Nachdem die aktuelle Anweisung ausgeführt wurde, wird die nächste Anweisung ohne Beurteilung ausgeführt. [Besteht normalerweise aus Ausdrücken und Funktionsaufrufanweisungen] Da die Ausführung von Steueranweisungen nicht vollständig nacheinander ausgeführt wird, ist jede Ausführungsmethode anders.
Struktur auswählen
if-Anweisung [bei sequentieller Verwendung kann sie zur Beurteilung jedes Schritts im Prozess verwendet werden]
Einzelzweig-IF-Anweisung
Allgemeine Form: if (Ausdruck)-Anweisung;
Erläuterung: Wenn der Ausdruck wahr ist, werden die folgenden Anweisungen ausgeführt, andernfalls werden sie nicht ausgeführt.
if...else Doppelzweig-IF-Anweisung
Allgemeine Form: if (Ausdruck)-Anweisung;
Erläuterung: Wenn der Ausdruck wahr ist, wird die Anweisung danach ausgeführt, andernfalls wird die Anweisung danach ausgeführt.
if verschachtelte Anweisung
Wörtliche Bedeutung: Wenn Einzelzweig und Doppelzweig verschachtelt sind, gibt es keine detaillierte Erklärung
Hinweis: Wenn es mehrere Wenn- und Sonst-Werte gibt und Sie die entsprechende Kombination finden möchten, können Sie von „Sonst“ aus suchen, d.
if Multi-Branch-Anweisung
Allgemeine Form: if (Ausdruck)-Anweisung; else if (Ausdruck)-Anweisung;
Erläuterung: Welcher Ausdruck wahr ist, die folgenden Anweisungen werden ausgeführt und die Multi-Branch-Anweisung wird herausgesprungen. Wenn beide falsch sind, wird die letzte Anweisung ausgeführt und der Multibranch beendet.
switch-Anweisung (kann auch zum Aufrufen von Funktionen verwendet werden)
Allgemeine Form: switch (Ausdruck) {case konstanter Ausdruck: Anweisung; Pause;...Standard: Anweisung Pause;}
Beachten
1. Der Ausdruck in switch muss vom Typ Ganzzahl oder Zeichen sein.
2. Ausführungsreihenfolge wechseln: Beurteilen Sie den Wert, indem Sie den Wert des Ausdrucks in Klammern und des konstanten Ausdrucks berechnen, und führen Sie dann die Anweisung nach dem Fall aus. Wenn nicht, führen Sie die Anweisung nach unten aus . Wenn es keine Pause gibt, werden alle nachfolgenden Anweisungen ausgeführt.
Drittens können mehrere Anweisungen nach Groß- und Kleinschreibung angegeben werden, ohne dass geschweifte Klammern verwendet werden müssen.
Vier. Am besten verwenden Sie eine Jump-Anweisung, die die Ausführung stoppt.
Bedingte Operatoren und bedingte Ausdrücke
Hinweis: Die Prioritäten sind unterschiedlich. Wenn die höchste Priorität ist, ist der Schalter die zweite.
Schleifenstruktur
while-Anweisung
Allgemeine Form: while-Anweisung (Ausdruck);
Erläuterung: Wenn der Ausdruck immer wahr ist, wird die entsprechende Anweisung immer ausgeführt. Wenn der Ausdruck nicht immer wahr sein kann, kommt es zu einer Endlosschleife. Daher muss der Ausdruck der Schleife falsch sein oder nach der entsprechenden Anweisung muss eine Break-Anweisung stehen.
Hinweis: Ausdruckspositionen sind im Allgemeinen relationale Ausdrücke und logische Ausdrücke, es kann sich jedoch auch um andere Arten von Ausdrücken handeln. Zum Beispiel selbst hinzugefügt, Beziehung, 1 und 0.
do-while-Anweisung (mit if-Anweisung, kann unter bestimmten Bedingungen beendet werden)
Allgemeine Form: do{statement;}while (expression);
Erläuterung: Es ist whlie sehr ähnlich, es gibt jedoch einige Unterschiede in der Form und den Ausführungsmethoden. Die while-Schleife wird zuerst beurteilt und dann ausgeführt, während diese Art von Anweisung einmal ausgeführt und dann beurteilt wird. Es ist diese Ausführungsmethode, die sie weniger anwendbar macht als die while-Anweisung.
zur Aussage
Hinweis: Die oben genannten drei Schleifentypen können ineinander verschachtelt werden. Die drei Schleifenanweisungen haben unterschiedliche Bereiche, nämlich for ist der größte, while ist der zweite und do-while ist der letzte.
Hinweis: Das Obige bietet nur eine teilweise Organisation und allgemeine Schleifenanweisungen. Es wird empfohlen, sie während der Verwendung schrittweise zu beherrschen.
Jump-Anweisung
break-Anweisung: Wird häufig in Schleifenkörpern und Schaltern verwendet, kann jedoch nicht zum Unterbrechen von if-Anweisungen verwendet werden
continue-Anweisung: kann nur in Schleifenkörpern verwendet werden und wird häufig in Verbindung mit if-Anweisungen verwendet
goto-Anweisung
Allgemeine Form: Bezeichner der goto-Anweisung;
Erläuterung: Führen Sie die durch das Symbol gekennzeichnete Anweisung aus, die im Allgemeinen in Verbindung mit der if-Anweisung verwendet wird
return-Anweisung
Hinweis: Wenn es zurückgekehrt ist, springt es direkt aus der Schleife.
Hinweis: Durch die Verwendung von Sprunganweisungen werden Auswahlstrukturen und Schleifenstrukturen flexibler. Die Auswahlstruktur und die Schleifenstruktur bestehen aus einer Auswahlanweisung und einer Schleifenanweisung sowie einer Sprunganweisung. Die drei werden als Steueranweisungen bezeichnet.
Struktur und ihre Erweiterungen
Definition der Struktur
Definitionsformular
struct Strukturname {Datentyp-Variablenname;...};
Verwendung von typedef [Hilfe zur Definition und Verwendung von Strukturvariablen]
Beim Definieren einer Struktur: typedef struct structure name {data type variable name;...} new data type name;
Hinweis: Im obigen Verwendungsprozess wird der Strukturname weggelassen, was sich nicht auf das Ergebnis auswirkt. Der Strukturname kann jedoch beim Definieren der Strukturvariablen nicht verwendet werden, da Sie ihn weggelassen haben.
Nach der Definition verwenden: typedef-Datentyp oder Datentypname [z. B. int- und Strukturstrukturname] neuer Datentypname
Beschreibung [Hinweise zur Strukturdefinition]
1. Strukturelemente können beliebige Basisdatentypen sein. Darüber hinaus können sie auch Array- und Zeigertypen sein.
Zweitens müssen Größe und Anzahl der Strukturen sicher sein, und dynamische Strukturen können nicht definiert werden [wird in der C-Sprache nicht unterstützt].
Drittens kann eine Struktur in mehreren Nestern definiert werden, sie kann jedoch nicht rekursiv definiert werden [verwenden Sie den Strukturnamen, um die Strukturmitglieder in der Struktur zu definieren].
4. Die Namen der Strukturmitglieder dürfen nicht identisch sein.
5. Sie können den Strukturnamen verwenden, um Zeigervariablen in der Struktur zu definieren, und die Zeigervariable kann auf die Strukturvariable verweisen.
Strukturvariable
Definition: Wir haben den Strukturtyp selbst definiert. Wenn wir ihn zum Definieren von Variablen verwenden, nennen wir ihn Strukturvariable, ähnlich wie grundlegende Datentypen definiert werden.
Merkmale: Aus der Definition können wir erkennen, dass die definierte Struktur keinen Speicherplatz belegt. Wenn wir sie jedoch zum Definieren von Strukturvariablen verwenden, weist das System Speicherplatz zu.
Definitionsformular
Definieren Sie zunächst die Struktur [hier können Sie typedef verwenden] und definieren Sie dann die Strukturvariablen, indem Sie den Variablennamen zur Struktur hinzufügen. Da es separat definiert wird, können Sie den neuen Namen nach ty verwenden, um es zu definieren. Diese beiden Methoden gehören zur [sequentiellen Kategorie]
2. Definieren Sie beim Definieren der Struktur die Strukturvariablen [schreiben Sie den Variablennamen direkt nach den geschweiften Klammern und trennen Sie mehrere Variablen durch Kommas]. Zu diesem Zeitpunkt kann der Strukturvariablenname weggelassen werden, es gibt jedoch Einschränkungen zur Strukturdefinition. Diese beiden Methoden gehören zur [gleichzeitigen Kategorie]
Initialisierung [nicht initialisiert, Strukturvariablen sind automatisch 0]
Allgemeine Form: Viele Formen, dh die definierte Struktur - [Strukturtyp] Strukturvariablenname = {Anfangswerttabelle};
Konkret: Definieren Sie zuerst die Struktur und initialisieren Sie die [Strukturvariable], während Sie die [Strukturvariable] definieren. Oder definieren Sie die Struktur und definieren und initialisieren Sie gleichzeitig die Strukturvariablen. Wenn Sie im Definitions- und Initialisierungsprozess des ersteren kein Typedef zum Einrichten eines Alias verwenden, können Sie den Strukturtyp nicht weglassen und den Variablennamen für die Definition direkt auswählen.
Erläuterung: Die sogenannten vielen Formen unterteilen den Definitions- und Initialisierungsprozess grob in zwei Kategorien, [sequentiell] und [gleichzeitig], die beide ihre eigenen Eigenschaften haben, die mit typedef verwendet werden können und [gleichzeitig] ausgewählt werden können den Strukturnamen wegzulassen.
Hinweis: Bei der Initialisierung durch [Zuweisungsvorgang] sind Definition und Initialisierung untrennbar miteinander verbunden, [aber es können Grundtypen verwendet werden, was auch den Unterschied ausmacht]. Tabelle] Die Reihenfolge muss mit der Reihenfolge der Mitglieder in der Struktur übereinstimmen und es darf keine Fehler geben.]
Zitierformular
Mitgliedsoperator: Name der Strukturvariablen
Zeiger-Pluswert-Operator: (*Zeigervariablenname).Mitgliedsname
Zeiger plus Mitgliedsauswahlzeiger: Zeigervariablenname -> Mitgliedsname
Hinweis: Es kann nicht als Ganzes zitiert werden. Es kann nur durch Referenzierung einiger Variablen über die oben genannten drei Methoden verwendet werden. Es hat die Funktion einer gewöhnlichen Variablen und kann beim Verweisen zunächst nur als Ganzes und dann als Teil verwendet werden.
Zeiger auf Strukturvariable [Nach Überlegung wurde dieser Teil für die Platzierung im Zeigerabschnitt ausgewählt]
Strukturarray
Eigenschaften: Es verfügt über die Eigenschaften von Arrays und Strukturvariablen.
Definition: Die Definitionsmethode entspricht der Definition von Strukturvariablen nacheinander oder gleichzeitig.
Allgemeine Form: Strukturstrukturname Strukturarrayname [Größe]
struct Strukturvariablenname { } Strukturarrayname [Größe]
Initialisierung: Es ähnelt immer noch den Definitionsanforderungen von Strukturvariablen. Es ist eng in die Array-Definition der Struktur integriert und kann nicht getrennt werden [dh es kann nicht zuerst definiert und dann durch Zuweisungsoperationen initialisiert werden, Sie können scanf verwenden]. . Informationen zum Formular finden Sie in der Initialisierung von Strukturvariablen und der Zuweisungsmethode für mehrdimensionale Arrays.
Referenz: Verwenden Sie Array-Indizes und Mitgliedsoperatoren, um auf bestimmte Variablen im Array zu verweisen. Jedem Teil des Arrays kann ein Wert als Ganzes zugewiesen werden, beispielsweise a[0]=a[1]. Eine teilweise Zuweisung kann auch für Mitglieder durchgeführt werden, ihre Typen müssen jedoch identisch sein, z. B. a[0].name=a[1].name.
Beispieldiagramm zur Überprüfung des oben genannten Problems
Mehrere Beispieldiagramme zur Erläuterung der Definition und Initialisierung
Alle Initialisierungen in der Struktur können zusätzlich zur Definition auch über die Formatsteuerungseingabefunktion scanf initialisiert werden.
Wenn Definition und Initialisierung durch Zuweisungsoperationen initialisiert werden, sind die beiden untrennbar miteinander verbunden. Dies kann durch scanf erfolgen.
Gemeinschaft
Definitionsformat: Union <Union-Name>{<Mitgliederliste>}
Funktionen: Die größte Variable in der Mitgliederliste wird verwendet, um für jede Mitgliedsvariable den gleichen Platz zu schaffen. Nach der Initialisierung werden verschiedene Formen eines Werts in der Mitgliederliste gespeichert.
Ergänzung: Andere Methoden sind genau die gleichen wie die Struktur
Konzepte im Zusammenhang mit der variablen Speicherung
Variablenbereich
Definition: Der gültige Bereich einer Variablen wird als Gültigkeitsbereich der Variablen bezeichnet. Wenn eine Funktion aufgerufen wird, wird den formalen Parametern nur dann Platz zugewiesen, wenn die Funktion aufgerufen wird. Daher ist die Variable nicht immer vorhanden und die Ergebnisse sind unterschiedlich Variablen sind unterschiedlich.
Kernpunkt: Die Regulierung des Variablenbereichs führt natürlich zu dem Problem, dass Variablen mit demselben Namen in [verschiedenen Definitionsbereichen] nicht verwandt sind.
lokale Variablen
Definition: Variablen, die innerhalb einer Funktion oder in einer zusammengesetzten Anweisung definiert sind, werden lokale Variablen genannt
Gültiger Bereich: Lokale Variablen sind nur innerhalb der Funktion oder zusammengesetzten Anweisung gültig, in der sie definiert sind. Es gibt keine Priorität zwischen den beiden. Wenn es eine zusammengesetzte Anweisung in der Funktion gibt, wird sie entsprechend nur in einer von ihnen wirksam definierten Umfang.
Globale Variablen (externe Variablen)
Definition: Eine globale Variable ist eine Variable, die außerhalb aller Funktionen definiert ist und von allen Funktionen im selben Programm gemeinsam genutzt werden kann. Wenn sie sich ändert, wird nur die globale Variable mit demselben Namen in der zusammengesetzten Anweisung in der Funktion nicht geändert.
Gültiger Bereich: von der definierten Position bis zum Ende des Programms.
Hinweis: Die Verwendung globaler Variablen beeinträchtigt die Lesbarkeit des Programms. Versuchen Sie daher, keine globalen Variablen zu definieren.
Speicherklasse und Lebenszyklus von Variablen
Grund: Entsprechend dem Lebenszyklus von Variablen können sie in statische Speichervariablen und dynamische Speichervariablen unterteilt werden. Statische Speichervariablen sind Variablen, denen während der Programmausführung ein fester Speicherplatz zugewiesen wird. Dynamische Speichervariablen sind Variablen, die zur Laufzeit nach Bedarf Speicherplatz zuweisen. Sie sind klar definiert und besser verständlich.
Statische Speichervariablen
Geltungsbereich: globale Variablen, statische lokale Variablen
Lebenszyklus: Wenn das Programm ausgeführt wird, wird Speicherplatz zugewiesen und nach Abschluss des gesamten Programms freigegeben.
Dynamische Speichervariablen
Geltungsbereich: automatische Variablen, formale Parametervariablen, unterbrochene Felddaten
Lebenszyklus: Vom Aufruf der Funktion bis zum Ende durchläuft sie den gesamten Ausführungsprozess der Funktion.
Automatische Variablenerklärung: Bezieht sich auf lokale Variablen, die nicht mit statischen Variablen deklariert werden
Erläuterung formaler Parametervariablen: Bezieht sich auf Parameter in Form von Funktionen
Interrupt-Kontextdateninterpretation: Kontextschutz und Rückgabewerte für Funktionsaufrufe
Variable Speicherklasse
Erläuterung: Bei der Definition von Variablen verwenden wir normalerweise Datentypdefinitionen, aber Variablen haben auch Speicherkategorien. In der C-Sprache haben Variablen zwei Attribute: Datentyp und Datenspeichertyp.
Die vollständige Definitionsform der Variablen: Speicherkategorie-Datentyp-ID-Variablenname;
automatische Variable (auto)
Definition: Wenn beim Definieren einer lokalen Variablen Auto verwendet wird oder die Speicherkategorie nicht angegeben ist, verwendet das System standardmäßig eine automatische Variable, weist ihr Speicherplatz zu und platziert einen dynamischen Speicherbereich.
Geltungsbereich: beginnt an der Definitionsposition und endet am Definitionsfunktionsbereich oder an der zusammengesetzten Anweisung.
Registervariable (Register)
Grund: Aufgrund der hohen Nutzungshäufigkeit einiger Variablen speichert das System aus Gründen der Betriebseffizienz den Wert der Variablen im Register der CPU.
Definition: Eine spezielle automatische Variable.
Grenze
Kann nur Variablen der Kategorien char, int und pointer sein
Als Registervariablen können nur in Funktionen definierte Variablen und Parameter definiert werden
Das aktuelle Kompilierungssystem kann diese Variablen bereits automatisch identifizieren und in Registervariablen ablegen.
statische Variablen
Definition: Variablen, die mit dem Schlüsselwort static definiert werden
statische lokale Variablen
Definition: Variablen, die innerhalb einer Funktion oder zusammengesetzten Anweisung mit dem Schlüsselwort static definiert werden
Umfang: Der Umfang bleibt unverändert und der Lebenszyklus ändert sich im Ausführungsprozess des gesamten Programms.
statische globale Variablen
Definition: Statisch deklarierte Variablen verwenden. Nach der Deklaration kann diese globale Variable jedoch nur in dieser Quelldatei verwendet werden und verliert einen Teil ihrer Rolle als externe Variable.
externe Variablen (extern)
Definition: Variablen, die außerhalb aller Funktionen definiert sind
Geltungsbereich: von der Definitionsposition bis zum Ende des gesamten Programms. Wenn Sie externe Variablen vor der Definitionsposition verwenden möchten, können Sie externe Variablen an der Referenzposition deklarieren und so den Geltungsbereich erweitern.
Hinweis: In anderen Quelldateien kann die Deklaration dieser externen Variablen in anderen Quelldateien verwendet werden.
Dateioperationen
Dokumentenübersicht
Datei: Dabei handelt es sich nicht nur um eine geordnete Sammlung zusammengehöriger Daten, die durch einen Dateinamen identifiziert werden, sondern auch um eine vom Betriebssystem verwaltete Dateneinheit.
Klassifizierung von Dateien [Dateien werden in der Regel auf externen Medien gespeichert und erst bei der Verwendung in den Speicher abgerufen. Je nach Perspektive ist auch die Klassifizierung von Dateien unterschiedlich.]
【1】 Aus Benutzersicht können Dateien in Gerätedateien und normale Dateien unterteilt werden.
【2】Aus Sicht der logischen Struktur können Dateien in Aufnahmedateien und Streaming-Dateien unterteilt werden.
[3] Aus Sicht der Kodierungsmethode können Dateien in Textdateien und Binärdateien unterteilt werden.
Dateizeiger
Hinweis: In der Sprache C erfolgt der Zugriff auf Dateien über Dateizeiger.
Zeiger auf Dateityp: Der FILE-Typ in der Sprache C ist ein Strukturtyp, der zum Speichern von Informationen über Dateien verwendet wird. Er ist in <stdio.h> definiert
Dateistrukturzeiger: In der Sprache C werden alle externen Geräte als Dateien behandelt, die als Gerätedateien bezeichnet werden.
Dateien öffnen und schließen
Hinweis: Wenn ein C-Sprachprogramm Dateioperationen ausführt, muss es dem Vorgang „Öffnen“ -> „Lesen und Schreiben“ -> „Schließen“ folgen. Die Datei kann nicht gelesen oder geschrieben werden, ohne sie zu öffnen, und die Systemressourcen sind erschöpft, wenn sie nicht geschlossen wird.
Öffnen der Datei [gibt NULL zurück, wenn der Vorgang fehlschlägt]
Funktion: fopen
Format: Dateizeigername = fopen (Dateiname, Dateiöffnungsmodus)
[Dateizeigername] muss eine Zeigervariable sein, die als FILE-Typ deklariert ist
[Dateiname] kann eine String-Konstante oder ein Zeichenarray sein.
[Dateimodus öffnen] bezieht sich wie folgt auf den Dateityp und die Betriebsanforderungen
Beispiel
Datei schließen
Hinweis: Nachdem Sie die Datei verwendet haben, sollten Sie sie mit der Funktion fclose schließen, um zu verhindern, dass die Datei verloren geht oder erneut missbraucht wird.
Form: fclose (Dateizeiger)
[1] [Der Schließvorgang der Datei führt dazu, dass der Dateizeiger nicht mehr auf die der Datei entsprechende FILE-Struktur zeigt, wodurch die Datei getrennt wird]
【2】【Beim Schreiben von Daten in eine Datei werden die Daten zuerst in den Puffer gelegt. Der Pufferinhalt wird erst dann an die Festplatte gesendet, wenn der Puffer voll ist Durch das Schließen der Datei wird das Senden des Pufferinhalts erzwungen.
【3】【0 für normalen Dateibetrieb zurückgeben, andernfalls EOF zurückgeben】
Dateien lesen und schreiben
[Erklärung]: Die C-Sprache bietet viele Funktionen zum Lesen und Schreiben von Dateien. Der Unterschied besteht darin, dass die Lese- und Schreibeinheiten unterschiedlich sind. Sie sind alle in der Header-Datei stdio.h definiert.
Funktionen zum Lesen und Schreiben von Zeichen: fgetc und fputc
Funktionen zum Lesen und Schreiben von Zeichenfolgen: fgets und fputs
Funktionen zum Lesen und Schreiben von Datenblöcken: freed und fwrite
Formatierte Eingabe- und Ausgabefunktionen: fscanf und fprinf
Worteingabe- und -ausgabefunktionen: getw und putw
Dateispeicherort [ausgenommen bestimmte Betriebsfunktionen]
Dateifehlerprüfung
Datenstruktur
Definition: Eine Sammlung von Datenelementen, die eine oder mehrere spezifische Beziehungen zueinander haben. Sie kann auch als Sammlung strukturierter Datenelemente betrachtet werden.
Zwei Ebenen der Datenstruktur
Logische Struktur: ein von tatsächlichen Problemen abstrahiertes Datenmodell
Abteilung 1
Lineare Strukturen: Stapel, Warteschlange, lineare Liste, Array
Nichtlineare Strukturen: Bäume, Graphen, Mengen
Abteilung 2
Menge: Datenelemente haben keine andere Beziehung, außer dass sie sich in derselben Menge befinden.
Lineare Struktur: Zwischen Datenelementen besteht eine Eins-zu-eins-Beziehung.
Baumstruktur – es besteht eine hierarchische Eins-zu-viele-Beziehung zwischen den Datenelementen in der Struktur
Diagrammstruktur – Es besteht eine Viele-zu-Viele-Beziehung zwischen Datenelementen in der Struktur
Speicherstruktur (physische Struktur): Wie Datenelemente und ihre Beziehungen im Speicher gespeichert werden
Sequentielle Speicherung: [erfordert, dass alle Elemente nacheinander im kontinuierlichen Speicherplatz gespeichert werden], wobei die Position der Elemente im Speicher verwendet wird, um die logische Beziehung zwischen Elementen darzustellen. Wird normalerweise durch ein Array dargestellt.
Kettenspeicher: [Datenelemente müssen nicht im kontinuierlichen Speicherplatz gespeichert werden, aber die Datenelemente in jedem Datenelement werden im kontinuierlichen Speicherplatz gespeichert], und an jeden Knoten muss ein Zeigerfeld angehängt werden. Die Adresse, die zum Speichern nachfolgender Elemente verwendet wird.
abstrakter Datentyp
Definition: Es bezieht sich auf das vom Benutzer definierte mathematische Modell zur Darstellung des Anwendungsproblems und die Summe einer Reihe von Operationen, die für dieses Modell definiert sind.
Einschließlich: Datenobjekte, eine Sammlung von Beziehungen zu Datenbeziehungen und eine Sammlung grundlegender Operationen für Datenobjekte.
linearer Tisch
Sequenztabelle
Definition: Eine endliche Folge bestehend aus n Datenelementen mit gleichen Dateneigenschaften wird als lineare Tabelle bezeichnet. Wenn n gleich 0 ist, spricht man von einer leeren Liste.
Merkmale
Es gibt nur ein Datenelement mit den Namen „erster“ und „letzter“.
Jedes Element hat außer dem ersten nur einen direkten Vorgänger.
Jedes Element hat außer dem letzten nur einen unmittelbaren Nachfolger.
Sequentielle Speicherdarstellung der linearen Tabelle [sequentielle Tabelle]
Definition: Verwenden Sie eine Reihe von [Speichereinheiten mit aufeinanderfolgenden Adressen], um die Datenelemente einer linearen Tabelle sequentiell zu speichern. Dies wird auch als sequentielle Speicherstruktur oder sequentielles Bild einer linearen Tabelle bezeichnet
Merkmale: Datenelemente, die logisch benachbart sind, sind auch in physischer Reihenfolge benachbart.
Hinweis: Da die Sequenztabelle kontinuierlich ist, kann auf jedes Datenelement zugegriffen werden, solange die erste Adresse der linearen Tabelle bestätigt wird. Daher ist die sequentielle Speicherstruktur der linearen Tabelle eine Speicherstruktur mit [wahlfreiem Zugriff].
Ergänzung: Da höhere Programmiersprachen auch Direktzugriffseigenschaften aufweisen, werden Arrays üblicherweise zur Beschreibung der sequentiellen Speicherstruktur in der Datenstruktur verwendet. Da hier die Länge der linearen Tabelle je nach Problem variieren kann, kann die lineare Tabelle durch ein dynamisch zugewiesenes eindimensionales Array in der C-Sprache dargestellt werden.
Implementierung der Grundoperationen in der Sequenztabelle [Legen Sie für die folgenden Operationen bitte die Bedingungen fest, um festzustellen, ob sie zulässig sind oder nicht. Wenn sie nicht zulässig sind, wird ein Fehler zurückgegeben.]
Initialisierung: Die Initialisierung der Sequenztabelle besteht darin, eine leere Sequenztabelle zu erstellen und zu bestimmen, ob die lineare Tabelle eine leere Tabelle ist, indem beurteilt wird, ob die Länge 0 ist.
Wert: Ermitteln Sie den Wert des i-ten Elements der linearen Tabelle über die angegebene Positionsnummer i. Das heißt, das Array enthält i-1 Elemente.
Einfügen: Fügen Sie ein neues Element an der i-ten Position in der Tabelle ein und verwandeln Sie die lineare Tabelle der Länge n in eine lineare Tabelle der Länge n 1. [Sie müssen auch feststellen, ob die lineare Tabelle voll ist]
Löschen: Löschen Sie das i-te Element in der Liste und reduzieren Sie die Länge der linearen Liste um eins.
Defekt:
verlinkte Liste
Daten und verwandte Konzepte
1.1 Forschungsinhalt der Datenstruktur
nicht numerischer Wert, Merkmal, Vorgang
besteht darin, Computer in die Lage zu versetzen, nicht-numerische Verarbeitung effizienter durchzuführen,
1.2 Grundkonzepte und Terminologie
1. Daten
Definition: Alle [Symbole], die in den Computer eingegeben werden können, um [objektive Dinge zu beschreiben]
Einstufung
numerische Daten
nicht numerische Daten
2. Datenelement (Element): Die Grundeinheit in Daten, auch Knoten (Knoten) genannt.
3. Datenelement: Die kleinste Einheit, die ein Datenelement in den Daten darstellt, eine unabhängige Bedeutung hat und unteilbar ist.
Geltungsbereich: Daten>Datenobjekt>Datenelement>Datenelement (einschließlich Geltungsbereich)
Datenobjekt: Datenelemente mit denselben Eigenschaften, die Teilmengen von Daten sind.
Bild
Definition: Es besteht aus einer endlichen, nicht leeren Menge von Punkten und einer endlichen Menge von Kanten. Wenn die Kantenmenge eine gerichtete Kante ist, wird der Graph als gerichteter Graph bezeichnet ein ungerichtetes Diagramm.
Grundbegriffe
Untergraph: Ein Graph, der durch Auswahl einiger vorhandener Punkte und Kanten in einem bestimmten Graphen und Befolgen der Verbindungsmethode im gegebenen Graphen erstellt wird.
Ungerichteter vollständiger Graph und gerichteter vollständiger Graph
1# Wenn ein ungerichteter Graph n(n-1)/2 Kanten hat, wird der Graph als ungerichteter vollständiger Graph bezeichnet.
2# Wenn ein gerichteter Graph n (n-1) Bögen hat, wird der Graph als gerichteter vollständiger Graph bezeichnet.
Sparse-Diagramme und dichte Diagramme: Ein Diagramm mit wenigen Kanten oder Bögen wird als spärliches Diagramm bezeichnet, und das Gegenteil wird als dichtes Diagramm bezeichnet [stark subjektiv, der Beurteilungsmaßstab wird von Menschen bestimmt]
Quanhe.com
Gewicht: In der praktischen Anwendung von Diagrammen werden Werte an den Rändern markiert. Diese Werte stellen die Kosten oder Kosten für den Übergang von einem Punkt zu einem anderen dar, die als Gewicht bezeichnet werden.
Netz: Ein Graph mit Autorität wird Netz genannt
Benachbarte Punkte: Zwei Punkte sind durch eine gemeinsame Kante benachbart, die man auch als mit den beiden Punkten verbunden bezeichnen kann.
Abschluss, In-Degree, Out-Degree
Grad: die Anzahl der Kanten, die den Punkt verbinden. In einem gerichteten Graphen ist der Grad gleich der Summe aus Außengrad und Innengrad.
Out-Grad: In einem gerichteten Graphen die Kante, die von diesem Punkt ausgeht
Eintritt: In einem gerichteten Graphen die Kante, die von diesem Punkt aus eintritt.
Pfad und Pfadlänge
Pfad: vom Startpunkt bis zum Endpunkt, alle Scheitelpunktsequenzen. Wenn der Graph ein gerichteter Graph ist, ist auch der Pfad gerichtet.
Pfadlänge: Die Anzahl der Kanten oder Bögen, die entlang eines Pfads durchlaufen werden.
Schleife oder Schleife: Ein Pfad, dessen erster und letzter Scheitelpunkt gleich sind, wird Schleife oder Schleife genannt.
Einfacher Pfad, einfache Schleife (einfache Schleife)
Einfacher Pfad: Ein Pfad, dessen Eckpunkte sich in der Folge nicht wiederholen, wird als einfacher Pfad bezeichnet
Einfache Schleife oder einfacher Ring: Eine Schleife, deren Scheitelpunkte sich mit Ausnahme des ersten und letzten Scheitelpunkts nicht wiederholen, wird als einfache Schleife oder einfacher Ring bezeichnet.
Konnektivitätsbezogene Konzepte
Verbunden: Wenn es in [ungerichtetem Diagramm] einen [Pfad] zwischen Scheitelpunkt v und Scheitelpunkt v1 gibt, wird dieser als verbunden bezeichnet [die Scheitelpunkte selbst können auch als verbunden betrachtet werden].
Verbundener Graph: Wenn zwei beliebige Eckpunkte verbunden sind, wird der Graph als verbundener Graph bezeichnet.
Verbundene Komponente: ein maximal zusammenhängender Teilgraph in einem ungerichteten Graphen.
Stark verbundener Graph: Wenn es im [gerichteten Graphen] einen Pfad zwischen zwei beliebigen Scheitelpunkten gibt [diese beiden Punkte sind nicht gleich], wird der Graph als stark verbundener Graph bezeichnet.
Stark zusammenhängende Komponente: in einem gerichteten Graphen maximal zusammenhängender Teilgraph
Der Spannbaum eines verbundenen Graphen: Zuerst ist er ein verbundener Untergraph und dann enthält er alle Scheitelpunkte im Graphen, aber nur n-1 Kanten.
Gerichteter Baum: ein gerichteter Graph, in dem ein Scheitelpunkt einen In-Grad von 0 und die übrigen Scheitelpunkte einen In-Grad von 1 haben.
Generativer Wald: bestehend aus mehreren gerichteten Bäumen.
Diagrammspeicherstruktur
Adjazenzmatrix: ist eine Matrix, die die benachbarte Beziehung zwischen Scheitelpunkten darstellt
Regel: Wenn es einen Pfad zwischen benachbarten Eckpunkten v(i) und v(j) gibt, wird der Pfad an der durch i und j bestimmten Position in der endlichen Kantenmenge des Diagramms durch 1 dargestellt, andernfalls wird er durch 0 dargestellt .
Vorteil
Sie können deutlich erkennen, ob es Kanten zwischen benachbarten Scheitelpunkten gibt
Es ist praktisch, den Grad jedes Scheitelpunkts zu berechnen. In einem ungerichteten Diagramm ist die Summe der Elemente in der i-ten Zeile der Grad. In einem ungerichteten Graphen ist die Summe der Elemente in Zeile i der Ausgangsgrad und die Summe der Elemente in Spalte j der Eingangsgrad.
Mangel
Das Hinzufügen und Löschen von Eckpunkten ist unpraktisch
Es ist nicht bequem, die Anzahl der Kanten zu zählen, die alle Elemente scannen müssen, und die zeitliche Komplexität beträgt Q(n^2).
Hohe räumliche Komplexität [besonders eine Zeitverschwendung für spärliche Diagramme]
Wenn es sich um ein Netzwerk handelt, wird jede verbundene Position durch ein Gewicht dargestellt, andernfalls wird ein Unendlichkeitssymbol verwendet.
Adjazenzliste: Es handelt sich um eine verknüpfte Speicherstruktur des Diagramms
Regel
Vorteil
Einfaches Hinzufügen und Löschen von Eckpunkten
Es ist praktisch, die Anzahl der Scheitelpunkte und Kanten zu zählen, und die Zeitkomplexität beträgt Q(ne)
Hohe Platzeffizienz [geeignet für dünn besetzte Diagramme]
Mangel
Es ist nicht einfach zu bestimmen, ob ein Scheitelpunkt eine Kante hat.
Es ist nicht bequem, die Kanten des gerichteten Graphen zu berechnen.
Graphdurchquerung
Tiefensuche [Regeln]
Besuchen Sie ausgehend von einem bestimmten Knoten im Diagramm diesen Knoten
Suchen Sie ausgehend vom gerade besuchten Knoten nach nicht besuchten benachbarten Punkten und besuchen Sie ihn dann. Wiederholen Sie diesen Schritt, bis der besuchte Knoten keine benachbarten Punkte mehr hat.
Wenn der Punkt zu diesem Zeitpunkt keine nicht besuchten benachbarten Punkte hat, kehren Sie zum zuletzt besuchten Knoten zurück. Wenn der Knoten einen nicht besuchten Knoten hat, besuchen Sie ihn und kehren Sie dann weiter zurück. andererseits. Kehren Sie direkt zurück, bis alle Knoten besucht sind
Breitensuche [Regeln]
Ausgehend von einem bestimmten Scheitelpunkt des Diagramms
Greifen Sie auf die angrenzenden Punkte des Punktes zu. Wenn mehrere benachbarte Punkte vorhanden sind, greifen Sie seitlich zu.
Basierend auf dem Prinzip, dass der zuerst besuchte Knoten höher ist als die Priorität des später besuchten Knotens, werden nachfolgende Knoten besucht, bis alle Knoten im Diagramm besucht sind.
Anwendung von Diagrammen
minimaler Spannbaum
Prims Algorithmus [Punktmethode hinzugefügt]
Für bestehende verbundene Netzwerke geben wir zunächst eine Menge von Kanten an [nach der Konstruktion des minimalen Spannbaums handelt es sich um die Menge der Kanten] und geben dann eine Menge nur mit [dem ersten Scheitelpunkt] an.
Nehmen Sie alle Eckpunkte im verbundenen Diagramm heraus und platzieren Sie sie entsprechend ihren entsprechenden Positionen
Suchen Sie ausgehend vom ersten Scheitelpunkt in dem gegebenen verbundenen Diagramm die angrenzende Kante mit dem kleinsten Gewicht [und der von dieser Kante erreichte Punkt darf nicht in der Konzentration der Verbindungspunkte liegen] und verbinden Sie sie auf die ursprüngliche Weise [diese Kante verbindet die Kante] Festlegen] und wiederholen Sie dann diesen Schritt beginnend mit dem Scheitelpunkt, den die Kante erreicht [dieser Punkt verbindet sich mit der Menge der Punkte].
Wenn bei der Auswahl einer Kante mehrere Kanten mit demselben Gewicht vorhanden sind, wählen Sie zu diesem Zeitpunkt einfach eine beliebige Kante aus.
Kruskals Algorithmus [Zusätzliche Kantenmethode]
Sortieren Sie bei vorhandenen verbundenen Netzwerken die Gewichtungen darin von klein nach groß.
Nehmen Sie alle Eckpunkte im verbundenen Diagramm heraus und platzieren Sie sie entsprechend ihren entsprechenden Positionen
Nehmen Sie die Kante mit dem geringsten Gewicht heraus und verbinden Sie sie entsprechend ihrer ursprünglichen Position in Ihrem eigenen Diagramm. Wenn die neu hinzugefügte Kante eine Schleife verursacht, verwerfen Sie die Kante und wählen Sie die nächste Kante mit einem geringeren Gewicht.
Kürzester Weg [In einem gewichteten gerichteten Graphen ist es üblich, den ersten Scheitelpunkt als Quellpunkt und den letzten Scheitelpunkt als Endpunkt zu bezeichnen.
Der kürzeste Weg von einem Quellpunkt zu anderen Quellpunkten [Dijkstra-Algorithmus]
Teilen Sie bei vorhandenen Netzen die Eckpunkte in zwei Gruppen ein
Eine Gruppe ist eine Menge, die nur Quellpunkte mit dem Namen S enthält
Eine Menge besteht aus allen Punkten mit Ausnahme des Quellpunkts
AOV-Net [ein gerichteter Graph, der Scheitelpunkte zur Darstellung von Aktivitäten und Bögen zur Darstellung von Aktivitätsprioritätsbeziehungen verwendet]
Ein azyklischer gerichteter Graph wird als gerichteter azyklischer Graph bezeichnet. Ein gerichteter azyklischer Graph ist ein wirksames Werkzeug zur Beschreibung des Prozesses eines Projekts oder Systems.
[Einführung] Im AOV-Netz sollte es keine gerichteten Zyklen geben. Die Erkennungsmethode besteht darin, eine topologische Sortierung für das gegebene Netz durchzuführen. Wenn sich alle Scheitelpunkte in der topologisch sortierten gerichteten Reihenfolge befinden, darf das AOV-Netz nicht vorhanden sein. Ring.
Wenn es vom Scheitelpunkt v(i) bis v(j) einen gerichteten Pfad gibt, wird v(i) als Vorgänger von v(j) bezeichnet. Wenn es einen Bogen im Netzwerk gibt, wird er als direkt bezeichnet Vorgänger.
Topologische Sortierung [Ordnen Sie alle Scheitelpunkte im AOV-Netz in einer linearen Reihenfolge an, die Folgendes erfüllt: Wenn es einen Pfad zwischen Scheitelpunkt v(i) und Scheitelpunkt v(j) im AOV-Netz gibt, dann muss v(i) vorhanden sein v(j)before】
Wählen Sie in einem gerichteten Diagramm einen Punkt aus, der keinen direkten Vorgänger hat, und geben Sie ihn aus
Und löschen Sie den Punkt und den Bogen, der an diesem Punkt im gerichteten Diagramm endet
Wiederholen Sie die obigen Schritte, bis keine Eckpunkte ohne Vorgänger mehr vorhanden sind.
Wenn die Anzahl der ausgegebenen Punkte zu diesem Zeitpunkt geringer ist als die Anzahl der Scheitelpunkte im gerichteten Diagramm, bedeutet dies, dass es im gerichteten Diagramm einen Zyklus gibt. Andernfalls handelt es sich um eine topologisch sortierte gerichtete Sequenz.
AOE-Net [Gewichteter gerichteter azyklischer Graph, der Kanten zur Darstellung von Aktivitäten, Scheitelpunkte zur Darstellung von Ereignissen und Gewichte zur Darstellung der Dauer der Aktivität verwendet. Jedes Ereignis stellt die Aktivität dar, bevor sie abgeschlossen wurde, und die Aktivität, nachdem sie gestartet werden kann.]
Es wird normalerweise verwendet, um ein Projekt darzustellen. Das gesamte Projekt hat nur einen Abschlusspunkt und einen Endpunkt. Daher gibt es unter normalen Umständen nur einen Punkt mit einem In-Grad von 0, der als Quellpunkt bezeichnet wird . Es gibt auch nur einen Punkt mit einem Außengrad von Null, der Senkenpunkt genannt wird.
Gewichtete Pfadlänge: In AOE-net die Summe der Gewichte jedes Bogens auf einem Pfad
Kritischer Pfad: der Pfad mit der längsten gewichteten Pfadlänge von der Quelle zur Senke.
Kritische Aktivitäten: Kanten auf dem kritischen Pfad.
Lösungsprozess für den kritischen Pfad
Topologische Sortierung, um den frühesten Auftrittszeitpunkt einer Aktivität zu ermitteln
Inverse topologische Sortierung, um den spätesten Zeitpunkt einer Aktivität zu ermitteln
Wenn diese beiden Zeitpunkte gleich sind, handelt es sich um eine kritische Aktivität
Jeder durch Schlüsselaktivitäten gebildete Pfad von der Quelle zur Senke ist ein kritischer Pfad. Es kann mehr als einen kritischen Pfad geben.
Bäume und Binärbäume
Baum [ist eine endliche Menge mit n Knoten, n ist größer oder gleich 0]
Erläuterung: Wenn n gleich 0 ist, spricht man von einem leeren Baum, andernfalls handelt es sich um einen nicht leeren Baum
Definition eines nicht leeren Baums
Es gibt nur einen Knoten namens Wurzel
Andere Knoten als der Wurzelknoten können in m disjunkte endliche Mengen unterteilt werden. Jede Menge selbst ist ein Baum und wird als Teilbaum des Baums bezeichnet.
Verständnis: Die Strukturdefinition eines Baums ist eine rekursive Definition, dh die Definition eines Baums wird in der Definition eines Baums verwendet. Bäume können auch andere Darstellungsformen haben, [verschachtelte Mengenform], [verallgemeinerte Tabellenform], [konkave Darstellung]
Grundlegende Terminologie für Bäume
Knoten: eine unabhängige Einheit des Baums, die ein Datenelement und [mehrere Zweige, die auf seine Unterbäume zeigen] enthält (? – z. B. in der Kettenspeicherung, Zeiger auf die linken und rechten Kinder und Variablen zum Speichern von Daten)
Grad des Knotens: Die Anzahl der Teilbäume, die einem Knoten gehören, wird als Grad des Knotens bezeichnet [Anzahl der untergeordneten Bäume, die dem Knoten gehören].
Grad des Baums: Der Maximalwert jedes Knotengrades, dh der Grad aller Knoten wird verglichen und der Maximalwert ermittelt
Blatt [oder Endknoten]: Knoten mit Grad 0
Nicht-terminale Knoten: Knoten mit einem anderen Grad als 0 werden als nicht-terminale Knoten oder Verzweigungsknoten bezeichnet. Neben dem Wurzelknoten werden Verzweigungsknoten auch interne Knoten genannt
Eltern und Kinder: Ein Knoten und die Wurzel seines Unterbaums werden als Kinder des Knotens bezeichnet. Entsprechend wird der Knoten als Eltern des Kindes bezeichnet.
Vorfahr: alle Knoten auf den Zweigen von der Wurzel bis zum Knoten
Nachkommen: Jeder Knoten im Teilbaum, der an einem bestimmten Knoten wurzelt, wird als Nachkomme bezeichnet.
Ebene: Ausgehend von der Definition des Baums ist die Wurzel die erste Ebene und die untergeordneten Elemente der Wurzel die zweite Ebene. Die Ebene jedes Knotens im Baum entspricht der Ebene seines übergeordneten Knotens plus eins.
Cousins: Knoten, deren Eltern auf derselben Ebene liegen, werden Cousins genannt
Tiefe des Baums: Die maximale Höhe der Knoten im Baum wird als Tiefe oder Höhe des Baums bezeichnet
Geordneter Baum und ungeordneter Baum: Wenn die Teilbäume der Knoten als von links nach rechts geordnet betrachtet werden, spricht man von einem geordneten Baum, andernfalls handelt es sich um einen ungeordneten Baum [wahrscheinlich, wenn die angegebene Position nicht geändert werden kann, dann in diesem Baum Die Position jedes Knotens kann nicht geändert werden. In einem geordneten Baum wird die Wurzel des Teilbaums ganz links als erstes Kind und das Kind ganz rechts als letztes Kind bezeichnet.
Wald: Es handelt sich um eine Sammlung von m disjunkten Bäumen, m ist größer oder gleich 0. Für jeden Knoten im Baum wird die Menge seiner Teilbäume als Wald bezeichnet.
Kernpunkt: Die Summe der Grade aller Knoten im Baum ist gleich dem Summenpunkt minus 1 [mit Ausnahme des Wurzelknotens nimmt jeder Knoten an der Berechnung der Gradzahl teil]
Baumspeicherstruktur
Elternvertretung
Beschreibung: Die Eigenschaft, einen Baum in einer Reihe kontinuierlicher Speichereinheiten zu speichern, macht es einfach, die übergeordneten Knoten eines Knotens zu finden, aber um die untergeordneten Knoten eines Knotens zu finden, muss die gesamte Struktur durchlaufen werden.
Jeder Knoten enthält ein Datenfeld und ein übergeordnetes Feld. Letzteres speichert den Index des übergeordneten Knotens, wie in der Abbildung dargestellt.
Kindervertretung
Binärbaum [eine Menge bestehend aus n Knoten, n ist größer oder gleich 0]
Der Unterschied zwischen einem Binärbaum und einem Baum: Jeder Knoten eines Binärbaums hat höchstens zwei Teilbäume. Die Teilbäume sind in linke und rechte Teilbäume unterteilt und ihre Reihenfolge kann nicht umgekehrt werden.
Definition [Baumbegriffe gelten grundsätzlich für Binärbäume]
Es gibt nur einen Wurzelknoten
Mit Ausnahme des Wurzelknotens sind andere Knoten in zwei disjunkte Teilmengen unterteilt, die als linker Teilbaum bzw. rechter Teilbaum bezeichnet werden und ebenfalls binäre Bäume sind.
Eigenschaften von Binärbäumen
Eigenschaft 1: Es gibt höchstens 2^i-1 Knoten in der [i]ten Ebene des Binärbaums (i ist größer oder gleich 1) [entspricht einer geometrischen Folge mit 1 als erstem Term und 2 als gemeinsames Verhältnis]
Eigenschaft 2: Ein Binärbaum mit der Tiefe k hat höchstens (2^k)-1 Knoten (k ist größer oder gleich 1) [entspricht einer geometrischen Folge mit 1 als erstem Term und 2 als gemeinsamem Verhältnis ist die Summe der ersten n Terme.
Eigenschaft 3: Für jeden Binärbaum ist die Anzahl der Endknoten gleich der Summe der Knoten mit Grad 2 plus 1
Vollständiger Binärbaum: Ein Binärbaum mit der Tiefe k und der Anzahl der Knoten beträgt 2^k minus 1 [entspricht dem Grad aller Knoten außer dem Wurzelknoten und den 2^i-1 Endknoten auf der höchsten Ebene, die 2 sind]
Vollständiger Binärbaum: Ein Binärbaum mit n Knoten der Tiefe k, genau dann, wenn jeder seiner Knoten den Knoten mit den Nummern 1 bis n im vollständigen Binärbaum der Tiefe k entspricht. [Der Unterschied zu einem vollständigen Binärbaum liegt in der Anzahl der Knoten]
Eigenschaft 1: Ein vollständiger Binärbaum mit n Knoten, deren Tiefe dem Logarithmus von n mit der Basis 2 plus eins entspricht
Eigenschaft 2:
Binäre Baumspeicherstruktur
Sequentielle Speicherstruktur [gilt nur für vollständige Binärbäume, allgemeine Binärbäume können ebenfalls verwendet werden, aber es ist eine Verschwendung von Speichereinheiten]
Erläuterung: Die sequentielle Speicherstruktur verwendet eine kontinuierliche Speichereinheit zum Speichern von Elementen. Um die logische Beziehung zwischen Knoten widerzuspiegeln, müssen die Knoten nach bestimmten Regeln gespeichert werden.
Speichermethode: Für einen vollständigen Binärbaum wird er vom Wurzelknoten in hierarchischer Reihenfolge von oben nach unten und von links nach rechts gespeichert. Die allgemeine Speichermethode von Binärbäumen besteht darin, dass im Vergleich zum vollständigen Binärbaum die entsprechenden Positionen ohne Knoten beim Speichern durch 0 dargestellt werden.
Kettenspeicherstruktur
Jeder Knoten enthält ein Datenfeld und die Zeigerfelder 1child und rchild, die auf die linken und rechten untergeordneten Elemente zeigen. Diese Art von verknüpfter Liste wird als binär verknüpfte Liste bezeichnet.
Um die Eltern des untergeordneten Knotens leicht zu finden, können Sie manchmal ein Zeigerfeld [parent] hinzufügen, das auf die Eltern verweist. Diese Art von verknüpfter Liste wird als dreigliedrige verknüpfte Liste bezeichnet.
Der Kopfzeiger der verknüpften Liste zeigt auf den Wurzelknoten
Durchquerung eines Binärbaums
Durchquerung eines Binärbaums vorbestellen
Besuchen Sie zuerst den Wurzelknoten
Durchlaufen Sie dann den linken Teilbaum der Reihe nach
Letzte Reihenfolge: Durchqueren Sie den rechten Teilbaum
Inorder-Traversierung eines Binärbaums
Durchquerung des linken Teilbaums in der richtigen Reihenfolge
Zugriff auf den Root-Knoten
Durchquerung des rechten Teilbaums in der richtigen Reihenfolge
Postorder-Traversierung eines Binärbaums
Postorder-Durchquerung des linken Teilbaums
Postorder-Durchquerung des rechten Teilbaums
Zugriff auf den Root-Knoten
linearer Tisch
Definition: Eine [endliche] Folge von n (n>0) [Elementen] mit [gleichen Dateneigenschaften] wird als lineare Tabelle bezeichnet.
Hinweis: Die Anzahl der Elemente n in der linearen Tabelle [n>0] ist als Länge der linearen Tabelle definiert. Wenn n gleich 0 ist, handelt es sich um eine leere Tabelle.
Merkmale [Zusammenfassung: Die Einzigartigkeit von Kopf und Schwanz sowie die Tatsache, dass der Kopf keinen Vorderantrieb und der Schwanz keinen Hinterantrieb hat. 】
Es gibt nur ein Datenelement namens [first]
Es gibt nur ein Datenelement namens [last]
Bis auf das erste Element hat jedes Datenelement in der Struktur nur einen Vorgänger
Jedes Datenelement in der Struktur, bis auf das letzte Element, hat genau einen Nachfolger
Definition des linearen Tabellentyps
Sequentielle Darstellung und Implementierung linearer Tabellen ([Sequentielle Speicherstruktur] [Sequentielles Bild])
Definition: bezieht sich auf die Verwendung einer Reihe kontinuierlicher Speichereinheiten, um Datenelemente einer linearen Tabelle nacheinander zu speichern
Merkmale: Logisch benachbarte Elemente sind auch strukturell benachbart, das heißt, die logische und physikalische Struktur entsprechen sich. Es handelt sich um eine zufällige Speicherstruktur.
Operation [Gleichzeitig wurde der kontinuierliche Speicherplatz geöffnet. Wir können jede Position im Array direkt darstellen (z. B. L.elem[i]=e), da die Zeigervariable in der Struktur darauf zeigt die erste Adresse des Raums, äquivalent zum Array-Namen. 】
Initialisierung: Öffnen Sie dynamisch einen Satz kontinuierlicher Speicherplätze, stellen Sie fest, ob das Öffnen erfolgreich ist, setzen Sie dann die Länge der linearen Tabelle auf 0 und geben Sie den entsprechenden Beurteilungswert zurück
Einfügen: Beurteilen Sie zunächst die Rationalität der Einfügeposition, verschieben Sie das Element an die entsprechende Position, fügen Sie dann das Datenelement an der entsprechenden Position ein, addieren Sie dann 1 zur Tabellenlänge und geben Sie den entsprechenden Beurteilungswert zurück.
Wert: Um die Rationalität des Werts zu bestimmen, nehmen Sie einfach den Wert der entsprechenden Position direkt.
Löschen: Beurteilen Sie zunächst die Rationalität der gelöschten Position, löschen Sie dann direkt den Wert an der entsprechenden Position und geben Sie den gelöschten Wert zurück, verschieben Sie die Werte auf beiden Seiten, reduzieren Sie dann die Länge der linearen Tabelle um eins und geben Sie den Wert zurück entsprechenden Urteilswert.
Leeren und zerstören: Ersteres dient dazu, die Länge der linearen Tabelle auf 0 zu setzen, und letzteres dient dazu, den geöffneten Raum freizugeben
Diagramm verstehen
Verknüpfte Darstellung und Implementierung linearer Tabellen ([nicht sequentielles Bild] [verkettetes Bild]) [logisch benachbart, nicht erforderlich, dass der physische Standort gleich ist]
Definition einer verketteten Speicherstruktur: Ein Satz beliebiger Speichereinheiten speichert Datenelemente einer linearen Tabelle. Dieser Satz von Speichereinheiten kann entweder kontinuierlich oder diskontinuierlich sein.
Merkmale: Aufgrund der Speicherstruktur muss die Elementverarbeitung vom Kopfzeiger aus beginnen, daher wird sie auch als sequentielle Speicherzugriffsstruktur bezeichnet.
Grund: Um die logische Beziehung zwischen benachbarten Datenelementen auszudrücken, drücken wir genau aufgrund dieser Speicherstruktur die Speicheradresse des unmittelbaren Nachfolgers im unmittelbaren Vorgänger aus. Daher gilt in der C-Sprache: Indem Sie die Datendomäne und die Zeigerfelder definieren, um dieses Element zu bilden, nennen Sie es einen Knoten. Die im Zeigerfeld gespeicherten Informationen werden als Zeiger oder Kette bezeichnet, und n Knoten bilden eine lineare Tabelle. [Da es im Knoten nur ein Zeigerfeld gibt, wird die auf diese Weise erstellte lineare Liste als lineare verknüpfte Liste oder einfach verknüpfte Liste bezeichnet. 】
erklären, unterscheiden, notieren
veranschaulichen
Definition verknüpfter Listenknoten
#! ElemType ist ein universeller Typbezeichner und kann bei Bedarf durch define ersetzt werden
#! Für die Lesbarkeit des Programms werden zwei Strukturvariablen, LNode und *LinkList, definiert. Erstere wird normalerweise zum Definieren des Knotens und letztere zum Definieren des Kopfzeigers der verknüpften Liste verwendet.
#! Eine einfach verknüpfte Liste wird jedoch eindeutig durch den Kopfzeiger bestimmt, sodass die einfach verknüpfte Liste mithilfe des Kopfzeigers benannt werden kann. Wenn der Kopfzeiger L ist, ist auch die verknüpfte Liste L.
unterscheiden
Knotenvariablen: der Name jedes Knotens
Zeigervariable: Zeiger auf Knoten
Kopfknoten: Um die Verarbeitung zu erleichtern, wird vor dem ersten Knoten der einfach verknüpften Liste ein Knoten angehängt, der als Kopfknoten bezeichnet wird. Das Datenfeld kann selektiv gespeichert werden, und das Zeigerfeld zeigt auf den ersten Knoten.
Kopfzeiger: Ein Zeiger, der auf den ersten Knoten in der verknüpften Liste zeigt. Abhängig davon, ob ein Kopfknoten vorhanden ist, werden unterschiedliche Zeigeobjekte generiert.
Hauptknoten: Bezieht sich auf den Knoten, der das erste Datenelement in der verknüpften Liste speichert.
Hinweis: Der zweite Schritt in der Erklärung ist sehr wichtig, da die beiden Strukturen unterschiedliche Namen haben, aber gleichwertig sind.
Erstellen Sie eine einfach verknüpfte Liste
Vorwärtsinterpolationsmethode: Fügen Sie nach jeder Anwendung einen neuen Knoten nach dem Kopfknoten ein. Achten Sie auf die Speicherung von Elementwerten.
Algorithmusschritte
#! Erstellen Sie zunächst eine verknüpfte Liste nur mit dem Kopfknoten
#! Führen Sie entsprechend der in der verknüpften Liste enthaltenen Zahl n eine Schleife n-mal durch
#Generieren Sie einen neuen Knoten*p
#Geben Sie den Elementwert ein und speichern Sie ihn im Datenfeld
#Fügen Sie den neuen Knoten nach dem Hauptknoten ein
Schematische Darstellung
Methode nach dem Einfügen: Lassen Sie zunächst einen Endzeiger auf den Endknoten der verknüpften Liste zeigen, wenden Sie dann jedes Mal einen neuen Knoten an und fügen Sie ihn nach dem Endknoten ein. Bewegen Sie dann den Endzeiger so, dass er auf die Position zeigt neuer Knoten
Beschreibung des Algorithmus
#! Erstellen Sie zunächst eine verknüpfte Liste nur mit dem Kopfknoten und initialisieren Sie dann den Endzeiger so, dass er auf den Kopfknoten zeigt.
Führen Sie entsprechend der Anzahl der verknüpften Listen n n Schleifen durch
#Bewerben Sie sich für einen neuen Knoten*p
#Weisen Sie den Eingabeelementwert der Speicherstruktur zu
#Fügen Sie den neuen Knoten nach dem Endzeiger ein
#Bewegen Sie den Endzeiger so, dass er auf den neuen Endzeiger zeigt
arbeiten
Initialisierung
【1】Generieren Sie einen neuen Knoten als Kopfknoten und stellen Sie sicher, dass der Kopfzeiger auf den Kopfknoten zeigt
【2】Das Datenfeld des Hauptknotens bleibt leer
[Schematische Darstellung]