第一种就是selection sort排序,如果是升序的话就是从剩下的元素中选择最小的元素放到元素的最前面。
代码实现,时间复杂度O(n*n)
// 1. Find the smallest element in the range between left hand and the
// end of the vector, and point at that element with your right hand (rh).
// 2. Move that element into its correct position by exchanging the elements
// indicated by your left and right hands.
void sort(Vector<int> & vec) {
int n = vec.size();
for (int lh = 0; lh < n; lh++) {
int rh = lh;
for (int i = lh + 1; i < n; i++) {
if (vec[i] < vec[rh]) rh = i;
}
int tmp = vec[lh];
vec[lh] = vec[rh];
vec[rh] = tmp;
}
}
第二种方法叫做分治法,先分后合,就是先把元素分成有序的两个,然后依次合入两个Vector.
代码实现,时间复杂度O(n * log(n))
// 1. Divide the vector into two halves.
// 2. Sort each of these smaller vectors recursively.
// 3. Merge the two vectors back into the original one.
void sort(Vector<int> & vec) {
int n = vec.size();
if (n <= 1) return;
Vector<int> v1;
Vector<int> v2;
for (int i = 0; i < n; i++) {
if (i < n / 2) {
v1.add(vec[i]);
} else {
v2.add(vec[i]);
}
}
sort(v1);
sort(v2);
vec.clear();
merge(vec, v1, v2);
}
// Because the input vectors are sorted, the implemntation can always
// select the first unused element in one fo the input vector to fill
// the next position.
void merge(Vector<int> & vec, Vector<int> & v1, Vector<int> & v2) {
int n1 = v1.size();
int n2 = v2.size();
int p1 = 0;
int p2 = 0;
while (p1 < n1 && p2 < n2) {
if (v1[p1] < v2[p2]) {
vec.add(v1[p1++]);
} else {
vec.add(v2[p2++]);
}
}
while (p1 < n1) vec.add(v1[p1++]);
while (p2 < n2) vec.add(v2[p2++]);
}
第三种是快速排序,是常规选用的方法。
Quick Sort Algorithm
实现有点像分治法,就是选择一个值,比这个值小的放在左边,比这个值大的放在右边。这样不断地分割,进行排序。
感觉理解这些东西,首先需要理解迭代,学习迭代是学习这些算法的前提。
void sort(Vector<int> & vec) {
quicksort(vec, 0, vec.size() - 1);
}
// The Quicksort algorithm begins by "partitioning" the vector so
// that all elements smaller than a designated pivot element appear
// to the left of a boundary and all equal or larger values appear
// to the right.
void quicksort(Vector<int> & vec, int start, int finish) {
if (start >= finish) return;
int boundary = partition(vec, start, finish);
quicksort(vec, start, boundary-1);
quicksort(vec, boundary+1, finish);
}
// The distinction between small and large is made by comparing
// each element to the pivot value, which is initially taken
// from vec[start].
int partition(Vector<int> & vec, int start, int finish) {
int pivot = vec[start];
int lh = start + 1;
int rh = finish;
while (true) {
while (lh < rh && vec[rh] >= pivot) rh--;
while (lh < rh && vec[lh] < pivot) lh++;
if (lh == rh) break;
int tmp = vec[lh];
vec[lh] = vec[rh];
vec[rh] = tmp;
}
if (vec[lh] >= pivot) return start;
vec[start] = vec[lh];
vec[lh] = pivot;
return lh;
}