C——冒泡排序、快速排序,選擇排序

在編程中, 排序是數據處理的重要內容。排序的方法有很多種,根據序列的規模以及數據處理的需求,所採用的方法也不同。在這就整理一下簡單的三種排序方法。


一、冒泡排序

冒泡排序的原理是:一次比較相鄰的兩個數,小的放到前面,大的放到後面。
在第一趟:首先比較第1個和第2個數,將小數放前,大數放後。然後比較第2個數和第3個數,將小數放前,大數放後,如此繼續,直至比較最後兩個數,將小數放前,大數放後。至此第一趟結束,將最大的數放到了最後。在第二趟:仍從第一對數開始比較(因爲可能由於第2個數和第3個數的交換,使得第1個數不再小於第2個數),將小數放前,大數放後,一直比較到倒數第二個數(倒數第一的位置上已經是最大的),第二趟結束,在倒數第二的位置上得到一個新的最大數(其實在整個數列中是第二大的數)。如此下去,重複以上過程,直至最終完成排序。由於在排序過程中總是小數往前放,大數往後放,相當於氣泡往上升,所以稱作冒泡排序。

實現:

void bubble_sort(int arr[], int len)
{
    int i, j;
    int tmp;
    int flag = 0;

    if(len < 1)
    {
        return;
    }
    for(i=0; i<len; i++)   /*要排序len次*/
    {
        for(j=0; j<len-1; j++)   /*每次從頭遍歷*/
        {
            if(arr[j] > arr[j+1])    /*比較大小*/
            {
                swap(&arr[j], &arr[j+1]);   /*交換*/
                flag = 1;
            }
        }
        if(0 == flag)
            break;
    }
}

這裏設置了一個flag,若一開始這個序列就是有序序列,就不用排了。


二、快速排序

快速排序原理:通過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比另外一部分的所有數據都要小,然後再按此方法對這兩部分數據分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數據變成有序序列。(”二分“的思想)

舉例說明:
如無序數組[6 2 4 1 5 9]
a),先把第一項[6]取出來,(通常選用第一個數據)作爲關鍵數據
用[6]依次與其餘項進行比較,
如果比[6]小就放[6]前邊,2 4 1 5都比[6]小,所以全部放到[6]前邊
如果比[6]大就放[6]後邊,9比[6]大,放到[6]後邊,
一趟排完後變成下邊這樣:
排序前 6 2 4 1 5 9
排序後 2 4 1 5 6 9

b),對前半部分[2 4 1 5]繼續進行快速排序
重複步驟a)後變成下邊這樣:
排序前 2 4 1 5
排序後 1 2 4 5
前半部分排序完成,總的排序也完成:
排序前:[6 2 4 1 5 9]
排序後:[1 2 4 5 6 9]

實現:

void quick_sort(int *arr, int left, int right)
{
    int i = left;
    int j = right;
    int key = arr[left];   /*key保存的是基準數*/

    if(left >= right)
        return;
    while(i < j)   /*在組內尋找*/
    {
        while(i < j && key <= arr[j])  /*要先從後往前找*/
        {
            j--;  /*往前找*/
        }

        while(i < j && key >= arr[i])  /*再從前往後找*/
        {
            i++; /*往後找*/
        }

        if(i < j)   /*i和j沒碰到一起時*/
        {
            swap(&arr[i], &arr[j]);  /*交換*/
        }
    }
    /*基準數歸位*/
    arr[left] = arr[i];
    arr[i] = key;

    quick_sort(arr, left, i-1);  /*遞歸處理前半部分*/
    quick_sort(arr, i+1, right);  /*遞歸處理後半部分*/
}

三、選擇排序

選擇排序原理:每一次從無序組的數據元素中選出最小(或最大)的一個元素,存放在無序組的起始位置,無序組元素減少,有序組元素增加,直到全部待排序的數據元素排完。
比如:10個數需排9次,按升序排列,第一趟比較:則是將數組的第一個元素與數組中從第二個元素開始到最後的元素進行比較找到最小的數記錄下來然後將值賦值給數組的第一個元素,然後進行第二趟比較:則是將數組的第二個元素與數組中從第三個元素開始到最後的元素進行比較,找最小的數記錄下來將值賦值給數組的第二個元素。……依次循環。

實現:

void select_sort(int *arr, int len)
{
    int i, j;
    int tmp;
    int min;

    for(i = 0; i < len - 1; i++)
    {
        min = i;    /*每次都把min置成無序組起始位置元素下標*/
        for(j = i; j < len; j++)   /*遍歷無序數組,尋找最小值*/
        {
            if(arr[min] > arr[j])
            {
                min = j;
            }
        }

        if(min != i)   /*若最小值沒在起始位置*/
        {
            swap(&arr[min], &arr[i]);  /*交換*/
        }
    }
}

完整代碼:

/*********************************************************************************
 *      Copyright:  (C) 2017 TangBin<[email protected]>
 *                  All rights reserved.
 *
 *       Filename:  sort.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(08/01/2017)
 *         Author:  TangBin <[email protected]>
 *      ChangeLog:  1, Release initial version on "08/01/2017 01:40:38 PM"
 *                 
 ********************************************************************************/

#include <stdio.h>
#include <stdlib.h>

#define LEN(array) ( (sizeof(array))/(sizeof(array[0])) )

void swap(int *a, int *b)
{
    int tmp;

    tmp = *a;
    *a = *b;
    *b = tmp;
}
void bubble_sort(int arr[], int len)
{
    int i, j;
    int tmp;
    int flag = 0;

    if(len < 1)
    {
        return;
    }
    for(i=0; i<len; i++)
    {
        for(j=0; j<len-1; j++)
        {
            if(arr[j] > arr[j+1])
            {
                swap(&arr[j], &arr[j+1]);
                flag = 1;
            }
        }
        if(0 == flag)
            break;
    }
}

void quick_sort(int *arr, int left, int right)
{
    int i = left;
    int j = right;
    int key = arr[left];

    if(left > right)
        return;
    while(i < j)
    {
        while(i < j && key <= arr[j])
        {
            j--;
        }

        while(i < j && key >= arr[i])
        {
            i++;
        }

        if(i < j)
        {
            swap(&arr[i], &arr[j]);
        }
    }
    arr[left] = arr[i];
    arr[i] = key;

    quick_sort(arr, left, i-1);
    quick_sort(arr, i+1, right);
}
void select_sort(int *arr, int len)
{
    int i, j;
    int tmp;
    int min;

    for(i = 0; i < len - 1; i++)
    {
        min = i;
        for(j = i; j < len; j++)
        {
            if(arr[min] > arr[j])
            {
                min = j;
            }
        }

        if(min != i)
        {
            swap(&arr[min], &arr[i]);
        }
    }
}
int main()
{
    int arr[] = {8, 3, 7, 1, 8, 10, 9, 100, 78};
    //int arr[] = {1, 2, 3, 4, 5, 6};
    int i;

    //bubble_sort(arr, LEN(arr));
    //quick_sort(arr, 0, LEN(arr));
    select_sort(arr, LEN(arr));

    for(i=0; i<LEN(arr); i++)
    {
        printf("%-6d", arr[i]);
    }
    printf("\n");

    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章