1.快速排序
1>找到一个基准
2>小于它的在它前面,大于等于在它后面。找它在数组排序中的位置
3>分隔数组递归
template<typename _Ty> inline void quick(_Ty* arr, size_t left, size_t right) { size_t i = left, j = right, p = (left + right) / 2; _Ty temp = arr[p]; while (i < j) { while (i < p && a[i] < temp) i++; if (i < p) arr[p] = arr[i], p = i; while (j > p && a[j] >= a[p]) j--; if (j > p) arr[p] = arr[j], p = j; } arr[p] = temp; if (left - p > 1) quick(arr, left, p - 1); if (p - right > 1) quick(arr, p + 1, right); }
- 希尔排序
1>取一个间隔
2>比较相邻间隔的元素进行排序
3>不断减少间隔
template<typename _Ty>
inline void shell(_Ty* arr, size_t len)
{
for (size_t increment = len / 2; increment > 0; increment /= 2)
for (size_t i = increment; i < len; ++i)
for (size_t j = i; j >= increment; j -= increment)
if (arr[j] < arr[j - increment])
std::swap(arr[j], arr[j - increment]);
else
break;
}
希尔排序的增量
1.
Hibbard 算法 2.
Knuth 算法 3.
Sedgewick 算法 4.Gonnet 算法
http://baike.baidu.com/link?url=bZibeou1Kd6eb5BCTMIbry1pzQH2epo1s8FS7kQDrUzAQFii2wbNjoFssYzoMVS1M0dxLm-y7foXV7Hmwm8k9q
1>建立一个堆序性质父节点大于子节点
2>删除第一个节点,对[0, length - i]范围重新建堆
#define LEFT_CHILD(child) ((child) * 2 + 1)
template<typename _Ty>
void down(_Ty arr[], size_t index, size_t len)
{
size_t child;
_Ty temp = arr[index];
for (; LEFT_CHILD(index) < len; index = child)
{
child = LEFT_CHILD(index);
if (child < len - 1 && arr[child + 1] > arr[child])
child++;
if (temp < arr[child])
std::swap(arr[index], arr[child]);
else
return;
}
}
template<typename _Ty>
void heapsort(_Ty arr[], size_t len)
{
for (int i = len / 2 - 1; i >= 0; --i)
{
down(arr, i, len);
}
for (size_t i = len - 1; i > 0; --i)
{
std::swap(arr[0], arr[i]);
down(arr, 0, i);
}
}
4.归并排序
4.1 递归法
1.申请一个相同大小大空间
2.对表进行分割,只有2个或一个
3.合并2个已排序的表
template<typename _Ty>
void mergersort(_Ty arr[], _Ty temp[], size_t lefbeg, size_t rigbeg, size_t rigend)
{
size_t lefend = rigbeg - 1;
size_t pos = lefbeg;
size_t len = rigend + 1;
while (lefbeg <= lefend && rigbeg <= rigend)
temp[pos++] = (arr[lefbeg] <= arr[rigbeg] ? arr[lefbeg++]:arr[rigbeg++]);
while (lefbeg <= lefend)
temp[pos++] = arr[lefbeg++];
while (rigbeg <= rigend)
temp[pos++] = arr[rigbeg++];
for (pos = 0; pos <= len; ++pos, --rigend)
arr[rigend] = temp[rigend];
}
template<typename _Ty>
void merge(_Ty* arr, size_t len)
{
_Ty* temp = new _Ty[len];
msort(arr, temp, 0, len - 1);
delete[] temp;
}
template<typename _Ty>
void msort(_Ty* arr, _Ty* temp, size_t lef, size_t rig)
{
size_t center = (lef + rig) / 2;
if (lef < rig)
{
msort(arr, temp, lef, center);
msort(arr, temp, center + 1, rig);
mergersort(arr, temp, lef, center + 1, rig);
}
}
4.2 迭代法
1.申请一个相同大小大空间
2.比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
3.重复步骤3直到某一指针到达序列尾
4.将另一序列剩下的所有元素直接复制到合并序列尾
template<typename _Ty>
inline void merge(_Ty* arr, int len)
{
_Ty *temp = new _Ty[len];
for (int seg = 1; seg < len; seg+=seg)
{
for (int start = 0; start < len; start += 2 * seg)
{
int mid = Min(start + seg, len);
int bot = Min(start + seg + seg, len);
//数组中的相邻元素两两配对
int start1 = start,
end1 = mid - 1,
start2 = mid,
end2 = bot - 1,
pos = start1,
num = end2 - start1;
while (start1 <= end1 && start2 <= end2)
temp[pos++] = (arr[start1] < arr[start2] ?
arr[start1++] : arr[start2++]);
while (start1 <= end1)
temp[pos++] = arr[start1++];
while (start2 <= end2)
temp[pos++] = arr[start2++];
for (pos = 0; pos <= num; ++pos, --end2)
arr[end2] = temp[end2];
}
}
delete[]temp;
}
5.插入排序
1.第一元素为有序区,其他为无序区
2.把无序区元素插入有序
template<typename _Ty>
inline void insert(_Ty* arr, int len)
{
for (int i = 1; i < len; ++i)
{
_Ty temp = arr[i];
int j = i;
while (j > 0 && temp < arr[j - 1])
arr[j] = arr[j - 1], j--;
arr[j] = temp;
}
}
稳定排序和不稳定排序
假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,ri=rj,且ri在rj之前,而在排序后的序列中,ri仍在rj之前,则称这种排序算法是稳定的;否则称为不稳定的。
http://www.cnblogs.com/codingmylife/archive/2012/10/21/2732980.html