1. 程式人生 > 其它 >桶排序,基數排序

桶排序,基數排序

技術標籤:資料結構與演算法應用C++連結串列資料結構

桶排序

在這裡插入圖片描述
這裡是百度百科桶排序介紹圖,排序方法描述就是:對於要排序的目標取值範圍在0~n-1的m個數,例項說明,排序3,5,6,1,2,4,3這7個數字,取值在0~9之間;

  1. 首先建立10個桶子,編號分別為0、1、2……9,
  2. 按照這7個數字,把他們分別放到相應編號的桶子中
  3. 從桶子中按順序收集資料

註明:源資料為按連結串列排列,每個桶子也是一個連結串列。
程式碼如下:


template<class T>
void chain<T>::binSort(int range)
{// Sort the nodes in the chain.
// create and initialize the bins chainNode<T> **bottom, **top; bottom = new chainNode<T>* [range + 1]; top = new chainNode<T>* [range + 1]; for (int b = 0; b <= range; b++) bottom[b] = NULL; // 把節點放到箱子中 // 箱排序是每個箱子往頭結點插入 for (; firstNode != NULL; firstNode =
firstNode->next) {// add firstNode to proper bin int theBin = firstNode->element; // type conversion to int if (bottom[theBin] == NULL) // 箱子是空的,直接把插入節點設為頭結點 bottom[theBin] = top[theBin] = firstNode; else {// bin not empty top[theBin]->next = firstNode; top[
theBin] = firstNode; } } // collect from bins into sorted chain // 把箱子中的節點收集到排序的連結串列中 chainNode<T> *y = NULL; for (int theBin = 0; theBin <= range; theBin++) if (bottom[theBin] != NULL) {// bin not empty if (y == NULL) // first nonempty bin firstNode = bottom[theBin]; else // not first nonempty bin y->next = bottom[theBin]; y = top[theBin]; } if (y != NULL) y->next = NULL; //把用來排序的箱子空間釋放 delete [] bottom; delete [] top; }

基數排序

基數排序是桶排序的升級版
基數排序是多個桶排序,比如二位數的基數排序,取模10,然後對於個位、十位,有0~9共10個箱子,先按照各位排序,把整個數字放到桶子中,放到桶子中相應位置的編號為該數字的個位數,放進去之後,進行桶排序,結果是一個個位有序,而十位無序的表,然後把該表按照十位為其編號放到桶子中,桶排序,進行收集,之後的結果就是整體有序的數字了。

計算執行步數的話,例如對於取值在0~10^6的1000個數字,如果按照模1000的基數排序,一共需要兩次桶排序,每次桶排序共需要1000+1000+1000=3000個步驟,共2*3000=6000
為什麼是3000?
1000個桶子初始化->分配1000個整數->從1000個桶子中收集;
因此,如果按照模100的計數排序共需要3*(100+1000+100)=3600個執行步
把數分解為數字需要出發和取模操作。如果用基數10來分解,那麼從最低位到最高位的數字分解式為x%10;(x%100)/10;(x%1000)/100;……

template<class T>
int chain<T>::decompose(int value,int range,int time)
{
    if(time == 1)
        return value%range;
    for(int i = 1; i < time; i++)
    {
        range *=10;
    }
    return (value%range)/(range/10);
}
template<class T>
void chain<T>::binSort(int range)
{
    for(int time = 1;time < 3; time++)
    {
        // Sort the nodes in the chain.
        // create and initialize the bins
        chainNode<T> **bottom, **top;
        bottom = new chainNode<T>* [range + 1];
        top = new chainNode<T>* [range + 1];
        for (int b = 0; b <= range; b++)
            bottom[b] = NULL;

        // 把節點放到箱子中
        // 箱排序是每個箱子往頭結點插入
        for (; firstNode != NULL; firstNode = firstNode->next)
        {
            // add firstNode to proper bin
            int theBin = decompose(firstNode->element,range,time); // type conversion to int
            if (bottom[theBin] == NULL) // 箱子是空的,直接把插入節點設為頭結點

                bottom[theBin] = top[theBin] = firstNode;
            else
            {
                // bin not empty
                top[theBin]->next = firstNode;
                top[theBin] = firstNode;
            }
        }

        // collect from bins into sorted chain
        // 把箱子中的節點收集到排序的連結串列中
        chainNode<T> *y = NULL;
        for (int theBin = 0; theBin <= range; theBin++)
            if (bottom[theBin] != NULL)
            {
                // bin not empty
                if (y == NULL) // first nonempty bin
                    firstNode = bottom[theBin];
                else // not first nonempty bin
                    y->next = bottom[theBin];
                y = top[theBin];
            }
        if (y != NULL)
            y->next = NULL;
        //把用來排序的箱子空間釋放
        delete [] bottom;
        delete [] top;
    }
}
template<class T>
void chain<T>::RadixSort(int range)
{
    // Sort the nodes in the chain
    binSort(range);//對個位進行排序
}