C++简单的几个排序(冒泡 插入 希尔 快速)

冒泡排序

冒泡排序的基本思想:通过无序区中相邻记录关键字间的比较和位置的交换,使关键字最小的记录如气泡一般逐渐往上“漂浮”直至“水面”。

整个算法是从最下面的记录开始,对每两个相邻的关键字进行比较,且使关键字较小的记录换至关键字较大的记录之上,使得经过一趟冒泡排序后,关键字最小的记录到达最上端,接着再在剩下的记录中找关键字次小的记录,并把它换在第二个位置上。依次类推,一直到所有记录都有序为止。

**若有 n个数据元素,则比较次数为:(n-1)n/2
交换次数:
如果序列本身有序,无需交换
如果序列本身倒序,交换(n-1)n/2
因此,冒泡排序的时间复杂度为O(n^2)
2)稳定性

#include "stdafx.h"

#include<iostream>
#include<string>
using namespace std;
// 冒泡排序
int main()
{
        int list[10] = { 56,98,10,84,19, 53,68,73,34,71 };
        int length = sizeof(list) / sizeof(list[0]);//求数组长度
        cout << length << endl;
        //-----------------------------------------------
        for (int i = 0; i < length-1; i++)
        {
                for (int j = 0; j < length-1-i; j++)
                {
                        if (list[j]>list[j+1])
                        {
                                int temp = list[j];
                                list[j] = list[j + 1];
                                list[j + 1] = temp;
                        }
                }
        }
        for (int i = 0; i < length; i++)
        {
                cout << list[i]<<" ";
        }
    return 0;
}

插入排序

假设待排序的记录存放在数组R[0…n-1]中,排序过程的某一中间时刻,R被划分成两个子区间R[0…i-1]和R[i…n-1],其中:前一个子区间是已排好序的有序区,后一个子区间则是当前未排序的部分,不妨称其为无序区。

直接插入排序的基本操作是将当前无序区的第1个记录R[i]插入到有序区R[0…i-1]中适当的位置上,使R[0…i]变为新的有序区。

**1)时间复杂度
若有 n个数据元素序列
如果序列本身有序,比较n-1次,交换0次
如果序列本身倒序,比较(n-1)n/2次,交换(n-1)n/2次
所以插入排序的时间复杂度为O(n2),最优复杂度为O(n)
2)稳定性

#include "stdafx.h"

#include<iostream>
#include<string>
using namespace std;

int main()
{
        int list[10] = { 56,98,10,84,19, 53,68,73,34,71 };
        int length = sizeof(list) / sizeof(list[0]);//求数组长度
        cout << length << endl;
    
       
        int  key = 0;//监视哨
        for (int i = 0; i < length; i++)
        {
                for (int j = i-1; j >=0; j--)                  //******
                {
                        if (list[j+1]>list[j])
                        {
                        key = list[j + 1];
                        list[j + 1] = list[j];
                        list[j] = key;

                        }
                }
        }
        for (int i = 0; i < length; i++)
        {
                cout << list[i] << "  ";
        }

    return 0;
}



希尔 排序

希尔排序:希尔排序又称为缩小增量排序,它是一种插入排序。其基本思想是:

把记录按步长(增量)分组,对每组记录采用插入排序方法进行排序;

随着步长逐渐缩小,所分成的组包含的记录越来越多,当步长的值减到1时,整个数据合成为一组;

增量序列的选择一般依据下面两点:
1)最后一个增量必须为1;
2)应该尽量避免序列中的值(尤其是相邻的值)互为倍数的情况。
希尔排序的时间性能优于直接插入排序的原因:
1)当数据有序时,插入排序所需的比较和移动次数均较少,复杂度为O(n)。
2)在希尔排序分组,每组的记录数目少,使用插入排序速度快,当增量为1时,数据又接近有序,速度自然快了。因此,希尔排序在效率上较直接插人排序有较大的改进。平均时间复杂度为O(n^2)。
因为以增量跳跃分组排序,所以希尔排序不稳定。


#include <iostream>
#include<string>
using namespace std;
/*数组遍历*/
void ListShow(int list[],int length){
        for(int i=0;i<10;i++){
        cout<<list[i]<<"  ";
        }
        cout<<endl;
}

void ShellSort(int *list,int len){
        int incream=len;//增量
        int i,j;
        int key=0;
        do{
        incream=incream/3;
        for(i=incream;i<len;i++){
                if(list[i]<list[i-incream]){
                        key=list[i];
                        for(j=i-incream;j>=0&&key<list[j];j-=incream){
                                list[j+incream]=list[j];
                                list[j]=key;
                        }
                }
        } 
 
        }while(incream>1);  cout<<"结果:";
ListShow(list,len);
} 
int  main()
{
        int list[10]={56,98,10,84,19, 53,68,73,34,71};
        int length=sizeof(list)/sizeof(list[0]);//求数组的长度,C++固定方式
          ListShow(list,length);
           ShellSort(list,length);
        return 0;
}


快速排序

快速排序的基本思想:在待排序的n个记录中任取一个记录,把该记录放入适当位置后,数据序列被此记录划分成两部分。所有关键字比该记录关键字小的记录放置在前一部分,所有比它大的记录放置在后一部分,并把该记录排在这两部分的中间(称为该记录归位),这个过程称作一趟快速排序。 首先对无序的记录序列进行“一次划分”,之后分别对分割所得两个子序列“递归”进行快速排序。
设待排序的表有10个记录,其关键字分别为{6,8,7,9,0,1,3,2,4,5},采用快速排序方法进行排序的详细过程如下图所示。

在这里插入图片描述

排序步骤:

1**)选取6为key,先从尾部(high指针)开始查找比key小的数与key交换,然后从头部(low指针)开始查找比key大的数与key交换,交替进行,直到high指针和low指针相遇,第一趟排序结束,由key将序列分成左右两个子序列,左边都比key小,右边都比key大。
2)以同样的方法排序左子序列,直到左子序列有序。
3)再以同样的方法排序右子序列,直到右子序列有序。**

)时间复杂度

现有 n个数据元素序列

首先对整个数列所有元素都比较一次,分成两个序列,比较的次数为n

然后再对这两个子序列排序,假设子序列时间排序为O(n/2)

则n个元素的时间复杂度=

<=2O(n/2)+n

<=2(2(O(n/4))+n/2))+n=4O(n/4)+2n

<=2(2(2(O(n/8))+n/4)+n/2))+n=8O(n/8)+3n

……

<=n(O(1))+nlog2^n (O(1)=0)

<= nlog2^n

快速排序的时间复杂度为:O(nlog2^n)

2)稳定性

在实施快速排序的过程中,相同元素的顺序过能会因为在左右两个序中不断的改变位置,因此最后的排序结果相同元素的位置有可能发生变化,因此快速排序算法是不稳定的。

发布了24 篇原创文章 · 获赞 48 · 访问量 2237

猜你喜欢

转载自blog.csdn.net/H_L_Y/article/details/94472142