快速排序:选中一个元素,将比该元素小的元素放在其左侧,比该元素大的放在其右侧,然后将该元素放在正确的位置。然后对左侧和右侧的所有元素依次进行以上操作。
- 以首元素作为比较元素C
- 初始化i为0,j为len-1
- 找到右边第一个比C小的数字A[j],放在i位置
- 找到左边第一个比C大的数字A[i],放在j位置
- 重复3、4,直到i,j重合
template <class T>
void QuickSort(T* src, int firstPosition, int lastPosition)
{
if (firstPosition >= lastPosition) return;
int compareElement = src[firstPosition];
int iPosition = firstPosition;
int jPosition = lastPosition;
while (true)
{
while (jPosition > iPosition && src[jPosition] >= compareElement) jPosition--;
if (jPosition > iPosition) src[iPosition] = src[jPosition];
while (jPosition > iPosition && src[iPosition] <= compareElement) iPosition++;
if (jPosition > iPosition) src[jPosition] = src[iPosition];
if (jPosition <= iPosition) break;
}
src[iPosition] = compareElement;
QuickSort(src, firstPosition, iPosition - 1);
QuickSort(src, iPosition + 1, lastPosition);
}
归并排序:假定数组左右两侧的数据都已经有序,则只要把这两组数据从头开始扫描排序即可
- 对左边部分进行归并排序
- 对右边部分进行归并排序
- 合并左右两部分
template <class T>
void Merge(T* src, int leftStart, int leftEnd, int rightEnd)
{
T* cachedValue = new T[rightEnd - leftStart + 1];
int leftPosition = leftStart;
int rightPosition = leftEnd + 1;
int cachedPosition = 0;
while (leftPosition <= leftEnd && rightPosition <= rightEnd)
{
if (src[leftPosition] <= src[rightPosition])
cachedValue[cachedPosition++] = src[leftPosition++];
else
cachedValue[cachedPosition++] = src[rightPosition++];
}
while (leftPosition <= leftEnd)
cachedValue[cachedPosition++] = src[leftPosition++];
while (rightPosition <= rightEnd)
cachedValue[cachedPosition++] = src[rightPosition++];
cachedPosition = 0;
leftPosition = leftStart;
while (leftPosition <= rightEnd)
src[leftPosition++] = cachedValue[cachedPosition++];
delete []cachedValue;
}
template <class T>
void MergeSort(T*src, int leftStart, int rightEnd)
{
if (leftStart >= rightEnd) return;
int middlePosition = (rightEnd + leftStart) / 2;
MergeSort(src, leftStart, middlePosition);
MergeSort(src, middlePosition + 1, rightEnd);
Merge(src, leftStart, middlePosition, rightEnd);
}
堆排序:假定存在一个最大堆,则每次从堆顶上取出的元素都是堆里面的最大元素
- 构造最大堆
- 取堆顶的元素
- 重新构造最大堆
template <class T>
void MakeHeap(T* src, int rootPosition, int lastPosition)
{
int currentPosition = rootPosition;
int childPosition = 0;
while (currentPosition * 2 + 1 <= lastPosition)
{
childPosition = currentPosition * 2 + 1;
if (childPosition + 1 <= lastPosition && src[childPosition] < src[childPosition + 1])
childPosition++;
if (src[childPosition] > src[currentPosition])
{
T tmp = src[childPosition];
src[childPosition] = src[currentPosition];
src[currentPosition] = tmp;
currentPosition = childPosition;
}
else break;
}
}
template <class T>
void HeapSort(T* src, int start, int end)
{
int position = 0;
for (position = (end + 1) / 2 - 1; position >= 0; --position)
MakeHeap(src, position, end);
for (position = end; position > 0; --position)
{
T tmp = src[0];
src[0] = src[position];
src[position] = tmp;
MakeHeap(src, 0, position - 1);
}
}
插入排序:将无序的每一个元素依次插入到有序的序列中
选择排序:每次选择一个元素并将其放入序列
冒泡排序:每次比较相邻的两个元素
Shell排序:通过减小间隔依次进行插入排序
SO:
稳定排序:
插入排序
选择排序
冒泡排序
归并排序
不稳定排序:
Shell排序:在多次插入排序的过程中可能出现乱序的情况
快速排序:在移动时,如果一个元素移动,会引起两个元素都移动,从而乱序
堆排序:在生成堆时,有可能乱序