排序

1. 冒泡排序

从左到右不断交换相邻逆序的元素,在一轮循环之后,最大的元素放在最右边。
一轮循环如果没有进行交换,说明已经有序,可以直接退出。
时间复杂度: 最好O(n);最坏O(n2 );平均O(n2 )
空间复杂度:O(1)
稳定。

2. 选择排序

选择最小的元素与第一个元素互换位置。再从剩下的数组中选择最小的元素,与第二个元素交换。不断重复。
时间复杂度:O(n2 )
空间复杂度:O(1)
不稳定。

3. 插入排序

将第一个元素视为有序。对于无序数据,将其与有序序列从后向前扫描,找到左侧相应位置插入。
时间复杂度: 最好O(n);最坏O(n2 );平均O(n2 )
空间复杂度:O(1)
稳定。

4. 希尔排序

在插入排序上的改进。希尔增量:{n/2,n/2/2…1}。将序列分成 增量 个组,对每组进行插入排序。然后选择下一个增量,分组进行插入排序。直到增量为1 。
对于插入排序,每一次交换使得逆序-1;而希尔排序每次逆序->1;因为比插入排序高效。
时间复杂度:最好O(n);最坏O(n2 );平均O(n1.3 )
空间复杂度:O(1)。
不稳定

5. 归并排序 *

分治和递归思想。
将输入序列对半分;对两个子序列分别采用归并排序;将两个排序号的子序列合并成一个最终的序列。
时间复杂度:O(nlog n)
空间复杂度:O(n)。
稳定。
归并排序思想延伸:小和问题,逆序对问题。

void merge(vector<int> &arr,int left,int mid,int right)
{
    int n1 = mid-left+1;
    int n2 = right-mid;
    int* L = new int[n1];
    int* R = new int[n2];
    for(int i=0;i<n1;i++)
    {
        L[i]=arr[left+i];
    }
    for(int i=0;i<n2;i++)
    {
        R[i]=arr[mid+1+i];
    }
    for(int i=0,j=0,p = left; p<=right; p++)
    {
        if (i>=n1)
        {
            arr[p]=R[j++];
        }
        else if (j>=n2)
        {
            arr[p]=L[i++];
        }
        else if(L[i] <= R[j])
        {
            arr[p] =L[i++];
        }
        else{
            arr[p]=R[j++];
        }
    }
    delete []L;
    delete []R;
}
void merge_sort(vector<int> &arr,int left,int right)
{
    if(left<right)
    {
        int p = (left+right)/2;
        merge_sort(arr, left, p);
        merge_sort(arr, p+1, right);
        merge(arr,left,p,right);
    }
    return ;
}

6. 快速排序 *

通过一个切分元素对数组进行切分,将比基准小的元素放左边,大的放右边。用递归将两侧数列分别进行快排。
切分:去a[1]作为切分元素,两个指针,一个从左向右扫描直到找到一个大于等于它的元素,一个从右向左扫描找到一个比他小的元素,交换。不断进行着过程,直到两个指针相遇,将切分元素与右指针元素交换。
时间复杂度:O(nlog n),最差O(n2 )
空间复杂度:O(log n)。
不稳定

void quicksort(int left,int right, vector<int> & arr)
{
    if(left<right)
    {
        int i=left;
        int j=right;
        int base = arr[left];
        while (i<j) {
            while(i<j && arr[j]>=base) j--;
            if(i<j) arr[i++]=arr[j];
            while(i<j && arr[i]<=base) i++;
            if(i<j) arr[j--]=arr[i];
        }
        arr[i]=base;
        quicksort(left, i-1, arr);
        quicksort(i+1, right, arr);
    }
}

7. 堆排序*

将初始化序列构建成大顶堆;将堆顶元素与最后一个元素交换;交换后进行下沉操作调整堆为大顶堆;不断操作上述过程,直到完成。
大顶堆:父节点比子节点大。
调整堆:上浮和下沉。
时间复杂度:O(nlog n)
空间复杂度:O(1)。
不稳定

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值