我目前已经学会的排序以及理解(会不断更新)
先贴个交换函数:
void Swap(int A[],int i,int j)
{
int temp = A[i];
A[i] = A[j];
A[j] = temp;
}
冒泡排序
这是进大学后c语言课本上介绍的第一个排序,也是最简单,最容易理解的一个排序,顾名思义,就像冒泡一样,一次一次把最值往最后面放,完成排序。函数代码如下:
void BubbleSort(int A[],int n)
{
for(int j = 0;j < n - 1;j++)
{
for(int i = 0;i < n - 1 - j;i++)
{
if(A[i] > A[i + 1]) //从小到大排序
{
Swap(A,i,i + 1);
}
}
}
}
冒泡排序是稳定的,因为即使有相同的数也不会打乱原来是次序,平均时间复杂度:O(n²)。
选择排序
相比于相邻交换的冒牌排序,选择排序是通过从未排序的数据元素中选出最值放在该序列的起始位置,直到所有元素排完,同样需要循环两次,无法优化时间。代码如下:
void SelectionSort(int A[],int n)
{
for(int i = 0;i < n - 1;i++)
{
int min = i;
for(int j = i + 1;j < n;j++)
{
if(A[j] < A[min])
{
min = j;
}
}
if(min != i)
{
Swap(A,min,i);
}
}
}
选择排序是不稳定的,因为如果有相同的数的话是可以改变原来次序的,平均时间复杂度:O(n²)。
插入排序
看到这个方法,我的第一反应便是抓扑克牌,原理和抓牌原理一样,即,左手上的牌是已经排好序了的,将左手上的牌依次和抓到的牌比较,如果大于抓到的牌便把这张牌左移,然后插入抓到的牌。函数代码如下:
void InsertionSort(int A[],int n)
{
for(int i = 1;i < n;i++)
{
int get = A[i];
int j = i - 1;
while(j >= 0 && A[j] > get)
{
A[j + 1] = A[j];
j--;
}
A[j + 1] = get;
}
}
相同的牌不影响顺序,插入排序是稳定的,平均时间复杂度:O(n²)。
快速排序
快速排序基于一种二分的思想,即以一个数为基准数,不断将数组二分,最终当所有基准数都归位后,排序也就完成了。快速排序之所以较快,是因为每次交换都是跳跃式的。函数代码如下:
void quicksort(int arr[],int left,int right)
{
if(left > right) return;
int i,j,temp;
temp = arr[left];//temp为基准数
i = left;
j = right;
while(i != j)
{
//基准数在左边,所以要从右边开始找
while(arr[j] >= temp && i < j)j--;
//再从左往右找
while(arr[i] <= temp && i < j)i++;
//如果没有相遇。就交换
if(i < j) Swap(arr,i,j);
}
arr[left] = arr[i];
arr[i] = temp;
quicksort(arr,left,i - 1);//继续处理左边
quicksort(arr,i + 1,right);//继续处理右边
}
下面这两等会了再补充。
浙公网安备 33010602011771号