1. 程式人生 > >交換排序---氣泡排序----快速排序

交換排序---氣泡排序----快速排序

交換排序

氣泡排序

  • 比較相鄰的元素。
  • 如果第一個比第二個大,就交換他們兩個。
  • 對每一對相鄰元素做同樣的工作,從開始第一對到結尾的最後一對。 在這一點,最後的元素應該會是最大的數。
  • 針對所有的元素重複以上的步驟,除了最後一個。
  • 持續每次對越來越少的元素重複上面的步驟,直到沒有任何一對數字需要比較。
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);
}