一句话总结几种排序算法及其稳定性

排序的稳定性

这里写图片描述
稳定性: 两记录排序码相等,稳定的排序算法可以保证即使值相等,排序后顺序仍然不变。
因为原序列的顺序可能隐含一些信息,稳定排序算法维持这些信息。

冒泡排序(相邻元素排序调):如若两个数值相等,则不会发生交换,故该排序是稳定的。
选择排序(每次选最小的排序):如果较小的元素出现在一个和当前元素相等的元素后面,那么交换后稳定性就被破坏了,故该排序是稳定的。
插入排序(在已经有序的队列里插值):比较是从有序序列的末尾开始,
如果碰见一个和插入元素相等的,那么插入元素把想插入的元素放在相等元素的后面。插入排序是稳定的。
快速排序(从左往右,基数右移,小于基数前调):快速排序是一个不稳定的排序算法,不稳定发生在基数元素和a[j] 交换的时刻。详见下文快速排序的介绍
归并排序(将序列递归地分成短序列):稳定的排序算法。
希尔排序(shell)(按照不同步长对元素进行插入排序):不稳定的排序算法
堆排序(节点排序):当为n /2-1, n/2-2, …1这些个父节点选择元素时,就会破坏稳定性。有可能第n/2个父节点交换把后面一个元素交换过去了,而第n/2-1个父节点把后面一个相同的元素没有交换,这2个相同的元素之间的稳定性就被破坏了 。

综上,选择排序、快速排序、希尔排序、堆排序等不是稳定的排序算法,而 冒泡排序、插入排序、归并排序和基数排序等是稳定的排序算法。
这部分详细见百度百科

几种排序算法总结

  • BUBBLE 冒泡排序

从左往右,找到最大的移至最后

示例代码:

int i,j,k;
for(i=0;i<n-1;i++) //找出n-1个最大的放在右边
{
    for(j=0;j<n-1-i;j++) //排好的序列逐步从右向左推进
{
    if(ap[j]>ap[j+1])
    {
        swap(ap[j],ap[j+1]); //交换
    }
}}
  • SELECT 选择排序

从左往右,找到最小的移至前面,排好的序列由左向右推进。

示例代码:

void sort (int array[],int n)
{
int i,j,k,t;
for (i=0;i<n-1;i++) //需要n-1次
{
    k=i; //k保存最小的值
    for(j=i+1;j<n;j++) //从左向右推进
        if(array[k]>array[j])
    k=j; //k保存最小的值
    swap(array[k],array[i]);//交换
}
}
  • INSERT 插入排序

从左往右,依次为该数找到相应的位置插入前面序列

  • MERGE 归并排序

将数列多次分半,直到每组有两个数,对每小组进行排序,成为有序数列,再往前合并其他小组

  • QUICK 快速排序 O(N*logN)

visualgo里的排序流程
for each (unsorted) partition set first element as pivot
for i = pivotIndex + 1 to rightmostIndex
if element[i] < element[pivot]
swap(i, storeIndex);
storeIndex++ swap(pivot, storeIndex - 1)

先从数列中取出一个数作为基准数。一般为第一个数。
分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
再对左右区间重复第二步,直到各区间只有一个数。
总结:用i,j两个数左右搜索,将第一个值存入X,右往左找比X小的数,左往右找X大的数,填坑,i,j逼进,直到ij相等。此时,左边是比X小的数,右边是比X大的数

示例
主函数

int main()
{
    int array[10],k;
    int len;//要排列的数的长度,不能超过10个
    cout<<"the len";
    cout<<endl;
    cin>>len;
    cout<<"The orginal array are:"<<endl;
    for(int k=0; k<len; k++)
        cin>>array[k];

    quickSort(array,0,len-1);

    cout<<"The sorted array are:"<<endl;
    for(int k=0; k<len; k++)
        cout<<array[k]<<" ";
    cout<<endl;
    system("pause");
    return 0;
}

版本一

void quickSort(int s[], int l, int r) //主函数
{
if (l< r)
{
    int i = l, j = r, x = s[l];
while (i < j) //直到i==j
{
while(i < j && s[j]>= x) // 从右向左找第一个小于x的数
j–;
if(i < j)
s[i++] = s[j];//s[i] = s[j],++i;
while(i < j && s[i]< x) // 从左向右找第一个大于等于x的数
i++;
if(i < j)
s[j–] = s[i];//s[j] = s[i],–j;
}
s[i] = x;
quickSort(s, l, i – 1); // 递归调用
quickSort(s, i + 1, r);
}
}

版本二:

//一次划分
int Partition(int r[], int start, int end)
{
    if(r==NULL ||start <0||end < start)
        throw new std::exception("Invailid Paramater");
    //初始化
    int i=start;
    int j=end;
    int temp;
    while (i<j)
    {
        while (i<j && r[i]<= r[j])
            j--; 
        if (i<j) //右往左找到大值,交换值且i右移
        {
            //将较小记录交换到前面
            swap(r[i],r[j]);
            i++;
        }
        while (i<j && r[i]<=r[j])
            i++; //左侧扫描
        if (i<j)
        {
            swap(r[i],r[j]); //将较大记录交换到后面
            j--;
        }
    }
    return i; //i为轴值记录的最终位置
}

//快速排序
void quickSort(int r[], int start, int end)
{
    if (start<end)
    {
        //递归结束
        int pivot=Partition(r, start, end); //一次划分
        quickSort(r, start, pivot-1);//递归地对左侧子序列进行快速排序
        quickSort(r, pivot+1, end); //递归地对右侧子序列进行快速排序
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值