排序
1. 在多个数据元素(Ri)的序列,其中每个元素有相应的关键字(Ki)(也叫元素的属性),通过关键字的固有关系来对对应数据元素进行排序
2. 排序稳定性:元素R1 R2 的关键字K1 K2相同,排序前R1在R2前面,排序后 R1在R2前面,则该排序方法是稳定的。
3. 多关键字排序:排序先用最高优先级的关键字N1进行排序,,当N1关键字相同时使用N2优先级关键字进行排序,如果关键字还是相同依次使用N2,,Nn-1
4. 排序和交换两个重要手段
5. 排序选择要素:时间性能,空间性能,程序复杂度
1.选择排序
思想:在排序到当前序列第 i 和元素时,从后面 n-i 个元素中选出最小元素,作为当前排序序列第 i 个元素。

code:
static void select(T array[], int len) { for(int x = 0; x < len; x++) { int min = x; for(int y = x + 1; y < len; y++) { if(array[min] > array[y]) //升序< 降序> min = y; } if(min != x) swap(array[x],array[min]); //不稳定排序 }
2.插入排序
思想:序列分为有序序列和无需序列。未排序序列选择第 i (1) 位的元素时,插入到前面的有序序列,使用 i 元素的关键字与前 i-1 个元素关键字进行比较,找到位置后插入即可

template <typename T>
static void insert_sort(T array[], int len, bool ascend = false)
{
for(int x = 1; x < len; x++)
{
int z = x;
T temp = array[z];
for(int y = x - 1; (y >= 0) && (ascend ? array[y] > temp: array[y] < temp); y--)
{
array[y + 1] = array[y]; //稳定排序
z = y;
}
if(z != x)
{
array[z] = temp;
}
}
}
3.冒泡排序
思想:序列分为有序序列和无序序列,从整个序列的最后一个元素开始向前依次比较大小,小则比较数前移,大则用被比较的元素前移。

template <typename T>
static void bubble_sort(T array[], int len, bool ascend = false)
{
bool state = ture;
for(int x = 0; x < len && state; x++) //某个元素无法前的元素都是有序的,表明有序
{
state = false;
for(int y = len - 1; y > x; y--)
{
if(ascend ? array[y] > array[y - 1] : array[y] < array[y - 1])
{
swap(array[y],array[y - 1]);
state = ture;
}
}
}
}
4.希尔排序
思想:将n个元素的序列分为d组,每一组使用插入排序。然后再分为d-1组,再分别排序。直到d=1。
如何分组: 将n个元素分为d个子序列:第一组:{R[1],R[1+d],R[1+2d]...R[1+kd]} 第二组:{R[2],R[2+d],R[2+2d]....R[2+kd]} .........第d组:{R[d],R[2d],R[3d]...R[(1+k)d]} 。

template <typename T>
static void shell_sort(T array[], int len, bool ascend = false)
{
int d = len;
do
{
d = d / 3 + 1; //???
for(int x = d ; x < len; x += d)
{
int z = x;
T temp = array[z];
for(int y = x - d; (y >= 0) && (ascend ? array[y] > temp: array[y] < temp); y -= d)
{
array[y + d] = array[y]; //稳定排序
z = y;
}
if(z != x)
{
array[z] = temp;
}
}
}
while(d > 1);
}
5.归并排序
思想:先将一个无序序列划分为两个无序序列,再将两个无序序列接着向下划分,直到每个子序列只包含一个元素此时每个子序列都是有序序列,
再两个两个子序列比较后合并,直到所有子序列合并为原来的序列,此时序列变为有序。
几个有序序列归并就叫几路归并。
稳定但是花费空间

template <typename T>
static void merge_sort(T array[], int len, bool ascned = ture)
{
T* temp_array = new T[len];
merge_sort_core(array, temp_array, 0, len - 1, ture);
delete[] temp_array;
}
template <typename T>
static void merge_sort_core(T array[], T temp_array[], int begin, int end, bool ascned = ture)
{
if(begin == end)
{
return;
}
else
{
// 分割
int mid = (begin + end) / 2;
merge_sort_core(array, temp_array, begin, mid, ascned);
merge_sort_core(array, temp_array, mid + 1, end, ascned);
// 合并
int x = begin, y = mid + 1, z = begin;
while(x <= mid && y <= end)
{
if(array[x] < array[y])
{
temp_array[z++] = array[x++];
}
else
{
temp_array[z++] = array[y++];
}
}
while(x <= mid)
{
temp_array[z++] = array[x++];
}
while(y <= end)
{
temp_array[z++] = array[y++];
}
for(z = begin; z <= end; z++)
{
array[z] = temp_array[z];
}
}
}
6.快速排序
思想: 通过在序列中选择一个基准值对一个无序序列划分,将无序序列大于基准值的放在左边,小于基准值的放在右边。再把左右两个子序列继续寻找基准值继续划分下去。
最后每个序列都只有一个元素,而此时整个序列变成有序的。
不稳定但是花费空间

template <typename T>
static void quick_sort(T array[], int len, bool ascned = ture)
{
quick_sort_core(array, 0, len - 1, ascned);
}
template <typename T>
static void quick_sort_core(T array[], int begin, int end, bool ascned = ture)
{
//确定基准值的位置
int base_pos = 0, base_value = array[begin], begin_slide = begin, end_slide = end;
while(begin_slide < end_slide)
{
while(begin_slide < end_slide && ascned ? base_value < array[end_slide] : base_value > array[end_slide])
{
--end_slide;
}
swap(array[begin_slide], array[end_slide]);
while(begin_slide < end_slide && ascned ? base_value >= array[begin_slide] : base_value <= array[begin_slide])
{
++begin_slide;
}
swap(array[begin_slide], array[end_slide]);
}
array[begin_slide] = base_value;
base_pos = begin_slide;
//继续划分
quick_sort_core(array, begin, (base_pos - 1), ascned);
quick_sort_core(array, base_pos + 1, end, ascned);
}

浙公网安备 33010602011771号