一、冒泡排序
前面为无序区,后面为有序区,每次在无序区中两两比较选出最大值,放到有序区的前面。
void BubbleSort(vector<int> &vec) {
if (vec.empty())
return;
for (int i = 0; i < vec.size() - 1; ++i)
for (int j = 0; j < vec.size() - i - 1; ++j)
if (vec[j] > vec[j + 1])
swap(vec[j], vec[j + 1]);
}
二、插入排序
前面为有序区,后面为无序区,每次将无序区第一个元素插入到有序区的合适位置。
void InsertSort(vector<int> &vec) {
if (vec.empty())
return;
for (int i = 1; i < vec.size(); ++i)
if (vec[i] < vec[i - 1])
{
int temp = vec[i];
int j = i - 1;
for (; j >= 0 && temp < vec[j]; --j)
vec[j + 1] = vec[j];
vec[j + 1] = temp;
}
}
三、选择排序,不稳定
前面为有序区,后面为无序区,每次在无序区选出最小的,加在有序区后面。
void SelectionSort(vector<int> &vec) {
if (vec.empty())
return;
for (int i = 0; i < vec.size(); ++i) {
int minIndex = i;
for (int j = i + 1; j < vec.size(); ++j)
if (vec[j] < vec[minIndex])
minIndex = j;
if(minIndex!=i)
//此处互换正是该算法不稳定的原因,vec[i]可能会换到后面相等元素之后
swap(vec[minIndex], vec[i]);
}
}
四、希尔排序
不稳定:不同组的相等元素位置随机
void ShellSort(vector<int> &vec) {
if (vec.empty())
return;
for (int gap = vec.size() >> 1; gap > 0; gap >>= 1)
//插入排序
for (int i = gap; i < vec.size(); ++i)
if (vec[i] < vec[i - gap])
{
int temp = vec[i];
int j = i - gap;
for (;j >= 0 && temp < vec[j]; j -= gap)
vec[j + gap] = vec[j];
vec[j + gap] = temp;
}
}
五、归并排序
void MergeArray(vector<int> &vec, int first, int middle, int last) {
int leftIndex = first, rightIndex = middle + 1;
int leftEnd = middle, rightEnd = last;
vector<int> temp;
temp.reserve(last-first+1);
while (leftIndex <= leftEnd && rightIndex <= rightEnd) {
if (vec[leftIndex] < vec[rightIndex])
temp.push_back(vec[leftIndex++]);
else
temp.push_back(vec[rightIndex++]);
}
while (leftIndex <= leftEnd)
temp.push_back(vec[leftIndex++]);
while (rightIndex <= rightEnd)
temp.push_back(vec[rightIndex++]);
for (int i = 0; i < tempIndex; ++i)
vec[first + i] = temp[i];
}
void mergeSort(vector<int> &vec, int first, int last) {
if (first < last) {
int middle = (first + last) / 2;
mergeSort(vec, first, middle);
mergeSort(vec, middle + 1, last);
MergeArray(vec, first, middle, last);
}
}
void MergeSort(vector<int> &vec) {
if (vec.empty())
return;
mergeSort(vec, 0, vec.size() - 1);
}
六、快速排序
不稳定:5 3 3 4 3 8 9 10 11,5与3互换,破坏稳定性
void QuickSort(vector<int> &vec, int left, int right) {
if (left < right) {
int leftIndex = left, rightIndex = right;
int pivot = vec[left];
while (leftIndex < rightIndex) {
while (leftIndex < rightIndex && vec[rightIndex] >= temp)
--rightIndex;
if (leftIndex < rightIndex)
vec[leftIndex++] = vec[rightIndex];
while (leftIndex < rightIndex && vec[leftIndex] < temp)
++leftIndex;
if (leftIndex < rightIndex)
vec[rightIndex--]=vec[leftIndex];
}
vec[leftIndex] = pivot;
QuickSort(vec, left, leftIndex-1);
QuickSort(vec, leftIndex + 1, right);
}
}
void QuickSort(vector<int> &vec) {
if (vec.empty())
return;
QuickSort(vec, 0, vec.size() - 1);
}
七、堆排序
不稳定:有可能第n/2个父节点交换把后面一个元素交换过去了,而第n/2-1个父节点把后面一个相同的元素没有交换,那么这2个相同的元素之间的稳定性就被破坏了
//root为起始位置,tail为结束位置(不含)
void AdjustHeap(vector<int> &vec, int root, int tail) {
int rootVal= vec[root];
int child = 2 * root+ 1;//root的左孩子(如果有的话)
while (child < tail) {
if (child + 1 < tail && vec[child +1] > vec[child])//root的右孩子
++child ;
if (rootVal>= vec[child])
break;
vec[root] = vec[child];
root = child ;
child = 2 * root + 1;
}
vec[root] = rootVal;
}
void HeapSort(vector<int> &vec) {
if (vec.empty())
return;
//堆化数组,从最后一个非叶子节点建堆
for (int i = vec.size() / 2 - 1; i >= 0; --i)
AdjustHeap(vec, i, vec.size());
//将最大元素与尾部互换,然后将0~i-1看作是堆,再调整
for (int i = vec.size() - 1; i >= 0; --i) {
swap(vec[0], vec[i]);
AdjustHeap(vec, 0, i);
}
}