数据结构复习-排序

内部排序

排序期间,元素全部存放在内存中的排序。并非所有内部排序都要基于比较操作,基数排序不基于比较。

关注时间复杂度、空间复杂度、稳定性

插入排序

  • 直接插入排序
  • 折半插入排序
  • 希尔排序(缩小增量排序)

取一个递减数组 从中取步长 将需要排序的数组按步长分为子数组 进行插入排序 达到基本有序的状态 某些步长数组的平均时间复杂度可以达到1.3次方

交换排序

  • 冒泡排序
  • 快速排序

选择排序

  • 简单选择排序
  • 堆排序

注意建堆的两种方法,一个个插入的nlogn、满足完全二叉树后从根到底的perdown操作,复杂度为n

交换排序

  • 冒泡排序
  • 快速排序

归并排序

基数排序

按基数r(进制)和位数进行分配和收集过程的排序,可以从低位到高位,也可以从高位到低位 桶排序的思想和其近似 空间上需要r个“桶”,存放分配的元素 而分配过程的稳定性保证了排序结果的稳定性 分配和收集的过程不基于比较 时间复杂度为最长位数*r

 

外部排序

排序期间元素无法全部同时存放在内存中,必须得在排序的过程中根据要求不断在内外存中间移动的排序。

 

void bubbleSort(int *arr,int l,int r)
{
    for (int i=l; i<r; i++) {
        for (int j=i+1; j<r; j++) {
            if (arr[i] > arr[j]) {
                int t = arr[i];
                arr[i] = arr[j];
                arr[j] = t;
            }
        }
    }
}

int partition(int *arr,int l,int r)
{
    int x = arr[l];
    r--;
    while (l<r)
    {
        while (arr[r]>=x && r>l)r--;
        arr[l]=arr[r];
        while (arr[l]<=x && r>l)l++;
        arr[r]=arr[l];
    }
    arr[l]=x;
    return l;
}

void quickSort(int *arr,int l,int r)
{
    if (l >= r) {
        return;
    }
    int pos = partition(arr, l, r);
    quickSort(arr, l, pos);
    quickSort(arr, pos+1, r);
}


int temp[N];
void merge(int *arr,int l, int r)
{
    int mid = (l+r)>>1;
    int p=l;
    int q=mid;
    int len=0;
    while (p<mid && q<r)
    {
        if (arr[p]>arr[q])
        {
            temp[l+len]=arr[q++];
            len++;
        }
        else
        {
            temp[l+len]=arr[p++];
            len++;
        }
    }
    while (p<mid)
    {
        temp[l+len]=arr[p++];
        len++;
    }
    while (q<r)
    {
        temp[l+len]=arr[q++];
        len++;
    }
    for (int i = l; i < r; ++i) {
        arr[i] = temp[i];
    }
}

void mergeSort(int *arr,int l, int r)
{
    if (r-1==l)
        return;
    mergeSort(arr, l, (l+r)>>1);
    mergeSort(arr, (l+r)>>1, r);
    merge(arr,l,r);
}

class Heap {
public:
    int heap[N];
    int size;
    void insert(int x)
    {
        size++;
        int now = size;
        for (; now/2 > 0; now/=2) {
            if (heap[now/2] > x) {
                heap[now] = heap[now/2];
            } else {
                break;
            }
        }
        heap[now] = x;
    }
    int getMin()
    {
        return heap[1];
    }
    void deleteMin()
    {
        heap[1] = heap[size];
        heap[size] = 0;
        size--;
        percDown(1);
    }
    void buildHeap()
    {
        //从有孩子结点的最大坐标往上,进行下滤操作
        for (int i=size/2;i>0;i--)
        {
            percDown(i);
        }
    }
private:
    /**
     * 整理子堆 使其符合堆的性质 以下实现以小根堆为例
     * @param p 子堆的根节点
     */
    void percDown(int p)
    {
        int child;
        int x = heap[p];
        for (int parent = p; parent*2 <= size; parent = child) {
            if (heap[parent*2] < heap[parent*2+1] || !heap[parent*2+1]) {
                child = parent * 2;
            } else {
                child = parent * 2 + 1;
            }
            if (heap[child] < heap[parent]) {
                heap[parent] = heap[child];
                heap[child] = x;
            } else {
                break;
            }
        }
    }
};

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值