
Swift language with excellent functional programming ability, like when the interview the interviewer asked us quick sort, then use Swift how to implement a quicksort it? First, extend the Array class:
extension Array {
var decompose: (head: T, tail: [T])? {
? Return (count> 0) (self [0], Array (self [1 ..
}
}
Property decompose role is to return the first element in the array and the remaining elements, note that this property is selection, when the count reaches zero return nil, count the Array properties. Extended reason is that resolution can achieve a lot of operations, once and for all.
Then quick sort method:
func qsortDemo (input: [Int]) > [Int] {
if let (pivot, rest) = input.decompose {
let lesser = rest.filter {$ 0
let greater = rest.filter {$ 0> = pivot}
return qsortDemo (lesser) + [pivot] + qsortDemo (greater)
} Else {
return []
}
}
Swift can be found using quick sort code is very simple. First call decompose attributes to be sorted sequence using a tuple to hold the first element of the array and the first array, as is still recursive way, the boundaries do so using the optional binding judgment. In an alternative method of binding internal use of the filter element to separate, eliminating the complexity of the process is moving element is smaller than the resulting array pivot of lesser, greater array is greater than the pivot, upon their return and use the splicing arrays array split recursive structure is very simple, bringing a quick sort of process is over.
Let's do a performance test in storyboard:
var a: [Int] = [1,2,4,6,2,4,3,7,8]
qsortDemo (a)
Efficiency in a fast array row are as follows
You can see the implementation of an optional binding of return equal to nine times a number of elements, and expected, because each element is to determine its own position in this return, so the number of executions should be n . So why else statements executed n + 1 times did he? Want to know each element in a recursion what happened, you can make only one element in a recursive analog happened
Open the recording is performed decompose
You can see the decompose is performed three times, the first [1] to access, returned ([1], []), this time in an alternative binding, lesser and greater are [], in return the recursive when lesser and greater access will continue to decompose this time returned two nil, so the corresponding optional binding judgment false else runs directly in the return [], the end of the whole process.
else condition returns [], [] is added to the array will not work, it can be used as the return value of the boundary.
The elements in the expansion to a two.
Recording is performed to decompose the
Well understood, the first split to give [1] and [2], pivot to [1], lesser is [], which is greater [2]. When return lesser access decompose to give nil, optional binding for execution else false statements, then it became a greater array element, the step above. So in this fast recursive process each row, only the last element of a lesser and greater will be the same time as [], other elements are only one side of [], which explains why the number of executions of return n + 1 will appear.
Look at the two filter, this resolution method requires extra space to hold lesser and greater, you can see the opening track of the lesser and greater traces the trajectory is the opposite, it is well understood. Also filter is a system API, we do not know the internal implementation method, but you can see in the judgment [2] of the elements when they were called three times, should be internal mechanisms, although the number seems to perform much changed, but fast operation eliminates the traditional sort of element exchange position, the level of efficiency is not easy to say. In short write so much on a final effect: Sort.
After reading this code I made the following thought: Since it is sorted, then there must be able to use the system sorted method (previous sort method), results so far? Let's use an example to try first, you only need one line of code:
let b = a.sorted {$ 0 <$ 1}
1
Yes, the entire method is relatively only 15 times! Efficiency is very amazing, sorted implementation by Apple engineers in the underlying implementation, I think they must use a good way to improve efficiency. Do not believe? Consider the following example, we all know that quick sort of worst case occurs when the recursive uneven division of the array on the right, such as a modification to the array:
var a: [Int] = [1,1,1,1,1,1,1,1,1]
The overall size of the array does not change, operating efficiency
You can see the main algorithm and timeconsuming part of the lesser perform greater at this time from the previous 35 becomes 45 times, then sorted the efficiency of the method and how?
You read right! For the most troublesome row fast sequential array of repetitions sorted only n times! Description in the face of an array of this type when sorted by judging method, the direct output. Of course, the closure statement must be appropriate, "Do not use the equal sign!", Such as rewriting a:
var a: [Int] = [1,1,2,2,3,1,1,1,1]
Without equal number of
If you write the equal sign
Under OMG! The same effect as the premise of efficiency a lot worse.
Another extreme case, a full array of reverse
Of course, fast discharge time and the same elements as
If you think the order of magnitude too small is not fun, then to a large array of:
Now change a 500 random positive integers less than 100:
var a: [UInt32] = []
for _ in 0 .. <500 {
a.append (arc4random ()% 100)
}
While comparing the two sort, here are quick row
Below are sorted efficiency
We can try, the bigger the difference, the more obvious the efficiency of the array, sorted with the rate of visible spike fast row! 


