面试排序整理

为了防止面试再次翻车,总结一下排序,并给出代码

快排

描述:
1.首先设定一个分界值,通过这个分界值将数组的值分到两边
2.将大于或等于分界值的数,放到数组分界值的右边。将小于或等于分界值的数,放到数组的左边。
3.对于分界值左边的数据,继续进行分界流程,然后对于分界值右边的数据,同样可以继续进程分界流程。
4.上述过程可以写成递归实现,先递归实现左侧部分排序,然后实现右侧部分排序。然后整个排序过程就完成了。
代码

#include<iostream>
#include<string.h>
#include<stdio.h>
#include<algorithm>
using namespace std;
void QuickSort(int array[],int start,int last)
{
    int i=start;
    //底端指针
    int j=last;
    //高端指针
    int temp = array[i];
    //二分指针,把temp作为分割整个区间底依据
    if (i<j)
    {
        while(i<j)
        {
            while (i<j && array[j]>=temp)
                j--;
            //j找到右边第一个比a[i]小的数
            if (i<j)
            {
                array[i] = array[j];
                i++;
            }
            //把这个值放到低端指针上
            //这个时候array[j]的值已经移动了
            //这个时候应该从找到一个比temp大的值放到array[j]上
            while (i<j && temp > array[i])
                i++;
            //然后从低端指针找到第一个比二分指针大的值
            if (i<j)
            {
                array[j]=array[i];
                //把低端指针的值放到高端指针上
                //这个时候array[i]上的值已经移动
                //下次循环,又会找到一个比temp小的值放到array[i]上
                j--;
            }
        }
        array[i]=temp;
        //这样排序保证了i位置一定是正确的
        //左排序
        QuickSort(array,start,i-1);
        //右排序
        QuickSort(array,i+1,last);
    }
}
int main(){
    int a[100];
    int n;
    while(~scanf("%d",&n)){
        for (int i=1;i<=n;i++){
            scanf("%d",&a[i]);
        }
        QuickSort(a,1,n);
        for (int i=1;i<=n;i++){
            printf("%d ",a[i]);
        }
        cout<<endl;
    }
    return 0;
}

冒泡排序

冒泡排序相当于就是每次把最小的值(或者最大的值) 通过连续的和相邻的进行比较,把大的值往右边放,保证右边一定是有一部分是已经排序好的。
最坏时间复杂度是O(n^2)
最优时间复杂度是O(n)
原因,我们如果发现整个序列都是有序的,没有一个位置需要进行大小的交换,那么这个序列一定是已经排好序的,比如1 2 3 4 5 这类,其实只需要O(N)就排序完成了

#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
void Pop_sort(int array[],int len){
    int didswap;
    for (int i=1;i<=len;i++){
        didswap=0;
        //这一步做了判断
        for (int j=1;j<=len-i;j++){
            if (array[j+1]<array[j]){
                swap(array[j+1],array[j]);
                didswap=1;
            }
        }
        if (didswap==0)
            return ;
    }
}
int main(){
    int a[10];
    int n;
    while(~scanf("%d",&n)){
        for (int i=1;i<=n;i++){
            scanf("%d",&a[i]);
        }
        Pop_sort(a,n);
        for (int i=1;i<=n;i++){
            cout<<a[i]<<" ";
        }
        cout<<endl;
    }
    return 0;
}

选择排序

这个排序其实很简单,首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
最差时间复杂度是O(n^2)
最好时间复杂度还是(n^2)
因为循环每次都要从左往右扫去找第k小的数,放在第K个位置,无法进行优化
代码

#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
void SelectSort(int array[],int len){
    for (int i=1;i<=len;i++){
        int minIndex=i;
        for (int j=i+1;j<=len;j++){
            if (array[j]<array[minIndex]){
                swap(array[j],array[minIndex]);
            }
        }
    }
}
int main(){
    int a[10];
    int n;
    while(~scanf("%d",&n)){
        for (int i=1;i<=n;i++){
            scanf("%d",&a[i]);
        }
        SelectSort(a,n);
        for (int i=1;i<=n;i++){
            cout<<a[i]<<" ";
        }
        cout<<endl;
    }
    return 0;
}

归并排序

归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并得到完全有序的序列;
最坏复杂度:O(logn)
最优复杂度:O(logn)
由于本排序每次都把一个区间分成两端,类似于二分,在分区的操作是O(logn),加上遍历到底的交换,总复杂度是O(n),复杂度是O(n*logn),并且复杂度稳定。

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int temp[100];
void Merge(int a[],int left,int right){
    int i=left;
    int mid=(left+right)/2;
    int j=mid+1;
    int n=0;
    int lenth=right-left;
    while(i<=mid && j<=right){
         if (a[i]>a[j]){
             temp[n++]=a[j];
             j++;
         }else {
             temp[n++]=a[i];
             i++;
         }
         cout<<"ss"<<endl;
    }
    while(i<=mid){
        temp[n++]=a[i++];
    }
    while(j<=right){
        temp[n++]=a[j++];
    }
    for (int k=0;k<=lenth;k++){
        a[left+k]=temp[k];
    }
}
void merge_sort(int a[],int left,int right){
    int mid=(left+right)/2;
    if (left<right){
        //这里注意,是先要把数字分治到底部
        merge_sort(a,left,mid);
        merge_sort(a,mid+1,right);
        Merge(a,left,right);
    }
}
int main(){
    int a[10];
    int n;
    while(~scanf("%d",&n)){
        for (int i=0;i<n;i++){
            scanf("%d",&a[i]);
        }
        cout<<n<<endl;
        merge_sort(a,0,n-1);
        for (int i=0;i<n;i++){
            cout<<a[i]<<" ";
        }
        cout<<endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值