简单选择排序
空间复杂度:
O
(
1
)
O(1)
O(1)
时间复杂度(元素间的比较与序列的初始位置无关):
O
(
n
2
)
O(n^2)
O(n2)
稳定性:不稳定
适用顺序排序和链式排序
// 选择排序
typedef int ElemType;
void SelectSort(ElemType *A, int len)
{
for(int i=1; i<=n-1; i++)
{
int min = i;
for(int j=i+1; j<=n; j++)
{
if(A[min] > A[j])
{
min = j;
}
}
if(min != i)
{
swap(A[min], A[i]);
}
}
}
void swap(int &a, int &b)
{
int tmp = a;a = b;b = tmp;
}
堆排序
建立大根堆的算法
// 构造初始堆(大根堆)
typedef int ElemType;
void BuildMaxHeap(ElemType *A, int len)
{
for(int i=len/2; i>=1; i--)
{ // 对所有非叶结点进行调整
HeadAdjust(A, i, len);
}
}
void HeadAdjust(ElemType *A, int k, int len)
{
A[0] = A[k];
for(int i=2*k; i<=len; i*=2)
{
if(i<len && A[i] < A[i+1])
{ // 必须判断i < len,因为i有可能没有兄弟
i++;
}
if(A[0] >= A[i])
{ // 父节点的元素比最大孩子结点要大,筛选结束
break;
}
else {
// 不进行A[k]和A[i]值的交换,下一次判断用A[0]
A[k] = A[i];
k = i;
}
}
}
堆排序算法
1、每次访问堆顶元素
2、把堆顶元素放在堆底部,堆底部元素提在堆顶
3、对已访问元素之前的元素调整
4、重复操作
空间复杂度:
O
(
1
)
O(1)
O(1)
建立堆的时间复杂度:
O
(
n
)
O(n)
O(n)
时间复杂度:
O
(
n
l
o
g
2
n
)
O(nlog_2n)
O(nlog2n)
稳定性:不稳定
适用于顺序存储、(链式存储)
typedef int ElemType;
void HeapSort(ElemType *A, int len)
{
BuildMaxHeap(A, len);
for(int i=len; i>1; i--)
{
// visit(A[i]);
swap(A[i], A[1]);
HeadAdjust(A, 1, i-1);
}
}
堆的插入
堆的插入算法与HeadAdjust算法类似,不同的是堆插入是向上调整
ELemType A = (ElemType *) malloc(ElemType * (len+2));
void HeapInsert(ElemType *A, ELemType num, int len)
{
int k = len + 1; // 把新元素添加到堆底部
A[0] = A[k];
int i = k/2;
// 向上调整
while(A[0] > A[i] && i>0)
{
A[k] = A[i];
k = i;
i = k/2;
}
A[k] = A[0];
}