直接选择排序
1.在元素集合 array[i]–array[n-1] 中选择关键码最⼤(⼩)的数据元素
2.若它不是这组元素中的最后⼀个(第⼀个)元素,则将它与这组元素中的最后⼀个(第⼀个)元素 交换
3.在剩余的 array[i]–array[n-2](array[i+1]–array[n-1]) 集合中,重复上述步 骤,直到集合剩余 1 个元素
代码实现过程如下:
SelectSort.h
#pragma once
#include <stdio.h>
void Swap(int* x, int* y);
void SelectSort(int* arr, int n);
void Print(int* arr, int n);
SelectSort.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "SelectSort.h"
//交换数组内的元素
void Swap(int* x, int* y)
{
int tmp = *x;
*x = *y;
*y = tmp;
}
//选择排序
void SelectSort(int* arr, int n)
{
//end=n-1是为了防止越界
int begin = 0;
int end = n - 1;
while (begin < end)
{
//begin+1是为了减少比较的次数
int mini = begin;
int maxi = begin;
for (int i = begin + 1; i <= end; i++)
{
if (arr[maxi] < arr[i])
{
maxi = i;
}
if (arr[mini] > arr[i])
{
mini = i;
}
}
if (maxi == begin)
{
maxi = mini;
}
Swap(&arr[begin], &arr[mini]);
Swap(&arr[end], &arr[maxi]);
begin++;
end--;
}
}
void Print(int* arr, int n)
{
for (int i = 0; i < n; i++)
{
printf("%d", arr[i]);
}
printf("\n");
}
#define _CRT_SECURE_NO_WARNINGS 1
#include "SelectSort.h"
int main()
{
int arr[] = { 3,4,5,1,2,7,8,6,9 };
int n = sizeof(arr) / sizeof(arr[0]);
SelectSort(arr, n);
Print(arr, n);
return 0;
}
直接选择排序的特性总结:
1.直接选择排序思考⾮常好理解,但是效率不是很好。实际中很少使⽤
2.时间复杂度: O(N2)
3.空间复杂度: O(1)
快速排序
交换排序基本思想:
所谓交换,就是根据序列中两个记录键值的⽐较结果来对换这两个记录在序列中的位置 交换排序的特点是:将键值较⼤的记录向序列的尾部移动,键值较⼩的记录向序列的前部移动
快速排序
快速排序是Hoare于1962年提出的⼀种⼆叉树结构的交换排序⽅法,其基本思想为:任取待排序元素 序列中的某元素作为基准值,按照该排序码将待排序集合分割成两⼦序列,左⼦序列中所有元素均⼩ 于基准值,右⼦序列中所有元素均⼤于基准值,然后最左右⼦序列重复该过程,直到所有元素都排列 在相应位置上为⽌。
hoare版本
算法思路 :
1)创建左右指针,确定基准值
2)从右向左找出⽐基准值⼩的数据,从左向右找出⽐基准值⼤的数据,左右指针数据交换,进⼊下次 循环
问题1:为什么跳出循环后right位置的值⼀定不⼤于key?
当 left > right 时,即right⾛到left的左侧,⽽left扫描过的数据均不⼤于key,因此right此时指 向的数据⼀定不⼤于key
代码如下:
QuickSort.h
#pragma once
#include <stdio.h>
void Swap(int* x, int* y);
int _QuickSort(int* arr, int left, int right);
void QuickSort(int* arr, int left, int right);
void Print(int* arr, int n);
QuickSort.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "QuickSort.h"
void Swap(int* x, int* y)
{
int tmp = *x;
*x = *y;
*y = tmp;
}
//找基准值
int _QuickSort(int* arr, int left, int right)
{
//keyi表示基准值
int keyi = left;
left++;
//取等号是一个关键,如果不取等号会造成left和right相遇比基准值大
while (left <= right)
{
//这里数组里面的值不取等,是因为要跳出循环,保证基准值在序列的中间位置
while (left <= right && arr[right] > arr[keyi])
{
right--;
}
while (left <= right && arr[left] < arr[keyi])
{
left++;
}
if (left <= right)
{
//这里也是细节
Swap(&arr[left++], &arr[right--]);
}
}
Swap(&arr[keyi], &arr[right]);
return right;
}
//快速排序
void QuickSort(int* arr, int left, int right)
{
if (left <= right)
{
return;
}
//第一步找基准值
int keyi = _QuickSort(arr, left, right);
//左子序列
QuickSort(arr, left, keyi - 1);
//右子序列
QuickSort(arr, keyi + 1, right);
}