8种基本排序算法总结及相关代码

8种基本排序算法总结如下
这里写图片描述
各种演示代码,通过一个SortTest类来掩饰,在VS2010里面运行正常。最后的比较没有编写代码,并且一些输入信息没有做判断,只是实现了基本的排序功能
SortTest类代码如下,
SortTest.h

#pragma once
#include <vector>
using namespace std;
struct DigitInfo
{
    int digit;      // 随机数
    int index;      // 随机数的索引
};
class SortTest
{
public:
    SortTest(void);
    SortTest(int count, int start, int end);
    ~SortTest(void);
public:
    int count;
    int start;
    int end;
    DigitInfo *digitArray;                          // 随机生成数存储结构
    bool genRandDigits();                           // 生成随机数,存储在digitVec里面
    void printDigitArray();                         // 输出结果
    bool bubbleSort();                              // 冒泡排序
    bool quickSort();                               // 快速排序
    void swap(int i, int j);                        // 交换两个元素的数据
    bool quickSort_ChangePos(int left, int right);  // 快速排序要用到的递归调用函数
    bool directInsertSort();                        // 直接插入排序
    bool shellSort();                               // 希尔排序
    bool simpleSelectSort();                        // 选择排序
    bool maxHeapSort();                             // 堆排序(小顶堆)
    bool maxHeapAjust(int length, int nodeNum);     // 调整大顶推
    bool merge(int left, int mid, int right, DigitInfo *pDigitInfo);
    bool merge(int left, int right, DigitInfo *pDigitInfo);
    bool mergeSort();                               // 归并排序算法
    int getMaxNum();                                // 获取digitArray里面最大的数
    int getDigitCapacity();                         // 获取最大数字的位数
    bool baseSort();                                // 通过位数,将
    bool baseDigitSort();                           // 基数排序算法
    bool compareSort();                             // 比较各种算法所用时间,并且输出时间

};

SortTest.cpp

#include "SortTest.h"
#include <stdlib.h>
#include <time.h> 
#include <iostream>
#include <vector>
#include <queue>
#include "math.h"
using namespace std;

SortTest::SortTest(void)
{
    digitArray = NULL;
}

SortTest::SortTest(int count, int start, int end)
{
    digitArray = NULL;
    this->count = count;
    this->start = start;
    this->end = end;
}


SortTest::~SortTest(void)
{
    if (digitArray != NULL)
    {
        delete[] digitArray;
    }
}

bool SortTest::genRandDigits()      // 生成随机数,存储在digitVec里面
{
    if ( digitArray != nullptr)
    {
        delete[] digitArray;
    }
    srand((int)time(NULL));         //每次执行种子不同,生成不同的随机数
    digitArray = new DigitInfo[count];
    for(int i = 0; i < count; i ++)
    {
        int tmpRandDigit = rand() % ( end - start ) + start;
        struct DigitInfo digitInfo;
        digitInfo.digit = tmpRandDigit;
        digitInfo.index = i;
        digitArray[i] = digitInfo;
    }
    cout << "原始的排列顺序为以下:" << endl;
    printDigitArray();

    return true;
}

// 输出
void SortTest::printDigitArray()
{
    for (int i = 0; i < count; i ++)
    {
        if( i % 10 == 0 && i != 0)
            cout << endl;
        cout << digitArray[i].digit << "-[" << digitArray[i].index << "]" << "\t";
    }
}

// 冒泡排序
bool SortTest::bubbleSort()                         // 冒泡排序
{
    // 产生随机数
    genRandDigits();
    for(int i = 0; i < count - 1; i ++)             // 冒泡排序的趟数
    {
        bool flag = true;
        for( int j = 0; j < count - 1 - i; j ++)    // 每趟比较的次数
        {
            if ( digitArray[j].digit > digitArray[j + 1].digit )
            {
                swap(j, j + 1);
                flag = false;
            }
        }
        if (flag)
            break;
    }

    cout << "冒泡排序后的顺序是" << endl;
    printDigitArray();
    cout << endl;

    return true;
}



// 快速排序
bool SortTest::quickSort()
{
    genRandDigits();
    quickSort_ChangePos(0, count - 1);
    cout<< "快排之后的顺序:" << endl;
    printDigitArray();
    cout << endl;
    return true;
}

// 交换两个元素的值
void SortTest::swap(int i, int j)
{
    struct DigitInfo digitInfo;
    //digitInfo.digit = digitArray[i].digit;
    //digitInfo.index = digitArray[i].index;
    //digitArray[i].digit = digitArray[j].digit;
    //digitArray[i].index = digitArray[j].index;
    //digitArray[j].digit = digitInfo.digit;
    //digitArray[j].index = digitInfo.index;
    digitInfo = digitArray[i];
    digitArray[i] = digitArray[j];
    digitArray[j] = digitInfo;

}

// 递归调用,用于快速排序
bool SortTest::quickSort_ChangePos(int left, int right)
{
    int baseNum = digitArray[left].digit;   // 基准值,就取第一个
    int baseIndex = left;
    int tmpStart = left;
    int tmpEnd = right;
    if(left >= right)
        return true;
    while( tmpStart < tmpEnd )
    {
        if ( ( digitArray[tmpStart].digit > digitArray[tmpEnd].digit ) && ( tmpStart == baseIndex ) )
        {
            swap( tmpStart, tmpEnd );
            baseIndex = tmpEnd;
            tmpStart ++;
        }
        else if ( ( digitArray[tmpStart].digit > digitArray[tmpEnd].digit ) && ( tmpEnd == baseIndex ) )
        {
            swap( tmpStart, tmpEnd );
            baseIndex = tmpStart;
            tmpEnd --;
        }
        else if ( ( digitArray[tmpStart].digit <= digitArray[tmpEnd].digit ) && ( tmpStart == baseIndex ) )
        {
            tmpEnd --;
        }
        else if ( ( digitArray[tmpStart].digit <= digitArray[tmpEnd].digit ) && ( tmpEnd == baseIndex ) )
        {
            tmpStart ++;
        }       
    }   
    quickSort_ChangePos(left, baseIndex - 1);   // 左边
    quickSort_ChangePos(baseIndex + 1, right);  // 右边

    return false;
}

// 直接插入排序
bool SortTest::directInsertSort()
{
    // 产生随机数
    genRandDigits();
    for( int i = 1; i < count; i ++ )
    {
        if ( digitArray[i].digit < digitArray[i - 1].digit )     // 如果每次这个条件都不成立,则时间复杂度为O(n)
        {
            int tmpDigit = digitArray[i].digit;
            struct DigitInfo tmpDigitInfo = digitArray[i];
            int j = i - 1;
            for (; j >= 0 && digitArray[j].digit > tmpDigitInfo.digit; j -- )
            {
                digitArray[j + 1] = digitArray[j];
            }
            digitArray[j + 1] = tmpDigitInfo;
        }
    }

    cout << "直接插入排序排序后的顺序是" << endl;
    printDigitArray();
    cout << endl;
    return true;
}

// 希尔排序
bool SortTest::shellSort()
{
    genRandDigits();
    int increment = count / 2;
    while ( increment > 0 ) // 排序的趟数
    {
        for ( int i = 0; i < increment; i ++ )  // 分的组数
        {       
            for ( int j = i + increment; j < count ; j += increment) // 每组内需排序的元素个数
            {
                DigitInfo tmpDigitInfo = digitArray[j];
                int k = j - increment;
                for (; k >= 0 && digitArray[k].digit > tmpDigitInfo.digit; k -= increment)  // 每个元素的插入过程,查找的次数
                {
                    digitArray[k + increment] = digitArray[k];              
                }
                digitArray[k + increment] = tmpDigitInfo;
                printDigitArray();
                cout << "………………第" << j << "个元素排完了………………" << endl;
            }
            printDigitArray();
            cout << "***************一组排完了***************" << endl;

        }
        cout << "===============一趟排完了===============" << endl;
        increment /= 2;
    }
    cout << "希尔排序之后的顺序为:" << endl;
    printDigitArray();
    cout << endl;
    return true;
}

// 选择排序算法
bool SortTest::simpleSelectSort()
{
    genRandDigits();
    int minIndex = 0;               // 最小值的索引           
    for ( int i = 0; i < count; i ++ )
    {
        minIndex = i;
        for (int j = i; j < count; j ++ )
        {
            if( digitArray[j].digit < digitArray[minIndex].digit )
                minIndex = j;
        }
        swap(i, minIndex); // 将最小元素和第i个元素交换
    }

    cout << "简单选择排序之后的顺序为:" << endl;
    printDigitArray();
    cout << endl;
    return true;
}

// 堆排序(小顶堆)
bool SortTest::maxHeapSort()
{
    genRandDigits();
    for ( int i = count; i > 0; i -- )
    {
        for (int j = i / 2 - 1; j >= 0; j -- )
        {
            maxHeapAjust(i, j);
        }
        swap(0,i - 1);
    }

    cout << "堆排序(大顶堆)后的顺序为:" << endl;
    printDigitArray();
    cout << endl;
    return true;
}

// 调整至大顶堆
bool SortTest::maxHeapAjust(int length, int nodeNum)
{
    int leftChildNum = nodeNum * 2 + 1;
    int rightChildNum = nodeNum * 2 + 2;
    int maxIndex = nodeNum; // 临时变量用于存储左右孩子里面最大的值的nodeNum

    if ( leftChildNum <= length - 1 && digitArray[leftChildNum].digit > digitArray[maxIndex].digit )
    {
        maxIndex = leftChildNum;
    }
    if ( rightChildNum <= length - 1 && digitArray[rightChildNum].digit > digitArray[maxIndex].digit )
    {
        maxIndex = rightChildNum;
    }
    if ( maxIndex != nodeNum)
    {
        swap(nodeNum, maxIndex);
        maxHeapAjust(length, maxIndex);
    }

    return false;
}

// 将以left开始leftSize和以right开始rightSize为大小的有序合并给pDigitInfo指向的数组中
bool SortTest::merge(int left, int mid, int right, DigitInfo *pDigitInfo)
{
    int leftIndex = left;
    int rightIndex = mid + 1;
    int totalIndex = left;

    while ( leftIndex != mid + 1 && rightIndex != right + 1)
    {
        // 注意必须有等号,因为和右边的一样的话优先选左边的
        if ( digitArray[leftIndex].digit <= digitArray[rightIndex].digit)
        {
            pDigitInfo[totalIndex ++] = digitArray[leftIndex ++];
        }
        else
        {
            pDigitInfo[totalIndex ++] = digitArray[rightIndex ++];
        }
    }
    while ( leftIndex < mid + 1 )
    {
        pDigitInfo[totalIndex ++] = digitArray[leftIndex ++];

    }
    while( rightIndex < right + 1 )
    {
        pDigitInfo[totalIndex ++] = digitArray[rightIndex ++];
    }

    for (int i = left; i <= right; i ++)
    {
        digitArray[i] = pDigitInfo[i];
    }

    //cout << "合并之后:" << endl;
    //printDigitArray();
    //cout << endl;
    return true;
}

bool SortTest::merge(int left, int right, DigitInfo *pDigitInfo)
{
    if (left >= right)
    {
        return false;
    }
    int mid = ( left + right ) / 2;
    merge(left, mid, pDigitInfo);
    merge(mid + 1, right, pDigitInfo);
    merge(left, mid, right, pDigitInfo);

    return true;
}
// 归并排序算法
bool SortTest::mergeSort()
{
    DigitInfo *tmpDigitArray = new DigitInfo[count];
    genRandDigits();
    merge(0, count - 1, tmpDigitArray);
    delete[] tmpDigitArray;
    cout << "归并排序后的顺序:" << endl;
    printDigitArray();
    cout << endl;
    return true;
}

// 获取digitArray里面最大的数
int SortTest::getMaxNum()
{
    int maxNum = 0;
    for (int i = 0; i < count; i ++)
    {
        if(digitArray[i].digit > maxNum)
            maxNum = digitArray[i].digit;
    }
    return maxNum;
}

// 获取最大数字的位数
int SortTest::getDigitCapacity()
{
    int loopTimes = 0;
    int maxNum = getMaxNum();
    while (maxNum > 0)
    {
        maxNum /= 10;
        loopTimes ++;
    }

    return loopTimes;
}

// 
bool SortTest::baseSort()
{
    int digitCapacity = getDigitCapacity();

    for (int i = 0; i < digitCapacity; i ++)
    {
        vector<DigitInfo> bukets[10];   // 10个桶
        int numOfBucket = 0;
        for (int j = 0; j < count; j ++)
        {
            numOfBucket =( digitArray[j].digit / (int) pow((double)10, (double)i) ) % 10;   // 获取所应进入的桶的号码
            bukets[numOfBucket].push_back(digitArray[j]);                                   // 装入桶中
        }

        int indexOfArray = 0;
        for (int k = 0; k < 10; k ++)   // 从桶中放回到digitArray里面
        {
            //if(!bukets[k].empty())
            //{
            //  vector<DigitInfo>::iterator it = bukets[k].begin();
            //  while (it != bukets[k].end())
            //  {
            //      /*digitArray[indexOfArray] = *it;
            //      it ++;*/
            //      cout << it->digit << "\t";
            //      it ++;
            //  }
            //}


            if(!bukets[k].empty())
            {
                vector<DigitInfo>::iterator it = bukets[k].begin();
                while (it != bukets[k].end())
                {
                    digitArray[indexOfArray ++] = *it;
                    it ++;
                }
            }

        }

    }
    return true;
}

// 基数排序算法
bool SortTest::baseDigitSort()
{
    genRandDigits();
    baseSort();
    cout << "基数排序后的顺序:" << endl;
    printDigitArray();
    cout << endl;
    return true;
}

// 比较各种算法
bool SortTest::compareSort()
{
    DigitInfo *p = new DigitInfo[10];
    genRandDigits();
    // 把生成的数组存起来
    for (int i = 0; i < count; i ++)
    {
        p[i] = digitArray[i];
    }
    cout << "原始数组顺序:" << endl;
    printDigitArray();
    cout << "冒泡排序后的顺序为:" << endl;


    return true;
}

主函数
main.cpp

#include <iostream>
#include "stdlib.h"
#include "SortTest.h"
using namespace std;

void printMenu(int count, int start, int end)
{
    cout << "[0] 设置随机数的数量个数,目前数量为:" << count << endl;
    cout << "[1] 设置随机数的范围,目前范围为[" << start << "," << end << "]" << endl;
    cout << "[2] 交换排序算法" << endl;
    cout << "[3] 插入排序算法" << endl;
    cout << "[4] 选择排序算法" << endl;
    cout << "[5] 归并排序算法" << endl;
    cout << "[6] 基数排序算法" << endl;
    cout << "请选择:" << endl;
}

// 选择排序菜单
void printSwapSort()
{
    cout << "[0] 冒泡排序" << endl;
    cout << "[1] 快速排序" << endl;
    cout << "请选择:" << endl;
}

// 插入排序菜单
void printInsertSort()
{
    cout << "[0] 直接插入排序" << endl;
    cout << "[1] 希尔排序" << endl;
    cout << "请选择:" << endl;
}

// 选择排序菜单
void printSelectSort()
{
    cout << "[0] 简单选择排序" << endl;
    cout << "[1] 树形排序(堆排序)" << endl;
    cout << "请选择:" << endl;
}

// 处理交换排序
void swapSortHandler(int count, int start, int end)
{
    printSwapSort();
    int subChoice = 0;
    cin >> subChoice;
    switch( subChoice )
    {
    case 0:
        {
            SortTest sortTest(count, start, end);
            sortTest.bubbleSort();
        }
        break;
    case 1:
        {
            SortTest sortTest(count, start, end);
            sortTest.quickSort();
        }
        break;
    default:
        break;
    }
}

// 处理插入排序
void insertSortHandler(int count, int start, int end)
{
    printInsertSort();
    int subChoice = 0;
    cin >> subChoice;
    switch( subChoice )
    {
    case 0:
        {
            SortTest sortTest(count, start, end);
            sortTest.directInsertSort();
        }
        break;
    case 1:
        {
            SortTest SortTest(count, start, end);
            SortTest.shellSort();
        }
        break;
    default:
        break;
    }
}

// 处理选择排序
void selectSortHandler(int count, int start, int end)
{
    printSelectSort();
    int subChoice = 0;
    cin >> subChoice;
    switch(subChoice)
    {
    case 0:
        {
            SortTest sortTest(count, start, end);
            sortTest.simpleSelectSort();
        }
        break;
    case 1:
        {
            SortTest sortTest(count, start, end);
            sortTest.maxHeapSort();
        }
        break;
    default:
        break;
    }
}

// 处理归并排序
void mergeSortHandler(int count, int start, int end)
{
    SortTest sortTest(count, start, end);
    sortTest.mergeSort();
}

// 处理基数排序
void baseDigitHandler(int count, int start, int end)
{
    SortTest sortTest(count, start, end);
    sortTest.baseDigitSort();
}


void main()
{
    int randDigitCount = 10;                // 随机数的个数
    int randDigitStart = 0;             // 随机数的最小值
    int randDigitEnd = 100;         // 随机数的最大值

    while (1)
    {
        printMenu(randDigitCount, randDigitStart, randDigitEnd);
        int choice = 0;
        cin >> choice;
        switch(choice)
        {
        case 0:
            {
                cout << "请输入随机数的数量:" << endl;
                cin >> randDigitCount;
            }
            break;
        case 1:
            {
                cout << "请输入随机数的最小和最大值,中间用空格隔开" << endl; 
                cin >> randDigitStart >> randDigitEnd;
            }
            break;
        case 2:
            {
                swapSortHandler(randDigitCount, randDigitStart, randDigitEnd);  
            }
            break;
        case 3:
            {
                insertSortHandler(randDigitCount, randDigitStart, randDigitEnd);
            }
        case 4:
            {
                selectSortHandler(randDigitCount, randDigitStart, randDigitEnd);
            }
            break;
        case 5:
            {
                mergeSortHandler(randDigitCount, randDigitStart, randDigitEnd);
            }
            break;
        case 6:
            {
                baseDigitHandler(randDigitCount, randDigitStart, randDigitEnd);
            }
        default:
            break;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值