正文

排序算法  集中2006-11-07 17:34:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/embed/20066.html

分享到:

排序的算法集中到一起了,包括冒泡排序、选择排序、插入排序,Shell排序,快速排序、归并排序、堆排序,基数排序、bucket排序。

使用起来也很简单,包含SortAlgorithm.h即可直接使用(这里重在算法本身,用一个类包含static函数的做法则可以原谅了:)。

(两个文件:SortAlgorithm.hmain.cpp)。

//SortAlgorithm.h
#if !defined _SORT_ALGORITHM_H_
#define _SORT_ALGORITHM_H_

#ifndef NNULL
#define NULL 0L
#endif //~ NULL

#include <cassert>
#include <ctime>

#include <iostream>
using namespace std;

template <typename T>
class BasicSortor
{
public:
   
    // bubble sort
    static void bubbleSort( T* _data,int _left,int _right )
    {
        assert( NULL != _data );
        assert( ( _left >= 0 ) && ( _right >= _left ) );
   
        if ( 1 == _right - _left )  return ;  
   
        for ( int i = _left; i <= _right; ++i )
            for ( int j = _right; j > i; --j )
                if ( _data[j] < _data[j - 1] )
                    swap( _data[j], _data[j - 1] );
    }
   
    // select sort
    static void selectSort( T* _data, int _left, int _right )
    {
        assert( NULL != _data );
        assert( ( _left >= 0 ) && ( _right >= _left ) );
   
        if ( 0 == _right - _left ) return ;
   
        for ( int i = _left; i <= _right; ++i)
    {
            int min = i;
            for ( int j = i; j <= _right; ++j)
    {
                if ( _data[j] < _data[min] )
                min = j;
    }
   
            swap( _data[i],_data[min] );
    }
    }
   
    // insert sort
    static void insertSort( T* _data, int _left, int _right )
    {
        assert( NULL != _data );
        assert( ( _left >= 0 ) && ( _right >= _left ) );
   
        if ( 0 == _right - _left ) return ;
   
        for ( int i = _left; i <= _right; ++i )
    {
            int j = i;
            T tmp = _data[i];
   
            while ( ( j > _left ) && ( tmp < _data[j - 1] ) )
    {
                _data[j] = _data[j - 1];
        j--;
    }
   
            _data[j] = tmp;
    }
    }
   
    //shell sort
    static void shellSort( T* _data, int _left, int _right)
    {
        assert( NULL != _data );
        assert( ( _left >= 0 ) && ( _right >= _left ) );
   
        if ( 0 == _right - _left ) return ;
   
        int d = 0;
        for ( int  m = 0; m < ( _right - _left ) / 3; ++m )
            d = 3 * d + 1;
   
        for ( ; d > 0; d /= 3 )
    {
            for ( int i = _left; i <= _right; ++i )
    {
                int j = i;
                T tmp = _data[j];
   
                while ( ( j >= _left + d) && ( tmp < _data[j - d] ) )
        {
                    _data[j] = _data[j - d];
            j -= d;
        }
   
                _data[j] = tmp;
    }
    }
    }
   
    // quick sort
    static void quickSort( T* _data, int _left, int _right)
    {
        assert( NULL != _data );
   
        if ( _left >= _right ) return ;
   
        int mid = partition( _data, _left, _right );
        quickSort( _data, _left, mid - 1 );
        quickSort( _data, mid + 1, _right );
    }
   
    // merge sort
    static void mergeSort( T* _data, int _left, int _right )
    {
        assert ( NULL != _data );
   
        if ( _left >= _right ) return ;
   
        int mid = ( _left + _right ) / 2;
        mergeSort( _data, _left, mid );
        mergeSort( _data, mid + 1, _right );
        merge( _data, _left, _right, mid );
    }
   
    // heap sort
    static void heapSort( T* _data,int _left, int _right )
    {
        assert( NULL != _data );
        assert( ( _left >= 0 ) && ( _right >= _left ) );
   
        for ( int i = _right; i > ( _right - _left ) / 2; --i )
            fixUp(_data, _left, _right, i );
   
        while ( _right > _left )
    {
            swap( _data[_left], _data[_right] );
            fixDown( _data, _left, --_right, _left );
    }
    }
   
    // bucket sort
    static void bucketSort( T* _data,int _left, int _right, int MAX_NUM = 1000 )
    {
        assert( NULL != _data );
        assert( ( _left >= 0 ) && ( _right >= _left ) );
   
        if ( 0 == _right - _left ) return ;
   
        int num = _right - _left + 1;
        int* count = new int[MAX_NUM];
   
        // calculate the num of elements equal or less than _data[i]
        for ( int i = 0; i < MAX_NUM; ++i )
            count[i] = 0;
   
        for ( int j = _left; j <= _right; ++j )
            count[_data[j]]++;
   
        for ( int k = 1; k < MAX_NUM; ++k )
            count[k] += count[k - 1];
   
        T* tmp = new T[num];
   
        // copy each element to the right position
        // ( from right to left to reserve the related position in the array )
        for ( int m = _right; m >= _left; --m )
            tmp[--count[_data[m]]] = _data[m];
   
        for ( int n = _left; n <= _right; ++n)
            _data[n] = tmp[n - _left];
   
        delete[] count;
        delete[] tmp;
   
    }
   
    // radix sort
    static void radixSort( T* _data,int _left, int _right )
    {
        assert( NULL != _data );
        assert( ( _left >= 0 ) && ( _right >= _left ) );
   
        if ( 0 == _right - _left ) return ;

        const int WIDTH = 4;

        for ( int i = 1; i <= WIDTH; ++i )
            sortAtBit( _data, _left, _right, i );
    }


public:
    static void printData( const T* _data,
                           int _left,
                           int _right)
    {
        assert( NULL != _data );
        assert( (_left >= 0 ) && (_right >= _left) );
   
   
        for ( int i = _left; i <= _right; ++i)
    {
            cout<<_data[i]<<" ";
    }
   
        cout<<endl;
    }
   
    static T* initData( int ARR_LEN = 10,
                        int MAX_NUM = 1000 )
    {
        T* data = new T[ARR_LEN];
   
        srand( ( unsigned int )time(NULL));
   
        for ( int i = 0; i < ARR_LEN ; ++i)
    {
            data[i] = rand() % MAX_NUM;
    }
   
        return data;
    }
protected:
   
private:
   
    // swap
    static void swap(T& a,T& b)
    {
        T tmp = a;
        a = b;
        b = tmp;
    }
   
    // partition
    static int partition( T* _data,
                  int _left,
                  int _right)
    {
        assert ( NULL != _data);
        assert ( ( _left >= 0 ) && ( _right >= _left ) );
   
        if ( 0 == _right - _left )
    {
            return _left;
    }
   
        T tmp = _data[_left];
        int i = _left + 1;
        int j = _right;
   
        while ( true )
    {
            while ( _data[i] < tmp )
    {
        i++;
                if ( i == _right ) break;
    }

            while ( _data[j] > tmp )
        j--;
   
            if ( i >= j )
            break ;
   
            swap( _data[i], _data[j] );
    }
   
        swap( _data[_left], _data[j] );
   
        return j;
    }
   
    // merge
    static void merge( T* _data,
                       int _left,
                       int _right,
                       int _mid)
    {
        assert ( NULL != _data );
   
        int num = _right - _left + 1;
        T* tmp = new T[num];
   
        for ( int i = _left, j = _mid + 1, k = 0; k < num; ++k)
    {
            if ( i > _mid )
    {
                tmp[k] = _data[j++];
                continue ;
    }
            if ( j > _right )
    {
                 tmp[k] = _data[i++];
                 continue ;
    }
   
            tmp[k] = ( _data[i] < _data[j] ) ? _data[i++] : _data[j++];
    }
   
        for ( int m = _left; m <= _right; ++m )
            _data[m] = tmp[m - _left];
   
        delete[] tmp;
    }
   
    // heap fix up
    static void fixUp( T* _data,
                       int _left,
                       int _right,
                       int i )
    {
        int prt = ( i - _left - 1 ) / 2 + _left;   // parent node
        while ( i > _left )
    {
            if ( _data[i] < _data[prt] )
                swap( _data[i], _data[prt] );
   
            i = prt;
            prt = ( i - _left - 1 ) / 2 + _left;
    }
    }
   
    // heap fix down
    static void fixDown( T* _data,
                         int _left,
                         int _right,
                         int i )
    {
        int child = 2 * ( i - _left ) + 1 + _left;  // left child node
   
        while ( child <= _right )
    {
            if ( ( child + 1 <= _right ) && ( _data[child] > _data[child + 1] ) )
                child += 1;
   
            if ( _data[child] < _data[i] )
                swap( _data[child], _data[i] );
   
            i = child;
            child = 2 * ( i - _left ) + 1 + _left;
    }
    }
   
    // get bits from a int
    static int getBitAt( int num,
                          int i )
    {
        int ret = 0;
        while ( i-- > 0 )
    {
            ret = num % 10;
            num /= 10;
    }
   
        return ret;
    }
   
    // sort array on bit i
    static void sortAtBit( T* _data,
                           int _left,
                           int _right,
                           int d )
    {
        const int RADIX = 10;
   
        int count[RADIX] = { 0 };
   
        for ( int i = _left; i <= _right; ++i )
            count[getBitAt(_data[i], d)]++;
   
        for ( int j = 1; j < RADIX; ++j )
            count[j] += count[j - 1];
   
        int num = _right - _left + 1;
        T* tmp = new T[num];
   
        for ( int k = _right; k >= _left; --k )
            tmp[--count[getBitAt(_data[k], d)]] = _data[k];
   
        for ( int m = _left; m <= _right; ++m )
            _data[m] = tmp[m - _left];
   
        delete[] tmp;
    }
};

#endif //~_SORT_ALGORITHM_H_


//这里是最后简单的测试代码:
// main.cpp

#include "SortAlgorithm.h"

#include <iostream>
using namespace std;

int main(int argc,char* argv[])
{
    const int NUM = 20;

    cout<<"原始数据为:"<<endl;
    int* data = BasicSortor<int>::initData(NUM);
    BasicSortor<int>::printData(data,0,NUM - 1);

    cout<<"排序数据为:"<<endl;

    BasicSortor<int>::bubbleSort(data,0,NUM - 1);
    //BasicSortor<int>::selectSort(data,0,NUM - 1);
    //BasicSortor<int>::insertSort(data,0,NUM - 1);
    //BasicSortor<int>::quickSort(data,0,NUM - 1);
    //BasicSortor<int>::mergeSort(data,0,NUM - 1);
    //BasicSortor<int>::shellSort(data,0,NUM - 1);
    //BasicSortor<int>::heapSort(data,0,NUM - 1);
    //BasicSortor<int>::bucketSort(data,0,NUM - 1);
    //BasicSortor<int>::radixSort(data,0,NUM - 1);

    BasicSortor<int>::printData(data,0,NUM - 1);
   
    return 0;
}

阅读(229) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册