Qt5-可视化九大经典排序算法(二)插入排序

本文将在可视化算法一(传送门)的基础上实现插入排序,其实就是多添加了一个实现插入排序的函数,再将Widget里的构造函数中的goBubble更换成goInsertion就可以了。

先介绍一下插入排序,先给俩个官方介绍的传送门(百度百科Wiki对插入排序的介绍)

插入排序又可分为直接插入排序和折半插入排序,其中折半插入排序只是折半查找合适的位子。其实也可以结合扑克牌的理牌过程来理解。

直接插入排序(straight Insertion Sort)的基本操作时将一个记录擦汗如到已经排好序的有序表中,从而得到一个新的并且记录数增1的有序表。代码整体很简单,就是不断将较前者小的数插到有序表的合理位子。代码如下:

void Bubble::goInsertion()
{
    //直接插入排序
    for (int i = 1; i < length;i++) {
        int j ;
        if(data[i] < data[i - 1]){    //满足
            int temp = data[i];
            for (j = i - 1;j>= 0&&temp < data[j];j--) {//将比它大的数字往后挪一个位子
                data[j+1] = data[j];
                bubbleSignal(j);
                QThread::msleep(static_cast<unsigned int>(mDelay));
            }
            data[j + 1] = temp;
            bubbleSignal(j);
            QThread::msleep(static_cast<unsigned int>(mDelay));
        }
    }
}

运行结果,由于我用的截取gif文件的上限时间是20ms,所以在这里设置的延时是10ms,导致有点快,还请见谅。

总结,本来还想接着实现以下折半插入算法,可是仔细想了想,折半插入是优化查找合适的位子,但数组还是得进行那么多挪位,那不如直接边挪位边判断位子合不合适呢,就没实现了,如果读者有意,可尝试实现。很容易看出插入算法的时间复杂度是O(n^2),具体介绍还得看上面俩个传送门的。

另外,我将Bubble类中rand函数修改了下,以免出现相同的数据

void Bubble::rand()
{
    if(data == nullptr)
        throw "数据不合理";
    bool flag[length];
    for(int i = 0; i < length; i++)
        flag[i] = false;
    for(int i = 0; i < length ; i++){
        while(1){
            int r = qrand()%max + 1;
            if(flag[r-1] == false){
                data[i] = r;
                flag[r-1]= true;
                break;
            }
        }
    }
}

 

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