1,直接选择排序(效率很低)
(1)时间复杂度O(N*N)
(2)代码:
void SelectSort(int arr[],int n)
{
//定义一个begin和end的下标,begin位置放较小的数,end位置放较大的数
//此算法可以一次选两个数,分别从数组的两头开始选择
int begin = 0;
int end = n - 1;
while (begin < end)
{
int mini = begin;
int maxi = begin;
//每次从begin到end开始选择,用mini和maxi两个下标来记录每次遍历的最大值和最小值
for (int i = begin; i <= end; i++)
{
if (arr[mini] > arr[i])
{
mini = i;
}
if (arr[maxi] < arr[i])
{
maxi = i;
}
}
//交换两个数所在的位置,让小数在数组左边,大数在数组右边
Swap(&arr[begin], &arr[mini]);
//特殊情况:当begin=maxi时,经过上一次的交换,maxi所指向的已经不是最大值了,而mini所指向的是最大值,所以让maxi=mini
//比如数组:9 3 5 2 7 8 6 -1 9 4
if (begin == maxi)
{
maxi = mini;
}
Swap(&arr[end], &arr[maxi]);
begin++;
end--;
}
}
void TestSelectSort()
{
int arr[] = { 4,3,5,6,7,9,8,1,0,2 };
SelectSort(arr, sizeof(arr) / sizeof(arr[0]));
ArrPrint(arr, sizeof(arr) / sizeof(arr[0]));
}
2,堆排序(时间复杂度为O(N*logN,以二为底))
(1)前提知识:
堆的逻辑结构是一个完全二叉树,物理结构还是一个数组
堆的两个特性:结构性,用数组表示的完全二叉树;有序性,父亲节点是左子树右子树中的最大值或最小值。
大堆要求:树中所有父亲节点都大于等于孩子节点
小堆要求:树中所有父亲节点都小于等于孩子节点
通过下标父亲与孩子节点的关系:
leftchild=parent*2+1
rightchild=parent*2+2
parent=(child-1)/2
向下调整算法:(前提是左子树右子树都是大堆或者小堆)
从根节点开始,选出左右孩子中较小(大)的那个,去跟父亲节点进行比较,如果比父亲小(大)就交换,然后再往下调,知道叶子结点就结束。这样就可以保证父亲节点是最值。
(2)代码:
void ArrPrint(int a[], int n)
{
int i = 0;
for (i = 0; i < n; i++)
{
printf("%d ", a[i]);
}
}
void Swap(int* p1, int* p2)
{
int temp = *p1;
*p1 = *p2;
*p2 = temp;
}
//向下调整算法,前提是左右子树都是小堆或者是大堆,目的是确保根节点是最小的
void AdjustDown(int arr[], int n, int root)
{
int parent = root;
int child = parent * 2 + 1;
while (child < n)
{
//选出最小(大)的孩子(child+1<n是为了确保只有一个节点的时候不报错)
if (child+1<n&&arr[child + 1] > arr[child])
{
child++;
}
//跟父亲进行比较
if (arr[child] > arr[parent])
{
Swap(&arr[parent],&arr[child]);
parent = child;
child = parent * 2 + 1;
}
else
{
break;
}
}
}
void HeapSort(int arr[], int n)
{
//建堆的时间复杂度为0(n)
//把数组建成堆,可以一个一个树进行调整,从最后一个非叶子节点开始调(实际上就是最后一颗树)
//最后一个非叶子结点其实就是最后一个节点的父亲
for (int i = (n - 1 - 1) / 2; i >= 0; i--)
{
AdjustDown(arr, n, i);
}
//排升序,要建大堆
int end = n - 1;
while (end > 0)
{
Swap(&arr[0], &arr[end]);
AdjustDown(arr, end, 0);
end--;
}
}
void TestHeapSort()
{
//堆排序的时间复杂度为N*LogN(以二为底)
int arr[] = { 4,3,5,6,7,9,8,1,0,2 };
HeapSort(arr, sizeof(arr) / sizeof(arr[0]));
ArrPrint(arr, sizeof(arr) / sizeof(arr[0]));
}