feat: add Swift codes for chapter_searching articles (#309)

* feat: add Swift codes for linear_search article

* feat: add Swift codes for binary_search article

* feat: add Swift codes for hashing_search article
This commit is contained in:
nuomi1 2023-01-30 15:43:29 +08:00 committed by GitHub
parent 15c798046a
commit 1665fe176c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 261 additions and 7 deletions

View file

@ -28,6 +28,9 @@ let package = Package(
.executable(name: "binary_search_tree", targets: ["binary_search_tree"]), .executable(name: "binary_search_tree", targets: ["binary_search_tree"]),
.executable(name: "avl_tree", targets: ["avl_tree"]), .executable(name: "avl_tree", targets: ["avl_tree"]),
.executable(name: "my_heap", targets: ["my_heap"]), .executable(name: "my_heap", targets: ["my_heap"]),
.executable(name: "linear_search", targets: ["linear_search"]),
.executable(name: "binary_search", targets: ["binary_search"]),
.executable(name: "hashing_search", targets: ["hashing_search"]),
], ],
targets: [ targets: [
.target(name: "utils", path: "utils"), .target(name: "utils", path: "utils"),
@ -54,5 +57,8 @@ let package = Package(
.executableTarget(name: "binary_search_tree", dependencies: ["utils"], path: "chapter_tree", sources: ["binary_search_tree.swift"]), .executableTarget(name: "binary_search_tree", dependencies: ["utils"], path: "chapter_tree", sources: ["binary_search_tree.swift"]),
.executableTarget(name: "avl_tree", dependencies: ["utils"], path: "chapter_tree", sources: ["avl_tree.swift"]), .executableTarget(name: "avl_tree", dependencies: ["utils"], path: "chapter_tree", sources: ["avl_tree.swift"]),
.executableTarget(name: "my_heap", dependencies: ["utils"], path: "chapter_heap", sources: ["my_heap.swift"]), .executableTarget(name: "my_heap", dependencies: ["utils"], path: "chapter_heap", sources: ["my_heap.swift"]),
.executableTarget(name: "linear_search", dependencies: ["utils"], path: "chapter_searching", sources: ["linear_search.swift"]),
.executableTarget(name: "binary_search", path: "chapter_searching", sources: ["binary_search.swift"]),
.executableTarget(name: "hashing_search", dependencies: ["utils"], path: "chapter_searching", sources: ["hashing_search.swift"]),
] ]
) )

View file

@ -0,0 +1,62 @@
/**
* File: binary_search.swift
* Created Time: 2023-01-28
* Author: nuomi1 (nuomi1@qq.com)
*/
/* */
func binarySearch(nums: [Int], target: Int) -> Int {
// [0, n-1] i, j
var i = 0
var j = nums.count - 1
// i > j
while i <= j {
let m = (i + j) / 2 // m
if nums[m] < target { // target [m+1, j]
i = m + 1
} else if nums[m] > target { // target [i, m-1]
j = m - 1
} else { //
return m
}
}
// -1
return -1
}
/* */
func binarySearch1(nums: [Int], target: Int) -> Int {
// [0, n) i, j +1
var i = 0
var j = nums.count
// i = j
while i < j {
let m = (i + j) / 2 // m
if nums[m] < target { // target [m+1, j)
i = m + 1
} else if nums[m] > target { // target [i, m)
j = m
} else { //
return m
}
}
// -1
return -1
}
@main
enum BinarySearch {
/* Driver Code */
static func main() {
let target = 6
let nums = [1, 3, 6, 8, 12, 15, 23, 67, 70, 92]
/* */
var index = binarySearch(nums: nums, target: target)
print("目标元素 6 的索引 = \(index)")
/* */
index = binarySearch1(nums: nums, target: target)
print("目标元素 6 的索引 = \(index)")
}
}

View file

@ -0,0 +1,50 @@
/**
* File: hashing_search.swift
* Created Time: 2023-01-28
* Author: nuomi1 (nuomi1@qq.com)
*/
import utils
/* */
func hashingSearch(map: [Int: Int], target: Int) -> Int {
// key: value:
// key -1
return map[target, default: -1]
}
/* */
func hashingSearch1(map: [Int: ListNode], target: Int) -> ListNode? {
// key: value:
// key null
return map[target]
}
@main
enum HashingSearch {
/* Driver Code */
static func main() {
let target = 3
/* */
let nums = [1, 5, 3, 2, 4, 7, 5, 9, 10, 8]
//
var map: [Int: Int] = [:]
for i in nums.indices {
map[nums[i]] = i // key: value:
}
let index = hashingSearch(map: map, target: target)
print("目标元素 3 的索引 = \(index)")
/* */
var head = ListNode.arrToLinkedList(arr: nums)
//
var map1: [Int: ListNode] = [:]
while head != nil {
map1[head!.val] = head! // key: value:
head = head?.next
}
let node = hashingSearch1(map: map1, target: target)
print("目标结点值 3 的对应结点对象为 \(node!)")
}
}

View file

@ -0,0 +1,53 @@
/**
* File: linear_search.swift
* Created Time: 2023-01-28
* Author: nuomi1 (nuomi1@qq.com)
*/
import utils
/* 线 */
func linearSearch(nums: [Int], target: Int) -> Int {
//
for i in nums.indices {
//
if nums[i] == target {
return i
}
}
// -1
return -1
}
/* 线 */
func linearSearch(head: ListNode?, target: Int) -> ListNode? {
var head = head
//
while head != nil {
//
if head?.val == target {
return head
}
head = head?.next
}
// null
return nil
}
@main
enum LinearSearch {
/* Driver Code */
static func main() {
let target = 3
/* 线 */
let nums = [1, 5, 3, 2, 4, 7, 5, 9, 10, 8]
let index = linearSearch(nums: nums, target: target)
print("目标元素 3 的索引 = \(index)")
/* 线 */
let head = ListNode.arrToLinkedList(arr: nums)
let node = linearSearch(head: head, target: target)
print("目标结点值 3 的对应结点对象为 \(node!)")
}
}

View file

@ -11,4 +11,14 @@ public class ListNode {
public init(x: Int) { public init(x: Int) {
val = x val = x
} }
public static func arrToLinkedList(arr: [Int]) -> ListNode? {
let dum = ListNode(x: 0)
var head: ListNode? = dum
for val in arr {
head?.next = ListNode(x: val)
head = head?.next
}
return dum.next
}
} }

View file

@ -213,7 +213,25 @@ $$
=== "Swift" === "Swift"
```swift title="binary_search.swift" ```swift title="binary_search.swift"
/* 二分查找(双闭区间) */
func binarySearch(nums: [Int], target: Int) -> Int {
// 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素
var i = 0
var j = nums.count - 1
// 循环,当搜索区间为空时跳出(当 i > j 时为空)
while i <= j {
let m = (i + j) / 2 // 计算中点索引 m
if nums[m] < target { // 此情况说明 target 在区间 [m+1, j]
i = m + 1
} else if nums[m] > target { // 此情况说明 target 在区间 [i, m-1] 中
j = m - 1
} else { // 找到目标元素,返回其索引
return m
}
}
// 未找到目标元素,返回 -1
return -1
}
``` ```
### “左闭右开”实现 ### “左闭右开”实现
@ -383,7 +401,25 @@ $$
=== "Swift" === "Swift"
```swift title="binary_search.swift" ```swift title="binary_search.swift"
/* 二分查找(左闭右开) */
func binarySearch1(nums: [Int], target: Int) -> Int {
// 初始化左闭右开 [0, n) ,即 i, j 分别指向数组首元素、尾元素+1
var i = 0
var j = nums.count
// 循环,当搜索区间为空时跳出(当 i = j 时为空)
while i < j {
let m = (i + j) / 2 // 计算中点索引 m
if nums[m] < target { // 此情况说明 target 在区间 [m+1, j)
i = m + 1
} else if nums[m] > target { // 此情况说明 target 在区间 [i, m) 中
j = m
} else { // 找到目标元素,返回其索引
return m
}
}
// 未找到目标元素,返回 -1
return -1
}
``` ```
### 两种表示对比 ### 两种表示对比
@ -475,7 +511,10 @@ $$
=== "Swift" === "Swift"
```swift title="" ```swift title=""
// (i + j) 有可能超出 int 的取值范围
let m = (i + j) / 2
// 更换为此写法则不会越界
let m = i + (j - 1) / 2
``` ```
## 复杂度分析 ## 复杂度分析

View file

@ -108,7 +108,12 @@ comments: true
=== "Swift" === "Swift"
```swift title="hashing_search.swift" ```swift title="hashing_search.swift"
/* 哈希查找(数组) */
func hashingSearch(map: [Int: Int], target: Int) -> Int {
// 哈希表的 key: 目标元素value: 索引
// 若哈希表中无此 key ,返回 -1
return map[target, default: -1]
}
``` ```
再比如,如果我们想要给定一个目标结点值 `target` ,获取对应的链表结点对象,那么也可以使用哈希查找实现。 再比如,如果我们想要给定一个目标结点值 `target` ,获取对应的链表结点对象,那么也可以使用哈希查找实现。
@ -208,7 +213,12 @@ comments: true
=== "Swift" === "Swift"
```swift title="hashing_search.swift" ```swift title="hashing_search.swift"
/* 哈希查找(链表) */
func hashingSearch1(map: [Int: ListNode], target: Int) -> ListNode? {
// 哈希表的 key: 目标结点值value: 结点对象
// 若哈希表中无此 key ,返回 null
return map[target]
}
``` ```
## 复杂度分析 ## 复杂度分析

View file

@ -136,7 +136,18 @@ comments: true
=== "Swift" === "Swift"
```swift title="linear_search.swift" ```swift title="linear_search.swift"
/* 线性查找(数组) */
func linearSearch(nums: [Int], target: Int) -> Int {
// 遍历数组
for i in nums.indices {
// 找到目标元素,返回其索引
if nums[i] == target {
return i
}
}
// 未找到目标元素,返回 -1
return -1
}
``` ```
再比如,我们想要在给定一个目标结点值 `target` ,返回此结点对象,也可以在链表中进行线性查找。 再比如,我们想要在给定一个目标结点值 `target` ,返回此结点对象,也可以在链表中进行线性查找。
@ -270,7 +281,20 @@ comments: true
=== "Swift" === "Swift"
```swift title="linear_search.swift" ```swift title="linear_search.swift"
/* 线性查找(链表) */
func linearSearch(head: ListNode?, target: Int) -> ListNode? {
var head = head
// 遍历链表
while head != nil {
// 找到目标结点,返回之
if head?.val == target {
return head
}
head = head?.next
}
// 未找到目标结点,返回 null
return nil
}
``` ```
## 复杂度分析 ## 复杂度分析