Suche…


Einführung

Algorithmen sind ein Rückgrat für das Rechnen. Die Wahl des zu verwendenden Algorithmus in welcher Situation unterscheidet einen Durchschnitt von einem guten Programmierer. Vor diesem Hintergrund finden Sie hier Definitionen und Codebeispiele für einige der grundlegenden Algorithmen.

Sortieren durch Einfügen

Einfügungssortierung ist einer der grundlegenderen Algorithmen in der Informatik. Die Einfügungssortierung sortiert Elemente, indem sie eine Collection durchläuft, und positioniert Elemente basierend auf ihrem Wert. Der Satz ist in sortierte und unsortierte Hälften unterteilt und wiederholt, bis alle Elemente sortiert sind. Einfügungssortierung hat Komplexität von O (n2). Sie können es in eine Erweiterung einfügen, wie in einem Beispiel unten, oder Sie können eine Methode dafür erstellen.

extension Array where Element: Comparable {

func insertionSort() -> Array<Element> {
    
    //check for trivial case
    guard self.count > 1 else {
        return self
    }
    
    //mutated copy
    var output: Array<Element> = self
    
    for primaryindex in 0..<output.count {
        
        let key = output[primaryindex]
        var secondaryindex = primaryindex
        
        while secondaryindex > -1 {
            if key < output[secondaryindex] {
                
                //move to correct position
                output.remove(at: secondaryindex + 1)
                output.insert(key, at: secondaryindex)
            }
            secondaryindex -= 1
        }
    }
    
    return output
}
}

Sortierung

Bubble Sort

Dies ist ein einfacher Sortieralgorithmus, der die zu sortierende Liste wiederholt durchläuft, jedes Paar benachbarter Elemente miteinander vergleicht und sie austauscht, wenn sie in der falschen Reihenfolge sind. Der Durchlauf der Liste wird wiederholt, bis keine Swaps erforderlich sind. Obwohl der Algorithmus einfach ist, ist er für die meisten Probleme zu langsam und unpraktisch. Es hat eine Komplexität von O (n2), gilt jedoch als langsamer als die Einfügesortierung.

extension Array where Element: Comparable {

func bubbleSort() -> Array<Element> {
    
    //check for trivial case
    guard self.count > 1 else {
        return self
    }
    
    //mutated copy
    var output: Array<Element> = self
    
    for primaryIndex in 0..<self.count {
        let passes = (output.count - 1) - primaryIndex
        
        //"half-open" range operator
        for secondaryIndex in 0..<passes {
            let key = output[secondaryIndex]
            
            //compare / swap positions
            if (key > output[secondaryIndex + 1]) {
                swap(&output[secondaryIndex], &output[secondaryIndex + 1])
            }
        }
    }
    
    return output
}

}

Sortieren durch Einfügen

Einfügungssortierung ist einer der grundlegenderen Algorithmen in der Informatik. Die Einfügungssortierung sortiert Elemente, indem sie eine Collection durchläuft, und positioniert Elemente basierend auf ihrem Wert. Der Satz ist in sortierte und unsortierte Hälften unterteilt und wiederholt, bis alle Elemente sortiert sind. Einfügungssortierung hat Komplexität von O (n2). Sie können es in eine Erweiterung einfügen, wie in einem Beispiel unten, oder Sie können eine Methode dafür erstellen.

extension Array where Element: Comparable {

func insertionSort() -> Array<Element> {
    
    //check for trivial case
    guard self.count > 1 else {
        return self
    }
    
    //mutated copy
    var output: Array<Element> = self
    
    for primaryindex in 0..<output.count {
        
        let key = output[primaryindex]
        var secondaryindex = primaryindex
        
        while secondaryindex > -1 {
            if key < output[secondaryindex] {
                
                //move to correct position
                output.remove(at: secondaryindex + 1)
                output.insert(key, at: secondaryindex)
            }
            secondaryindex -= 1
        }
    }
    
    return output
}
}

Auswahl sortieren

Die Auswahl der Auswahl ist für ihre Einfachheit bekannt. Es beginnt mit dem ersten Element im Array und speichert seinen Wert als Mindestwert (oder als Maximum, abhängig von der Sortierreihenfolge). Es iteriert dann durch das Array und ersetzt den min-Wert durch einen anderen Wert, der kleiner ist als der auf dem Weg gefundene min. Dieser minimale Wert wird dann ganz links im Array platziert und der Prozess wird ab dem nächsten Index bis zum Ende des Arrays wiederholt. Auswahlsortierung hat Komplexität von O (n2), wird aber als langsamer angesehen als das Gegenstück - Auswahlsortierung.

func selectionSort () -> Array {// auf triviales Case Guard prüfen self.count> 1 else {return self}

//mutated copy
var output: Array<Element> = self
 
for primaryindex in 0..<output.count {
    var minimum = primaryindex
    var secondaryindex = primaryindex + 1
     
    while secondaryindex < output.count {
        //store lowest value as minimum
        if output[minimum] > output[secondaryindex] {
            minimum = secondaryindex
        }
        secondaryindex += 1
    }
     
    //swap minimum value with array iteration
    if primaryindex != minimum {
        swap(&output[primaryindex], &output[minimum])
    }
}
 
return output 
}

Schnelle Sortierung - O (n log n) Komplexitätszeit

Quicksort ist einer der fortgeschrittenen Algorithmen. Es verfügt über eine zeitliche Komplexität von O (n log n) und wendet eine Divide & Conquer-Strategie an. Diese Kombination führt zu einer erweiterten algorithmischen Leistung. Quicksort unterteilt zunächst ein großes Array in zwei kleinere Sub-Arrays: die Low-Elemente und die High-Elemente. Quicksort kann dann die Unterfelder rekursiv sortieren.

Die Schritte sind:

Wählen Sie aus dem Array ein Element aus, das als Drehpunkt bezeichnet wird.

Ordnen Sie das Array neu an, so dass alle Elemente mit Werten unter dem Pivot vor dem Pivot stehen, während alle Elemente mit Werten über dem Pivot danach folgen (gleiche Werte können in beide Richtungen gehen). Nach dieser Unterteilung befindet sich der Drehpunkt in seiner Endposition. Dies wird als Partitionsoperation bezeichnet.

Wenden Sie die obigen Schritte rekursiv auf das Unterfeld von Elementen mit kleineren Werten und separat auf das Unterfeld von Elementen mit höheren Werten an.

mutierendes func quickSort () -> Array {

func qSort(start startIndex: Int, _ pivot: Int) {
    
    if (startIndex < pivot) {
        let iPivot = qPartition(start: startIndex, pivot)
        qSort(start: startIndex, iPivot - 1)
        qSort(start: iPivot + 1, pivot)
    }
}
qSort(start: 0, self.endIndex - 1)
return self
}

mutating func qPartition(start startIndex: Int, _ pivot: Int) -> Int {

var wallIndex: Int = startIndex

//compare range with pivot
for currentIndex in wallIndex..<pivot {
    
    if self[currentIndex] <= self[pivot] {
        if wallIndex != currentIndex {
            swap(&self[currentIndex], &self[wallIndex])
        }
        
        //advance wall
        wallIndex += 1
    }
}
    //move pivot to final position
    if wallIndex != pivot {
        swap(&self[wallIndex], &self[pivot])
    }
    return wallIndex
}

Auswahl sortieren

Die Auswahl der Auswahl ist für ihre Einfachheit bekannt. Es beginnt mit dem ersten Element im Array und speichert seinen Wert als Mindestwert (oder als Maximum, abhängig von der Sortierreihenfolge). Es iteriert dann durch das Array und ersetzt den min-Wert durch einen anderen Wert, der kleiner ist als der auf dem Weg gefundene min. Dieser minimale Wert wird dann ganz links im Array platziert und der Prozess wird ab dem nächsten Index bis zum Ende des Arrays wiederholt. Auswahlsortierung hat Komplexität von O (n2), wird aber als langsamer angesehen als das Gegenstück - Auswahlsortierung.

func selectionSort() -> Array<Element> {
    //check for trivial case
    guard self.count > 1 else {
        return self
    }
     
    //mutated copy
    var output: Array<Element> = self
     
    for primaryindex in 0..<output.count {
        var minimum = primaryindex
        var secondaryindex = primaryindex + 1
         
        while secondaryindex < output.count {
            //store lowest value as minimum
            if output[minimum] > output[secondaryindex] {
                minimum = secondaryindex
            }
            secondaryindex += 1
        }
         
        //swap minimum value with array iteration
        if primaryindex != minimum {
            swap(&output[primaryindex], &output[minimum])
        }
    }
     
    return output
}

Asymptotische Analyse

Da wir viele verschiedene Algorithmen zur Auswahl haben, müssen wir beim Sortieren eines Arrays wissen, welcher Algorithmus seine Aufgabe erfüllt. Wir brauchen also eine Methode, um die Geschwindigkeit und Zuverlässigkeit von algoritm zu messen. Hier setzt die asymptotische Analyse an. Bei der asymptotischen Analyse wird die Effizienz von Algorithmen beschrieben, wenn ihre Eingangsgröße (n) wächst. In der Informatik werden Asymptotika normalerweise in einem üblichen Format ausgedrückt, das als Big O Notation bekannt ist.

  • Lineare Zeit O (n) : Wenn jedes Element im Array ausgewertet werden muss, damit eine Funktion ihr Ziel erreicht, bedeutet dies, dass die Funktion mit zunehmender Anzahl von Elementen weniger effizient wird. Eine Funktion wie diese läuft in linearer Zeit, da ihre Geschwindigkeit von der Eingangsgröße abhängt.
  • Polynom-Zeit O (n2) : Wenn die Komplexität einer Funktion exponentiell zunimmt (dh für n Elemente eines Arrays ist die Komplexität einer Funktion n im Quadrat), arbeitet diese Funktion in Polynom-Zeit. Dies sind normalerweise Funktionen mit verschachtelten Schleifen. Zwei verschachtelte Schleifen führen zu einer O (n2) -Komplexität, drei verschachtelten Schleifen zu einer O (n3) -Komplexität usw.
  • Logarithmische Zeit O (log n): Die Komplexität logarithmischer Zeitfunktionen wird minimiert, wenn die Größe ihrer Eingänge (n) zunimmt. Dies ist die Art von Funktionen, die jeder Programmierer anstrebt.

Schnelle Sortierung - O (n log n) Komplexitätszeit

Quicksort ist einer der fortgeschrittenen Algorithmen. Es verfügt über eine zeitliche Komplexität von O (n log n) und wendet eine Divide & Conquer-Strategie an. Diese Kombination führt zu einer erweiterten algorithmischen Leistung. Quicksort unterteilt zunächst ein großes Array in zwei kleinere Sub-Arrays: die Low-Elemente und die High-Elemente. Quicksort kann dann die Unterfelder rekursiv sortieren.

Die Schritte sind:

  1. Wählen Sie aus dem Array ein Element aus, das als Drehpunkt bezeichnet wird.

  2. Ordnen Sie das Array neu an, so dass alle Elemente mit Werten unter dem Pivot vor dem Pivot stehen, während alle Elemente mit Werten über dem Pivot danach folgen (gleiche Werte können in beide Richtungen gehen). Nach dieser Unterteilung befindet sich der Drehpunkt in seiner Endposition. Dies wird als Partitionsoperation bezeichnet.

  3. Wenden Sie die obigen Schritte rekursiv auf das Unterfeld von Elementen mit kleineren Werten und separat auf das Unterfeld von Elementen mit höheren Werten an.

    mutating func quickSort() -> Array<Element> {
    
    func qSort(start startIndex: Int, _ pivot: Int) {
        
        if (startIndex < pivot) {
            let iPivot = qPartition(start: startIndex, pivot)
            qSort(start: startIndex, iPivot - 1)
            qSort(start: iPivot + 1, pivot)
        }
    }
    qSort(start: 0, self.endIndex - 1)
    return self
    

    }

    mutating func qPartition (start startIndex: Int, _ Pivot: Int) -> Int {

    var wallIndex: Int = startIndex
    
    //compare range with pivot
    for currentIndex in wallIndex..<pivot {
        
        if self[currentIndex] <= self[pivot] {
            if wallIndex != currentIndex {
                swap(&self[currentIndex], &self[wallIndex])
            }
            
            //advance wall
            wallIndex += 1
        }
    }
    
    //move pivot to final position
    if wallIndex != pivot {
        swap(&self[wallIndex], &self[pivot])
    }
    return wallIndex
}

Diagramm, Trie, Stapel

Graph

In der Informatik ist ein Graph ein abstrakter Datentyp, der den ungerichteten Graph und gerichtete Graphkonzepte aus der Mathematik implementieren soll. Eine Diagrammdatenstruktur besteht aus einer endlichen (und möglicherweise veränderbaren) Menge von Scheitelpunkten oder Knoten oder Punkten zusammen mit einem Satz ungeordneter Paare dieser Scheitelpunkte für einen ungerichteten Graphen oder einem Satz geordneter Paare für einen gerichteten Graphen. Diese Paare sind als Kanten, Bögen oder Linien für einen ungerichteten Graphen und als Pfeile, gerichtete Kanten, gerichtete Bögen oder gerichtete Linien für einen gerichteten Graphen bekannt. Die Scheitelpunkte können Teil der Graphstruktur sein oder können externe Entitäten sein, die durch ganzzahlige Indizes oder Referenzen dargestellt werden. Eine Diagrammdatenstruktur kann jeder Kante auch einen bestimmten Kantenwert zuordnen, beispielsweise eine symbolische Beschriftung oder ein numerisches Attribut (Kosten, Kapazität, Länge usw.). (Wikipedia, Quelle )

//
//  GraphFactory.swift
//  SwiftStructures
//
//  Created by Wayne Bishop on 6/7/14.
//  Copyright (c) 2014 Arbutus Software Inc. All rights reserved.
//
import Foundation


public class SwiftGraph {
   
    
    //declare a default directed graph canvas
    private var canvas: Array<Vertex>
    public var isDirected: Bool
    
    
    init() {
        canvas = Array<Vertex>()
        isDirected = true
    }
    
    
    //create a new vertex
    func addVertex(key: String) -> Vertex {
        
        
        //set the key
        let childVertex: Vertex = Vertex()
        childVertex.key = key
        
        
        //add the vertex to the graph canvas
        canvas.append(childVertex)
        
        
        return childVertex
    }
    
    
    
    //add edge to source vertex
    func addEdge(source: Vertex, neighbor: Vertex, weight: Int) {
        
        
        //create a new edge
        let newEdge = Edge()
        
        
        //establish the default properties
        newEdge.neighbor = neighbor
        newEdge.weight = weight
        source.neighbors.append(newEdge)
        
        
        print("The neighbor of vertex: \(source.key as String!) is \(neighbor.key as String!)..")
        
        
        //check condition for an undirected graph
        if isDirected == false {
            
            
           //create a new reversed edge
           let reverseEdge = Edge()
            
            
           //establish the reversed properties
           reverseEdge.neighbor = source
           reverseEdge.weight = weight
           neighbor.neighbors.append(reverseEdge)
            
           print("The neighbor of vertex: \(neighbor.key as String!) is \(source.key as String!)..")
            
        }
        
        
    }

    
    
    
    
    /* reverse the sequence of paths given the shortest path.
       process analagous to reversing a linked list. */

    func reversePath(_ head: Path!, source: Vertex) -> Path! {
        
        
        guard head != nil else {
            return head
        }
        
        //mutated copy
        var output = head
        
        
        var current: Path! = output
        var prev: Path!
        var next: Path!
        
        
        while(current != nil) {
            next = current.previous
            current.previous = prev
            prev = current
            current = next
        }
        
        
        //append the source path to the sequence
        let sourcePath: Path = Path()
        
        sourcePath.destination = source
        sourcePath.previous = prev
        sourcePath.total = nil
        
        output = sourcePath
        
        
        return output
        
    }

    
    
    
    //process Dijkstra's shortest path algorthim
    func processDijkstra(_ source: Vertex, destination: Vertex) -> Path? {
        
        
        var frontier: Array<Path> = Array<Path>()
        var finalPaths: Array<Path> = Array<Path>()
        
        
        //use source edges to create the frontier
        for e in source.neighbors {
            
            let newPath: Path = Path()
            
            
            newPath.destination = e.neighbor
            newPath.previous = nil
            newPath.total = e.weight
            
            
            //add the new path to the frontier
            frontier.append(newPath)
            
        }
        

        //construct the best path
        var bestPath: Path = Path()
        
        
        while frontier.count != 0 {
            
            //support path changes using the greedy approach
            bestPath = Path()
            var pathIndex: Int = 0

            
            for x in 0..<frontier.count {
               
                let itemPath: Path = frontier[x]
                
                if  (bestPath.total == nil) || (itemPath.total < bestPath.total) {
                    bestPath = itemPath
                    pathIndex = x
                }
                
            }
            
            
            
            //enumerate the bestPath edges
            for e in bestPath.destination.neighbors {
                
                let newPath: Path = Path()
                
                newPath.destination = e.neighbor
                newPath.previous = bestPath
                newPath.total = bestPath.total + e.weight
                
                
                //add the new path to the frontier
                frontier.append(newPath)
                
            }
            
            
            //preserve the bestPath
            finalPaths.append(bestPath)
            
            
            //remove the bestPath from the frontier
            //frontier.removeAtIndex(pathIndex) - Swift2
            frontier.remove(at: pathIndex)
            
            
            
        } //end while
        
        
    
        //establish the shortest path as an optional
        var shortestPath: Path! = Path()
        
        
        for itemPath in finalPaths {
            
            if (itemPath.destination.key == destination.key) {
                
                if  (shortestPath.total == nil) || (itemPath.total < shortestPath.total) {
                    shortestPath = itemPath
                }
                
            }
            
        }
        
        
        return shortestPath
        
    }
    
    
    
    ///an optimized version of Dijkstra's shortest path algorthim
    func processDijkstraWithHeap(_ source: Vertex, destination: Vertex) -> Path! {
        
        
        let frontier: PathHeap = PathHeap()
        let finalPaths: PathHeap = PathHeap()
        
        
        //use source edges to create the frontier
        for e in source.neighbors {
            
            let newPath: Path = Path()
            
            
            newPath.destination = e.neighbor
            newPath.previous = nil
            newPath.total = e.weight
            
            
            //add the new path to the frontier
            frontier.enQueue(newPath)
            
        }
        
        
        //construct the best path
        var bestPath: Path = Path()
        
        
        while frontier.count != 0 {
                        
            //use the greedy approach to obtain the best path
            bestPath = Path()
            bestPath = frontier.peek()
            
            
            //enumerate the bestPath edges
            for e in bestPath.destination.neighbors {
                
                let newPath: Path = Path()
                
                newPath.destination = e.neighbor
                newPath.previous = bestPath
                newPath.total = bestPath.total + e.weight
                
                
                //add the new path to the frontier
                frontier.enQueue(newPath)
                
            }
            
            
            //preserve the bestPaths that match destination
            if (bestPath.destination.key == destination.key) {
                finalPaths.enQueue(bestPath)
            }
            
            
            //remove the bestPath from the frontier
            frontier.deQueue()
            
            
        } //end while
        
        
        
        //obtain the shortest path from the heap
        var shortestPath: Path! = Path()
        shortestPath = finalPaths.peek()
        
        
        return shortestPath
        
    }
    
    
    //MARK: traversal algorithms
    
    
    //bfs traversal with inout closure function
    func traverse(_ startingv: Vertex, formula: (_ node: inout Vertex) -> ()) {

        
        //establish a new queue
        let graphQueue: Queue<Vertex> = Queue<Vertex>()
        
        
        //queue a starting vertex
        graphQueue.enQueue(startingv)
        
        
        while !graphQueue.isEmpty() {
            
            //traverse the next queued vertex
            var vitem: Vertex = graphQueue.deQueue() as Vertex!
            
            
            //add unvisited vertices to the queue
            for e in vitem.neighbors {
                if e.neighbor.visited == false {
                    print("adding vertex: \(e.neighbor.key!) to queue..")
                    graphQueue.enQueue(e.neighbor)
                }
            }
            

            /*
            notes: this demonstrates how to invoke a closure with an inout parameter.
            By passing by reference no return value is required.
            */
            
            //invoke formula
            formula(&vitem)
            
            
        } //end while
        
        
        print("graph traversal complete..")
        
        
    }

    
    
    
    //breadth first search
    func traverse(_ startingv: Vertex) {
        
        
        //establish a new queue
        let graphQueue: Queue<Vertex> = Queue<Vertex>()
        
        
        //queue a starting vertex
        graphQueue.enQueue(startingv)
        
        
        while !graphQueue.isEmpty() {
            
            //traverse the next queued vertex
            let vitem = graphQueue.deQueue() as Vertex!
            
            guard vitem != nil else {
                return
            }
            
            //add unvisited vertices to the queue
            for e in vitem!.neighbors {
                if e.neighbor.visited == false {
                    print("adding vertex: \(e.neighbor.key!) to queue..")
                    graphQueue.enQueue(e.neighbor)
                }
            }
            
            
            vitem!.visited = true
            print("traversed vertex: \(vitem!.key!)..")
            
            
        } //end while
        
        
        print("graph traversal complete..")
        
        
    } //end function
    
    
    
    //use bfs with trailing closure to update all values
    func update(startingv: Vertex, formula:((Vertex) -> Bool)) {
        
        
        //establish a new queue
        let graphQueue: Queue<Vertex> = Queue<Vertex>()
        
        
        //queue a starting vertex
        graphQueue.enQueue(startingv)
        
        
        while !graphQueue.isEmpty() {
            
            //traverse the next queued vertex
            let vitem = graphQueue.deQueue() as Vertex!            
            
            guard vitem != nil else {
                return
            }
            
            //add unvisited vertices to the queue
            for e in vitem!.neighbors {
                if e.neighbor.visited == false {
                    print("adding vertex: \(e.neighbor.key!) to queue..")
                    graphQueue.enQueue(e.neighbor)
                }
            }
            
            
            //apply formula..
            if formula(vitem!) == false {
                print("formula unable to update: \(vitem!.key)")
            }
            else {
                print("traversed vertex: \(vitem!.key!)..")
            }
            
            vitem!.visited = true
            
            
        } //end while
        
        
        print("graph traversal complete..")
        
        
    }

    

    
    
}

Trie

In der Informatik ist ein Trie, auch Digital Tree und manchmal Radix Tree oder Prefix Tree (da er nach Präfixen gesucht werden kann) eine Art Suchbaum - eine geordnete Baumdatenstruktur, in der ein dynamischer Satz oder ein Assoziativ gespeichert wird Array, bei dem die Schlüssel normalerweise aus Zeichenketten bestehen. (Wikipedia, Quelle )

//
//  Trie.swift
//  SwiftStructures
//
//  Created by Wayne Bishop on 10/14/14.
//  Copyright (c) 2014 Arbutus Software Inc. All rights reserved.
//
import Foundation


public class Trie {
    
    private var root: TrieNode!
    
    
    init(){
        root = TrieNode()
    }
    
    
    
    //builds a tree hierarchy of dictionary content
    func append(word keyword: String) {
        
        
        //trivial case
        guard keyword.length > 0 else {
            return
        }
        
        
        var current: TrieNode = root
        
        
        while keyword.length != current.level {
            
            var childToUse: TrieNode!
            let searchKey = keyword.substring(to: current.level + 1)
            
            
            //print("current has \(current.children.count) children..")
            
            
            //iterate through child nodes
            for child in current.children {
                
                if (child.key == searchKey) {
                    childToUse = child
                    break
                }
                
            }
            
            
            //new node
            if childToUse == nil {
                
                childToUse = TrieNode()
                childToUse.key = searchKey
                childToUse.level = current.level + 1
                current.children.append(childToUse)
            }
            
            
            current = childToUse
            
            
        } //end while
        
        
        //final end of word check
        if (keyword.length == current.level) {
            current.isFinal = true
            print("end of word reached!")
            return
        }
        
        
        
    } //end function
    
    

    
    //find words based on the prefix
    func search(forWord keyword: String) -> Array<String>! {
        
        
        //trivial case
        guard keyword.length > 0 else {
            return nil
        }
        
        
        var current: TrieNode = root
        var wordList = Array<String>()
        
        
        while keyword.length != current.level {
            
            var childToUse: TrieNode!
            let searchKey = keyword.substring(to: current.level + 1)
            

            //print("looking for prefix: \(searchKey)..")
            
            
            //iterate through any child nodes
            for child in current.children {
                
                if (child.key == searchKey) {
                    childToUse = child
                    current = childToUse
                    break
                }
                
            }
            
 
            if childToUse == nil {
               return nil
            }
            
            
        } //end while
        
        
        
        //retrieve the keyword and any descendants
        if ((current.key == keyword) && (current.isFinal)) {
            wordList.append(current.key)
        }

        
        //include only children that are words
        for child in current.children {
            
            if (child.isFinal == true) {
                wordList.append(child.key)
            }
            
        }
        
        
        return wordList

        
    } //end function
    

}

(GitHub, Quelle )

Stapel

In der Informatik ist ein Stapel ein abstrakter Datentyp, der als Auflistung von Elementen dient, mit zwei Hauptoperationen: Push (Hinzufügen), um ein Element zur Auflistung hinzuzufügen, und Pop (Pop), um das zuletzt hinzugefügte Element zu entfernen, das noch nicht entfernt wurde. Die Reihenfolge, in der Elemente von einem Stapel abgehen, führt zu seinem alternativen Namen LIFO (Last-In-First-Out). Darüber hinaus kann eine Peek-Operation Zugriff auf die Oberseite gewähren, ohne den Stapel zu ändern. (Wikipedia, Quelle )

Siehe Lizenzinformationen unten und den ursprünglichen Quellcode unter ( github ).

//
//  Stack.swift
//  SwiftStructures
//
//  Created by Wayne Bishop on 8/1/14.
//  Copyright (c) 2014 Arbutus Software Inc. All rights reserved.
//
import Foundation


class Stack<T> {
    
    private var top: Node<T>
    
    init() {
        top = Node<T>()
    }
    
    
    //the number of items - O(n)
    var count: Int {
        
        
        //return trivial case
        guard top.key != nil else {
          return 0
        }
                
        
        var current = top
        var x: Int = 1
        
        
        //cycle through list
        while current.next != nil {
            current = current.next!
            x += 1
        }
            
        return x        
        
    }
    
    
    //add item to the stack
    func push(withKey key: T) {
        
        
        //return trivial case
        guard top.key != nil else {
            top.key = key
            return
        }
        
        
        //create new item
        let childToUse = Node<T>()
        childToUse.key = key
            
            
        //set new created item at top
        childToUse.next = top
        top = childToUse        

    }
    

    //remove item from the stack
    func pop() {
        
        if self.count > 1 {
            top = top.next
        }
        else {
            top.key = nil
        }
        
    }
    
    
    //retrieve the top most item
    func peek() -> T! {

        
        //determine instance
        if let topitem = top.key {
            return topitem
        }
            
        else {
            return nil
        }
        
    }
    
    
    
    //check for value
    func isEmpty() -> Bool {
        
        if self.count == 0 {
            return true
        }
        
        else {
            return false
        }
        
    }
    

}

Die MIT-Lizenz (MIT)

Copyright (c) 2015, Wayne Bishop und Arbutus Software Inc.

Jede Person, die eine Kopie dieser Software und der zugehörigen Dokumentationsdateien (die "Software") erhält, kann hiermit kostenlos die uneingeschränkte Behandlung der Software, einschließlich der Rechte zur Verwendung, zum Kopieren, Modifizieren und Zusammenführen, vornehmen Kopien der Software veröffentlichen, verteilen, unterlizenzieren und / oder verkaufen und Personen, denen die Software zur Verfügung gestellt wird, die Erlaubnis dazu erteilen, unter den folgenden Bedingungen:

Der obige Copyright-Hinweis und dieser Erlaubnisschein sind in allen Kopien oder wesentlichen Teilen der Software enthalten.

DIE SOFTWARE WIRD "WIE BESEHEN" OHNE JEGLICHE AUSDRÜCKLICHE ODER STILLSCHWEIGENDE GEWÄHRLEISTUNG ZUR VERFÜGUNG GESTELLT, EINSCHLIESSLICH DER GEWÄHRLEISTUNGEN DER MARKTFÄHIGKEIT, DER EIGNUNG FÜR EINEN BESTIMMTEN ZWECK UND NICHT VERLETZUNG. DIE AUTOREN ODER COPYRIGHT-INHABER HAFTEN KEINERLEI HAFTUNG FÜR HAFTUNGSANSPRÜCHE, SCHÄDEN ODER ANDERE HAFTUNGSANSPRÜCHE, unabhängig davon, ob sie einen Vertrag, einen Vertrag oder eine anderweitige Befreiung von der SOFTWARE oder der Verwendung der Software oder sonstiger diesbezüglicher Vereinbarungen enthalten SOFTWARE.



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow