暑假第一天,简单的排序。

    This is my first 文章。

    今天我们学习了最基础的算法,最简单的排序

(一)稳定排序: a在b的前面,且a=b,排序后a还在b的前面,这就是稳定的排序

         既然有稳定的那就肯定有不稳定的排序

         不稳定排序:a在b的前面,且a=b,排序后a可能会出现在b的后面,这就是不稳定的排序

         然后是内排序,外排序

(二)内排序:所有的排序操作都是在内存内完成的

          外排序:数据太大,需要给数据存放到磁盘,通过数据传输,进行排序

(三)时间复杂度:程序运行时间,一个算法中语句执行的次数,记为T(n)

           1.n是数据的规模

           2.T就是函数比如T(n)=n^2+n*2+c

扫描二维码关注公众号,回复: 2203775 查看本文章

           3.用大O阶来表示

           4.时间的复杂度:O(1),O(n),O(logn),O(n^2),O(n^3)~~~O(n^k)

(四)空间复杂度

        空间复杂度就是程序运行是所占的内存大小。

算法的时间复杂度和空间复杂度合称为算法的复杂度,他们往往是相互影响的,当追求一个较好的时间复杂度时,可能会使空间复杂度的性能变差,即可能导致占用较多的存储空间;反之,当追求一个较好的空间复杂度时,可能会使时间复杂度的性能变差,即可能导致占用较长的运行时间,所以我们在编写程序或者代码的时间就需要考虑,算法的时间,数据所占空间的大小,还有算法描述语言的特性,算法运行的机器系统环境等各方面因素,才能够设计出比较好的算法。

(五)排序

1.冒泡排序

int main()
{
    int a[250];
    int n;
    cin>>n;
    for(int i=0;i<n;i++)
    cin>>a[i];
    
    //冒泡排序
    //从第一个开始比较,如果这个数比后面的大则交换位置,然后一直比较到最后,这时最后的就是最大的数
    //,然后继续比较之前的数,还是2个比较从头开始,把最大的排到倒数第二个位置,然后,继续轮回一直比较
    //到第一个数,
    //本质:就是最大的数往下排
    for(int i=n;i>0;i--)
    {
        for(int j=n;j>n-i+1;j--)
    
        if(a[j]<a[j-1])
        {
            swap(a[j],a[j-1]);
        }
    }
    
    for(int i=0;i<n;i++)
    cout<<a[i]<<"  ";
    cout<<endl;
    
    return 0;

}

2.选择排序

int main(){
    int a[250];
    int n;
    cin>>n;
    for(int i=0;i<n;i++)
    cin>>a[i];
    
    //选择排序
    //从第一个数开始寻找,先定义一个变量标记到第一个数的下面,两个两个比较,
    //比较到最后找出最小或最大的数,然后变量一直标记最大或者最小的数,之后
    //把第一个数给第最大的数交换位置,然后从第二个数开始找找出第二大的数,直至最后
    //本质:找出最小的或最大的数,与第一个开始交换
    for(int i=0;i<n;i++){
        int dex=i;
        for(int j=i+1;j<n;j++){
            if(a[j]<a[dex])
            dex=j;//dex永远指向最小的元素
        }
        swap(a[i],a[dex]);
    }
    
    for(int i=0;i<n;i++)
    {
        int dex=i;
        for(int j=i+1;j<n;j++){
            if(a[dex]<a[j])
            dex=j;
        }
        swap(a[i],a[dex]);
    }
    
    
    for(int i=0;i<n;i++)
    cout<<a[i]<<"  ";
    cout<<endl;
    return 0;

}

3.插入排序

int main(){
    int a[250];
    int n;
    cin>>n;
    for(int i=0;i<n;i++)
    cin>>a[i];

    //插入排序
    //插入排序就是一个数组,从里面一个一个读,像起扑克牌一样一个一个起,起一张然后插入到
    //你手中的牌中,从第二张开始。如果比第一张大则放到第一张的后面,然后第3张从第二张判断,
    //如果比第二章大则放在后面,如果小则第二张往后放一个位置,然后判断与第一张的大小如果比
    //第一张大则第二张就放你起的牌,如果没有第一张大,则第一张往后放一个位置,起的这张牌就
    //放在第一个位置,这就是插叙函数,每次都从你手中最大的(或者最小)的开始判断,然后让这
    //张你刚起的牌与你手中的牌中找到比他小的,然后让你手中比他大的往后移动一个位置,把这张牌插入进去
    //本质:就是两个数组,一个无序,然后你手中的有序数组,每次从无序数组中拿出来一个数
    //插入你手中的有序数组中,将他排序到你的数组中。
    for(int i=1;i<n;i++){
        int key=a[i];
        int j=i-1;
        while(j>=0&&key<a[j]){
            a[j+1]=a[j];
            j--;
        }
        a[j+1]=key;
    }
    
    for(int i=0;i<n;i++)
    cout<<a[i]<<"  ";
    cout<<endl;
    return 0;
}

4.重点 难点快速排序

int a[101],n;
//让我来试着解释一下这个快速排列,这个快排的本质就是,先找一个基数,然后比他大的放到这个数后面
//比这个数小的放到这个数的前面,然后前面的部分继续找一个基数,以此类推,然后找后面的部分,这个
//依次类推的过程是一个递归的过程(!这是一个重难点) 然后是如何进行找基数分类也是一个重点,
下面我先来举个例子给大家
6 1 2 7 9 4 5 10 8
我们为了方便就直接把这个数组的第一个数作为基数
然后标记一下,假设现在有连个士兵,一个是(士兵i)一个是(士兵j)
士兵i站在最左边,士兵j站在最右边 然后让士兵j开始向左移动找出比基数小的数,
然后士兵i再移动(为什么士兵j先移动这个很重要,需要大家思考)找出比基数大的数
之后交换这连个数的位置,5和7换位置
然后士兵j继续移动,直到i和j碰面,交换基数和当前i的位置
这是第一次排序分类,这时基数前的数都比基数小,基数后的数都比基数大
然后递归进入前面的部分和后面的部分传递参数值,继续按照这个方法排序


先给大家讲一下为什么士兵j必须先走,
举一个例子,
6  1 2 9 7
因为如果士兵i先走的话, 会停到9这个位置,然后士兵j在走直接就与i相遇了,然后交换i和基数的值,然后9被分配到了6的前面,
这是不对的!!!
所以说问题就存在与我们从哪边开始,如果从基数边开始这个士兵i就会停到比基数大的位置,然后与j相遇后和基数交换位置
这时这个士兵i占位置上的数确大于基数所以
从哪里开始查找很重要,一般是从基数的对面查找

然后递归的运用,有点难理解,就是你可以一次一次调用
但是每次调用都有两个门,这两个门都是会执行的
 

void quicksort(int left,int right){
    int i,j,t,temp;
    if(left>right)
    return ;
    temp=a[left];
    i=left;
    j=right;
    while(i!=j){
        while(a[j]>=temp&&i<j)
        j--;
        while(a[i]<=temp&&i<j)
        i++;
        if(i<j){
            t=a[i];
            a[i]=a[j];
            a[j]=t;
        }
    }
    a[left]=a[i];
    a[i]=temp;
    
    quicksort(left,i-1);
    quicksort(i+1,right);
}
int main()
{
    int i,j,t;
    scanf("%d",&n);
    for(i=1;i<=n;i++)
    scanf("%d",&a[i]);
    quicksort(1,n);
    
    for(i=1;i<=n;i++)
    printf("%d",a[i]);
    getchar();getchar();
    return 0;
}

//也可以直接从c++库中调用 sort(1,n);是1到n个数
bool cmp(int n,int m){
    return n<m;//m>n是升序,m<n是降序
                //c++库里的快排函数升序排列所以
                //n<m的意思是从n到m
                //m<n的意思是从m到n
}

int  main(){
    int a[105];
    int n;
    cin>>n;
    for(int i=0;i<n;i++)
    cin>>a[i];
    sort(a,a+n,cmp);
    for(int i=0;i<n;i++)
    cout<<a[i];
    return 0;
}*/


这些都是我第一天上课所学,加上我对算法的理解写出来的,一起成长吧


猜你喜欢

转载自blog.csdn.net/weixin_42627450/article/details/80991110
今日推荐