交换排序:利用交换位置进行排序
冒泡排序
1、算法思想
重复的走访要排序的元素,依次比较相邻两个元素的大小,如果顺序错误则交换这两个元素的位置,直到不需要在比较
2、步骤
- 比较相邻两个元素,如果前一个比后一个大,则交换位置
- 从第一个元素一直比较到最后一个元素,这时最后一个元素的值是最大的
- 减掉最后一个元素,重复上述步骤
- 每次比较的元素个数逐渐减少,直到没有要比较的元素
程序代码:
void ButtorSort(int *array, int size)//冒泡排序
{
for (size_t i = 0; i < size - 1; i++)
{
for (size_t j = 0; j < size - 1 - i; j++)
{
if (array[j] > array[j + 1])
swap(array[j] , array[j + 1]);
}
}
}
最好情况下的时间复杂度:O(n)
最坏情况下的时间复杂度:O(n^2)
空间复杂度:O(1)
稳定性:稳定的
适用场景:
(1)数据量大
(2)数据随机
快速排序
方法一——基准值
算法描述:取第一个或最后一个元素为基准值;然后使标记left指向起始位置、right指向最后一个位置;让right从后往前走直至遇到比基准值小的时候才停下来,left从前往后走直至遇到比基准值大的时候停下来;然后交换arr[left]和arr[right]的值;重复上述步骤直至left>=right;然后交换基准值与当前停下来的位置的值。这个时候就以基准值为基础将数组分为两个部分,基准值左边的都小于基准值、基准值右边的都大于基准值。最后递归处理每部分。
步骤:
4 int pation(int *arr,int left,int right)
5 {
6 int key = left;
7 while(left < right)
8 {
9 while(left < right && arr[right] > arr[key])
10 right--;
11 while(left < right && arr[left] < arr[key])
12 left++;
13
14 swap(arr[left],arr[right]);
15 }
16 swap(arr[left],arr[key]);
17
18 return left;
19 }
20 void QuickSort(int *array,int left,int right)
21 {
22 if(left < right)
23 {
24 int n = pation(array,left,right);
25 QuickSort(array,left,n-1);
26 QuickSort(array,n+1,right);
27 }
28 }
方法二——挖坑法
算法描述:首先取首元素或最后一个元素为基准值key,让key=arr[0],这时候相当于第一个元素被挖走了,这里就成了一个坑;此时让right从后往前走找比key小的元素填到arr[0]这里,这时arr[right]这里又相当于是一个被挖走的坑;此时让left从前往后走找比key大的元素填到arr[right]。然后让right继续从后往前找填上一个坑,以此类推;直到left==right,此时此处必定是一个坑,将key的值填进去。这个时候就将整个数组分为两部分。最后递归调用。
快速排序的优化——三数取中
在数组中找三个数并取其中的中间值作为基准值
7 int mid(int *arr,int left,int right)
8 {
9 int mid = (right-left)/2+left;
10
11 if(arr[left] > arr[mid])
12 swap(arr[left],arr[mid]);
13 if(arr[mid] > arr[right])
14 swap(arr[mid],arr[right]);
15
16 return mid;
17 }
18 int pation(int *arr,int left,int right)
19 {
20 int key = mid(arr,left,right);
21 while(left < right)
22 {
23 while(left < right && arr[right] > arr[key])
24 right--;
25 while(left < right && arr[left] < arr[key])
26 left++;
27
28 swap(arr[left],arr[right]);
29 }
30 swap(arr[left],arr[key]);
31
32 return left;
33 }