排序算法(三)简单选择排序和直接插入排序

简单选择排序

选择排序的基本思想是每一趟在n-i+1(i=1,2,...,n-1)个记录中选取关键字最小的记录作为有序序列的第i个记录。

1、简单选择排序算法

简单选择排序法(Simple Selection Sort)就是通过n-i次关键字间的比较,从n-i+1个记录中选出关键字最小的记录,并和第i(1≤i≤n)个记录交换之。

/* 对顺序表L作简单选择排序 */
void SelectSort(SqList *L)
{
    int i, j, min;
    for (i = 1; i < L->length; i++)
    {
        /* 将当前下标定义为最小值下标 */
        min = i;                                
        /* 循环之后的数据 */
        for (j = i + 1; j <= L->length; j++)    
        {
            /* 如果有小于当前最小值的关键字 */
            if (L->r[min] > L->r[j])            
            /* 将此关键字的下标赋值给min */
            min = j;                            
        }
        /* 若min不等于i,说明找到最小值,交换 */
        if (i != min)                           
            /* 交换L->r[i]与L->r[min]的值 */
            swap(L, i, min);                    
    }
}

直接插入排序

  直接插入排序基本思想是每一步将一个待排序的记录,插入到前面已经排好序的有序序列中去,直到插完所有元素为止。

排序算法(三)简单选择排序和直接插入排序_第1张图片

/* 对顺序表L作直接插入排序 */
void InsertSort(SqList *L)
{
    int i, j;
    for (i = 2; i <= L->length; i++)
    {
        /* 需将L->r[i]插入有序子表 */
        if (L->r[i] < L->r[i - 1])        
        {
            /* 设置哨兵 */
            L->r[0] = L->r[i];            
            for (j = i - 1; L->r[j] > L->r[0]; j--)
                /* 记录后移 */
                L->r[j + 1] = L->r[j];    
            /* 插入到正确位置 */
            L->r[j + 1] = L->r[0];        
        }
    }
}

 

当最好的情况,也就是要排序的表本身就是有序的,比如纸牌拿到后就是{2,3,4,5,6},那么我们比较次数,其实就是代码第6行每个L.r[i]与L.r[i-1]的比较,共比较了(n-1)sigma(i=2, n, 1)次,由于每次都是L.r[i]>L.r[i-1],因此没有移动的记录,时间复杂度为O(n)。

当最坏的情况,即待排序表是逆序的情况,比如{6,5,4,3,2},此时需要比较sigma(i=2, n, i)=2+3+...+n=(n+2)(n-1)/2次,而记录的移动次数也达到最大值sigma(i=2, n, i+1)=(n+4)(n-1)/2次。

如果排序记录是随机的,那么根据概率相同的原则,平均比较和移动次数约为n2/4次。因此,我们得出直接插入排序法的时间复杂度为O(n2)。从这里也看出,同样的O(n2)时间复杂度,直接插入排序法比冒泡和简单选择排序的性能要好一些。

 

你可能感兴趣的:(数据结构)