插入排序
特性总结:
1.元素集合越接近有序,时间效率越高
2.时间复杂度:O(N^2)
3.空间复杂度:O(1)
排序思想:插入排序就像是打扑克,来一张牌就要把牌插入到合适的位置
void Insertsort(int* a, int n)
{
for (int i = 1; i < n; i++)
{
int end = i - 1;
int tmp = a[i];
while (end >= 0)
{
if (tmp >=a[end])
{
break;
}
else
{
a[end + 1] = a[end];
end--;
}
}
a[end + 1] = tmp;
}
}
希尔排序
希尔排序法我觉得是增强版的直接插入排序
希尔排序法的基本思想是:把一个数组分成gap个组,每个数组进行直接插入排序,之后缩小gap,再排序,直到gap=1,最后在排序,就得到了排序好的数组了
希尔排序的特性总结:
1. 希尔排序是对直接插入排序的优化。
2. 当gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,数组已经接近有序的了,这样就会很快。这样整体而言,可以达到优化的效果。我们实现后可以进行性能测试的对比。
3. 希尔排序的时间复杂度不好计算,因为gap的取值方法很多,导致很难去计算,因此在好些树中给出的希尔排序的时间复杂度都不固定
void xiersort(int* a, int n)
{
int gap = n;
while (gap > 1)
{
gap = gap / 2;
for (int i = 0; i < n - gap; i++)
{
int end = i;
int tmp = a[i + gap];
while (end >=0)
{
if (tmp > a[end])
{
break;
}
else
{
a[end + gap] = a[end];
end -= gap;
}
}
a[end + gap] = tmp;
}
}
}
选择排序
排序思想:在数组中选出最大和最小的两个数,然后把这两个数各放在左右两边,在剩下的数里选出最小最大的数各自放在左右两侧,如此往复
void SelectSort(int* a, int n)
{
int left = 0;
int right = n - 1;
while (left < right)
{
int min = left;
int max = left;
for(int i = left+1; i <=right; i++)
{
if (a[min] > a[i])
min = i;
if (a[max] < a[i])
max = i;
}
Swap(&a[right], &a[max]);
if (right == min)
{
min = max;
}
Swap(&a[left], &a[min]);
left++;
right--;
}
}
堆排序
堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。它是通过堆来进行选择数据。需要注意的是排升序要建大堆,排降序建小堆
void AdjustDown(HPDataType* a, int n, HPDataType parent)
{
HPDataType child=parent*2+1;
while (child < n)
{
if (child + 1 < n && a[child] > a[child + 1])
{
++child;
}
if (a[child] > a[parent])
{
Swap(&a[child], &a[parent]);
parent = child;
child = parent * 2 + 1;
}
else
{
break;
}
}
}
void HeapSort(HPDataType* a, int n)
{
//建堆的过程
int num = n-1;
for (int i = (n - 1-1) / 2; i >= 0; i--)
{
AdjustDown(a, n, i);
}
//排序的过程
while (num > 0)
{
Swap(&a[0],&a[num]);
AdjustDown(a, num,0);
num--;
}
}
冒泡排序
基本思想:所谓交换,就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置,交换排序的特点是:将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动。
快速排序
基本思想:任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止
以挖坑法为例: