面试笔试中的排序问题

快速排序:

#include<iostream>
#include <stdio.h>
#define N 100

using namespace std;
int a[N];

void quicksort(int l,int r)
{
    int x = l,y = r;
    int num = a[x];     //最左边的数字为基准
    while(x < y)
    {
        while(x < y && a[y] >= num) y--;    //从右往左选一个比基准小的数
        a[x] = a[y];
        while(x < y && a[x] <= num) x++;    //从左往右选一个比基准大的数
        a[y] = a[x];
    }
    a[x] = num;
    if(l < x)     quicksort(l,x);
    if(x < r)     quicksort(x+1,r);
}

int main()
{
    int n;
    while(scanf("%d",&n) != EOF)
    {
        int i;
        for(i = 0; i < n; i++)  scanf("%d",&a[i]);
        quicksort(0,n-1);
        for(i = 0; i < n; i++)  printf("%d ",a[i]);
        printf("\n");
    }
    return 0;
}



希尔排序:
 对于每一趟排序,选取一个增量,将原数组分成若干组,对每一组进行插入排序,重复上述步骤,最后一次增量为1。
 shell排序方法实质上是一种分组插入方法 ,它的时间复杂度的下界是n*logn。

堆排序:
堆分为大根堆和小根堆,是完全二叉树。
下面以大根堆为例解释算法,大根堆的每个节点的左右儿子节点都不大于它。假设有n个元素,存在a[1-n]。
1、建堆,从最后一个非叶子节点开始调整堆,直到调整到根节点,建堆完成之后a[1]最大,a[i]>=a[2*i]&&a[i]>=a[2*i+1]。
2、把a[1]和a[n]交换,a[1- (n-1)]是乱序的,之后是有序的
3、调整堆,使其满足堆的性质(即1)
4、重复上述操作

时间复杂度分析:建堆时间复杂度是O(n),从根节点开始的对调整时间复杂度是logn,一共调整n次,故时间复杂度为nlogn。

#include<stdio.h>
#define N 100
int a[N];

void swap(int &a,int &b)
{
    int t = a;
    a = b;
    b = t;
}

void adjustheap(int i,int size)
{
    int id = i;
    if(2*i <= size && a[2*i] > a[id])   id = 2*i;
    if(2*i+1 <= size && a[2*i+1] > a[id]) id = 2*i+1;
    if(i != id){
        swap(a[i],a[id]);
        adjustheap(id,size);
    }
}

void buildheap(int size)//从小到大排序,所以要建最大堆
{
    for(int i = size/2; i >= 1; i--)
        adjustheap(i,size);
}

void heapsort(int size)
{
    buildheap(size);//建堆的时间复杂度为 O(n),这个好好考虑下,挺有趣的
    for(int i = size; i > 1; i--)//这里的时间复杂度是O(nlogn)
    {
        swap(a[1],a[i]);
        adjustheap(1,i-1);
    }
}

int main()
{
    int n;
    while(scanf("%d",&n) != EOF)
    {
        for(int i = 1; i <= n; i++) scanf("%d",&a[i]);
        heapsort(n);
        for(int i = 1; i <= n; i++) printf("%d ",a[i]);
        printf("\n");
    }
    return 0;
}
/*
5
10 2 3 4 1
*/


归并排序:

二分的思想,递归到底层,排序,在合并

#include<iostream>
#include<stdio.h>
#define N 100
using namespace std;
int a[N],b[N];
void merge_sort(int l,int r)//从小到大排序
{

    int mid = (l+r)/2;
    if(l < mid) merge_sort(l,mid);
    if(mid+1 < r)   merge_sort(mid+1,r);

    int x = l,y = mid + 1;
    int j = l;
    while(x <= mid || y <= r)
    {
        if(x > mid)
        {
            while(y <= r)
                b[j++] = a[y++];
            break;
        }
        if(y > r)
        {
            while(x <= mid)
                b[j++] = a[x++];
            break;
        }
        if(a[x] < a[y]) b[j++] = a[x++];
        else b[j++] = a[y++];
    }

    for(int i = l; i <= r; i++)
        a[i] = b[i];
}
int main()
{
    int n;
    while(scanf("%d",&n) != EOF)
    {
        int i;
        for(i = 0; i < n; i++)
            scanf("%d",&a[i]);
        merge_sort(0,n-1);
        for(i = 0; i < n; i++)
            printf("%d ",a[i]);
        printf("\n");
    }

    return 0;
}




  



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值