交换排序---冒泡排序----快速排序

交换排序

冒泡排序

  • 比较相邻的元素。
  • 如果第一个比第二个大,就交换他们两个。
  • 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。 在这一点,最后的元素应该会是最大的数。
  • 针对所有的元素重复以上的步骤,除了最后一个。
  • 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
void BubbleSort(int arr[], int size)
{
    int i, j;
    for (i = 0; i < size-1; i++)
    {
         int isSorted = 1;//一开始有序
         for (j = 0; j < size - 1 - i; j++)  //比较相邻的元素,比较一趟之后,
                                    //相邻两数之间的比较在下一趟就会减少一次
         {
             if (arr[j]>arr[j + 1]){
                 Swap(arr+j,arr+j+1);
                 isSorted = 0;
             }
         }
         if (isSorted == 1){
             break;
         }
    }
}

快速排序

  • 分治算法
    1.找一个基准值;找最边上(最右边)
    2.和数组上所有数比较,比基准值小的,放左边;比基准值大的,放右边
    3.终止条件:小区间内有序:长度==1
    小区间没有数:长度 <= 0
void _QuickSort(int arr[], int left, int right)
{
    if (left == right){
         return;//只有一个数,已经有序
    }
    if (left > right){
         return;//没有数,不需要排序
    }
    int div = Partition_01(arr, left, right);//分成左右小区间[left,div-1];[div+1,right]
    _QuickSort(arr, left, div - 1);
    _QuickSort(arr, div + 1, right);
    
}
void QuickSort(int arr[], int size)
{
    _QuickSort(arr, 0, size - 1);
}
  • 比基准值小的放左,大的放右,有三种方式
<1>.hover法  (左右指针)时间复杂度:O(n)
int Partition_01(int arr[], int left, int right)
{
    int begin = left;//不是0
    int end = right;//不是right-1
    while (begin < end){
         //如果基准值在最右边,想先动begin
         //arr[begin]要<=不能<
         while (begin<end && arr[begin] <= arr[right]){
             begin++;
         }
         while (begin < end && arr[end] >= arr[right]){
             end--;
         }
         Swap(arr + begin, arr + end);
    }
    Swap(arr + begin, arr + end);
    return begin;
}
<2>.挖坑法
找个变量pivot存基准值,则需要交换的值的位置为坑,直接可以换过来
begin,end对应的即为坑
int Partition_02(int arr[], int left, int right)
{
         int begin = left;//不是0
         int end = right;//不是right-1
         int pivot = arr[right];//保存基准值
         while (begin < end){
             //如果基准值在最右边,想先动begin
             //arr[begin]要<=不能<
             while (begin<end && arr[begin] <= pivot){
                 begin++;
             }
             arr[end] = arr[begin];
             while (begin < end && arr[end] >= pivot){
                 end--;
             }
             arr[begin] = arr[end];
         }
         arr[begin] = pivot;
         return begin;
}
<3>.左右指针法


int Partition_03(int arr[], int left, int right)
{
    int cur = left;
    int div = left;
    for (cur = left, div = left; cur < right; cur++)
    {
         if (arr[cur] < arr[right])
         {
             Swap(arr + cur, arr + div);
             div++;
         }
    }
    Swap(arr + div, arr + right);
}

猜你喜欢

转载自blog.csdn.net/WZL995/article/details/84899283