Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

添加Swift跳表实现 #529

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
197 changes: 197 additions & 0 deletions swift/17_skipList/skipList.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
// Created by AlanLXG on 2022/9/14.

import UIKit
import Foundation
import Darwin

// Config max level of all nodes.
let MAX_LEVEL_OF_SKIP_LIST = 16

// Class declaration of node.
public class SkipListNode
{
var nodeData:Int
var nodeLevel:Int
// Next node of current node in all levels, whose value is first above current node.
var nodeForwardData:[SkipListNode?]
public init()
{
nodeData = -1
nodeLevel = 0
nodeForwardData = Array<SkipListNode?>(repeating: nil, count: MAX_LEVEL_OF_SKIP_LIST)
}
// Return a string that containins node value and level.
open func nodeToString() -> String
{
let nodeString = "{ data: \(nodeData); level: \(nodeLevel) }"
return nodeString
}
}

// Class declaration of skip list.
public class SkipList
{
var levelCount:Int
// Use sentinel node to simplify insert and delete process of a skip list.
let sentinelNode:SkipListNode

public init()
{
levelCount = 1
sentinelNode = SkipListNode()
}
// Find a node with a qualified value.

public func findNode(targetVaule:Int) -> SkipListNode?
{
var searchNode = sentinelNode
for level in (0..<levelCount).reversed()
{
while searchNode.nodeForwardData[level] != nil && searchNode.nodeForwardData[level]!.nodeData < targetVaule
{
searchNode = searchNode.nodeForwardData[level]!
}
}
if searchNode.nodeForwardData[0] != nil && searchNode.nodeForwardData[0]!.nodeData == targetVaule
{
return searchNode.nodeForwardData[0]
}
return nil
}
// Insert a new node.
public func insertNewNode(targetValue:Int) -> Void
{
let newNode = SkipListNode()
newNode.nodeData = targetValue
// generate a random level via random function.
let randomLevel = genarateRandomLevel()
newNode.nodeLevel = randomLevel
// A temp array that contains nodes whose values are just below the current value in all levels.
var tempForwardNode = Array<SkipListNode?>(repeating: nil, count: randomLevel+1)
var foundNode = sentinelNode
// First find the locations to be inserted.
for level in (0...randomLevel).reversed()
{
while foundNode.nodeForwardData[level] != nil && foundNode.nodeForwardData[level]!.nodeData < targetValue
{
foundNode = foundNode.nodeForwardData[level]!
}
tempForwardNode[level] = foundNode
}
for level in 0...randomLevel
{
newNode.nodeForwardData[level] = tempForwardNode[level]?.nodeForwardData[level]
tempForwardNode[level]?.nodeForwardData[level] = newNode
}
if levelCount < randomLevel
{
levelCount = randomLevel+1
}
}
// Delete node with current value.
public func deleteNode(targetValue:Int) -> Int
{
var signal = -1
var tempForwardNode = Array<SkipListNode?>(repeating: nil, count: levelCount)
var tempNode = sentinelNode
// Need to find the value first.
for level in (0..<levelCount).reversed()
{
while tempNode.nodeForwardData[level] != nil && tempNode.nodeForwardData[level]!.nodeData < targetValue
{
tempNode = tempNode.nodeForwardData[level]!
}
tempForwardNode[level] = tempNode
}
// Delete value.
if tempNode.nodeForwardData[0] != nil && tempNode.nodeForwardData[0]?.nodeData == targetValue
{
for level in (0..<levelCount).reversed()
{
if tempForwardNode[level]?.nodeForwardData[level] != nil && tempForwardNode[level]?.nodeForwardData[level]?.nodeData == targetValue
{
tempForwardNode[level]?.nodeForwardData[level] = tempForwardNode[level]?.nodeForwardData[level]?.nodeForwardData[level]
signal = 0
}
}
}
return signal
}
// Print all nodes with values and levels of current list.
public func printCurrentList() -> Void
{
var firstNode = sentinelNode.nodeForwardData[0]
while firstNode != nil
{
print(firstNode!.nodeToString())
firstNode = firstNode?.nodeForwardData[0]
}
}
// Print nodes of qulified level.
public func printListOfSomeLevel(targetLevel:Int) -> Void
{
for level in (0..<MAX_LEVEL_OF_SKIP_LIST)
{
var firstNode = sentinelNode
if targetLevel < 0 || (targetLevel > 0 && targetLevel == level)
{
print("第\(level)级数据:")
while firstNode.nodeForwardData[level] != nil
{
print("\(firstNode.nodeForwardData[level]!.nodeData)")
firstNode = firstNode.nodeForwardData[level]!
}
}
}
}
// Generate a random number and give it to node's level.
internal func genarateRandomLevel() -> Int
{
var level = 0

for _ in 1..<MAX_LEVEL_OF_SKIP_LIST
{
let randomSeed = arc4random()
// Using random number to be the seed of function "arc4random_uniform()".
let randomNum = arc4random_uniform(randomSeed)
if randomNum % 3 == 1
{
level += 1
}
}
return level
}
}
// Test all methods.
func main() -> Void
{
let skipList = SkipList()
for value in 1..<50
{
if value % 3 == 0
{
skipList.insertNewNode(targetValue: value)
}
}
for value in 1..<50
{
if value % 3 == 1
{
skipList.insertNewNode(targetValue: value)
}
}
skipList.printCurrentList()
let findNode = skipList.findNode(targetVaule: 27)
if let tempNode = findNode
{
print("find node of value: \(tempNode.nodeData), level is \(tempNode.nodeLevel)")
}
else
{
print("Node not find.")
}
let sig = skipList.deleteNode(targetValue: 27)
sig == -1 ? print("No such node to delete.") : print("Successfully delete qulified node.")
}

main()
199 changes: 199 additions & 0 deletions swift/24_binarySearchTree/binarySearchTree.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
import UIKit

public class TreeNode:Equatable
{
var value:Int?
var leftSibling:TreeNode?
var rightSibling:TreeNode?

init(treeValue:Int)
{
value = treeValue
}
}
// Make class TreeNode confirm to Equatable protocol for equal judgement.
extension TreeNode
{
public static func == (lhs: TreeNode, rhs: TreeNode) -> Bool
{
if lhs.value == rhs.value && lhs.rightSibling == rhs.rightSibling && lhs.leftSibling == rhs.leftSibling
{
return true
}
else
{
return false
}
}
}

public class BinarySearchTree
{
// rootNode.
var treeRootNode:TreeNode?
public func findNodeInBinarySearchTree(targetValue:Int) -> TreeNode?
{
var tempNode = treeRootNode
while tempNode != nil
{
if let tempValue = tempNode?.value
{
if tempValue < targetValue
{
tempNode = tempNode?.rightSibling
}
else if tempValue > targetValue
{
tempNode = tempNode?.leftSibling
}
else
{
print("Successfully find node, value is \(tempValue).")
return tempNode
}
}
}
print("Value not found.")
return nil
}

public func insertNodeToBinarySearchTree(targetValue:Int) -> Bool
{
if treeRootNode == nil
{
treeRootNode = TreeNode(treeValue: targetValue)
return true
}
var tempNode = treeRootNode
while tempNode != nil
{
if let tempValue = tempNode?.value, tempValue < targetValue
{
if tempNode?.rightSibling == nil
{
tempNode?.rightSibling = TreeNode(treeValue: targetValue)
return true
}
tempNode = tempNode?.rightSibling
}
if let tempValue = tempNode?.value, tempValue > targetValue
{
if tempNode?.leftSibling == nil
{
tempNode?.leftSibling = TreeNode(treeValue: targetValue)
return true
}
tempNode = tempNode?.leftSibling
}
// insert failed because of inserting a same value.
if let tempValue = tempNode?.value, tempValue == targetValue
{
print("The node to be inserted is already existed. Value is \(tempValue). Stopped.")
return false
}
}
print("Tree is not existed. Stopped.")
return false
}

public func deleteNodeInBinarySearchTree(targetValue:Int) -> Bool
{
// find node to be deleted.
var nodeToBeDeleted = treeRootNode
var fatherNode:TreeNode? = nil
while let tempNode = nodeToBeDeleted, tempNode.value != targetValue
{
fatherNode = tempNode
if let tempValue = tempNode.value, tempValue < targetValue
{
nodeToBeDeleted = nodeToBeDeleted?.rightSibling
}
else if let tempValue = tempNode.value, tempValue >= targetValue
{
nodeToBeDeleted = nodeToBeDeleted?.leftSibling
}
}
// node not found in tree.
if nodeToBeDeleted == nil
{
print("The node to be deleted is not found in tree. Stopped.")
return false
}
let printValue = nodeToBeDeleted?.value
// case1: Node to be deleted has two siblings.
if nodeToBeDeleted?.leftSibling != nil && nodeToBeDeleted?.rightSibling != nil
{
var minNode = nodeToBeDeleted?.rightSibling
var fatherNodeOfMinNode = nodeToBeDeleted
while minNode?.leftSibling != nil
{
fatherNodeOfMinNode = minNode
minNode = minNode?.leftSibling
}
nodeToBeDeleted?.value = minNode?.value
nodeToBeDeleted = minNode
fatherNode = fatherNodeOfMinNode
}

// case 2 and 3: Node to be deleted has one sibling or no sibling.
var siblingNode:TreeNode? = nil
if let _ = nodeToBeDeleted?.leftSibling
{
siblingNode = nodeToBeDeleted?.leftSibling
}
if let _ = nodeToBeDeleted?.rightSibling
{
siblingNode = nodeToBeDeleted?.rightSibling
}
// case: Node to be deleted is rootNode.
if fatherNode == nil
{
treeRootNode = siblingNode
}

// if case2: set fatherNode's sibling to node's to be deleted sibling according to whether node to be deleted is its fatherNode's leftSibling or rightSibling.
// if case3: set fatherNode's sibling to nil according to whether node to be deleted is its fatherNode's leftSibling or rightSibling.
fatherNode?.leftSibling == nodeToBeDeleted ? (fatherNode?.leftSibling = siblingNode) : (fatherNode?.rightSibling = siblingNode)
print("Successfully deleted node. Value is \(printValue!).")
return true
}

// inOrder visit all nodes, print the ordered array.
public func inOrderPrint(rootNode:TreeNode?)
{
guard let tempNode = rootNode else
{
return
}
inOrderPrint(rootNode: tempNode.leftSibling)
print("\(tempNode.value!) ", terminator: "")
inOrderPrint(rootNode: tempNode.rightSibling)
}
}
// test function.
func mainTest()
{
let searchTree = BinarySearchTree()
let array = [3,6,1,2,7,9,21,33,11,34,55,22,10,8]
//let array = [3,6,1,9]
// test insert node.
for index in array
{
searchTree.insertNodeToBinarySearchTree(targetValue: index)
}
print("All tree nodes are: ", terminator: "")
searchTree.inOrderPrint(rootNode: searchTree.treeRootNode)
print("")
// test find and delete node.
searchTree.findNodeInBinarySearchTree(targetValue: 21)
searchTree.deleteNodeInBinarySearchTree(targetValue: 9)
searchTree.inOrderPrint(rootNode: searchTree.treeRootNode)
print("")
searchTree.findNodeInBinarySearchTree(targetValue: 25)
searchTree.deleteNodeInBinarySearchTree(targetValue: 5)
// test insert node value that is already existed.
searchTree.insertNodeToBinarySearchTree(targetValue: 34)
searchTree.inOrderPrint(rootNode: searchTree.treeRootNode)
}

mainTest()
Loading