首页 > 其他分享 >排序

排序

时间:2022-12-31 08:44:37浏览次数:165  
标签:int 复杂度 high void low 排序 节点

快速排序

  • 平均时间复杂度O(nlogn),最坏时间复杂度O(n^2),时间开销与待排数组初始状态有关,当待排数组有序时,效率最低。
  • 空间复杂度最坏O(n),最好O(logn)
int partition(int a[], int low, int high){
    int pivot = a[low];         //表中第一个元素作为枢轴进行划分
    int i = low, j = high;
    while(i < j){
        while(i < j && a[j] >= pivot)
            --j;
        a[i] = a[j];    //比枢轴小的元素移到左边       
        while(i < j && a[i] <= pivot)
            ++i;
        a[j] = a[i];    //比枢轴大的元素移到右边
    }
    a[i] = pivot;       //枢轴元素存放位置
    return i;           //返回划分的枢轴位置
}

void quickSort(int a[], int low, int high){
    if(low < high){        //递归条件
        int pos = partition(a, low, high);      //划分左右子表
        quickSort(a, low, pos-1);           //左子表递归
        quickSort(a, pos+1, high);          //右子表递归
    }
}

归并排序

  • 时间复杂度为O(nlogn),与初始状态无关
  • 空间复杂度O(n),需要辅助数组b
//a[low...mid],a[mid+1...high]为有序的两个子表,将其归并成a[low...high]有序的表
void merge(int a[], int low, int mid, int high){
    int i, j, k;
    int *b = (int *)malloc(sizeof(int) * (high-low+1));  //辅助数组
    i = low, j = mid+1, k = 0;
    while(i <= mid && j <= high){   //较小者加入a
        if(a[i] <= a[j]){
            b[k++] = a[i++];
        }
        else{
            b[k++] = a[j++];
        }
    }
    while(i <= mid){        //前表有剩余,直接加入归并表
        b[k++] = a[i++];
    }
    while(j <= high){       //后表有剩余,直接加入归并表
        b[k++] = a[j++];
    }

    //b中存放归并好的表,写回a中即可,注意a中数据位置要相对low偏移    
    for(i = 0; i < k; ++i){
        a[i+low] = b[i];
    }
}

void mergeSort(int a[], int low, int high){
    if(low < high){
        int mid = (low + high) / 2;         //中间划分两个子表
        mergeSort(a, low, mid);             //左子表递归排序
        mergeSort(a, mid + 1, high);    //右子表递归排序
        merge(a, low, mid, high);           //归并左右子表
    }
}

堆排序

  • 时间复杂度O(nlogn),与初始状态无关
  • 空间复杂度O(1)
//k为待调整子树的根节点
void heapAdjust(int a[], int k, int n){
    int i;
    a[0] = a[k];    //a[0]暂存子树根节点
    for(i = 2*k; i <= n; i*=2){
        if(i+1 <= n && a[i+1]>a[i])    //i指向左右孩子key较大者(右孩子存在的前提下)
            i++;
        if(a[0] >= a[i])    //根>=左右孩子,则调整完成
            break;
        else{
            a[k] = a[i];    //左右孩子较大者上移到父节点位置
            k = i;          //根节点尝试"下坠",继续向下筛选
        }
    }
    a[k] = a[0];    //根节点最终应该存放的位置k
}

//建立大根堆
void buildMaxHeap(int a[], int n){
    int i;
    for(i = n/2; i >= 1; --i){      //从第一个非叶子节点a[n/2]开始调整堆
        heapAdjust(a, i, n);
    }
}

//堆排序:①建堆;②堆顶堆底元素交换,调整堆
void heapSort(int a[], int n){
    buildMaxHeap(a, n);
    int i, temp;
    for(i = n; i > 1; --i){     //n-1趟调整建堆过程
        //堆顶元素和堆底元素交换,堆底为有序
        //swap(a[i], a[1]);
        temp = a[i];
        a[i] = a[1];
        a[1] = temp;
        heapAdjust(a, 1, i-1);      //调整,把剩余的i-1个元素整理成堆
    }
}

标签:int,复杂度,high,void,low,排序,节点
From: https://www.cnblogs.com/dctwan/p/17016200.html

相关文章

  • BM5 合并k个已排序的链表
    题目描述合并k个升序的链表并将结果作为一个升序的链表返回其头节点。思路分析之前已经完成了两条有序链表的排序,那么对于任意条有序链表的合并我们都可以借助之前的......
  • 【归并排序】【链表】LeetCode 148. 排序链表
    题目链接148.排序链表思想分割cut环节:找到当前链表中点,并从中点将链表断开(以便在下次递归cut时,链表片段拥有正确边界)我们使用fast,slow快慢双指针法,奇数个......
  • 有向图的拓扑排序——DFS
    在有向图的拓扑排序——BFS这篇文章中,介绍了有向图的拓扑排序的定义以及使用广度优先搜索(BFS)对有向图进行拓扑排序的方法,这里再介绍另一种方法:深度优先搜索(DFS)。算法考虑......
  • 归并排序 以及衍生作品 逆序数统计
     首先介绍归并排序: 国际惯例,我引入比喻,各位看官随意听听抽象代师。 我将归并排序比喻成“斗兽场排序”,什么意思呢?就是将原来的一个数组一分为二,将数字比喻斗士,A组B......
  • 64. 学生成绩排序
    64.学生成绩排序    大家参加了期末考试,成绩出来后老师要对n个学生进行成绩汇总和排序。要求程序按成绩降序进行排序。在排序过程中对于成绩相同的学生,要按照......
  • Java 自定义Excel数据排序
    通常,我们可以在Excel中对指定列数据执行升序或者降序排序,排序时可依据单元格中的数值、单元格颜色、字体颜色或图标等。在需要自定义排序情况下,我们也可以自行根据排序需要......
  • H5 拖动排序 美食排行榜
    尝试写一下拖动元素进行排序,真是想到什么去写什么......
  • 【LeeCode】34. 在排序数组中查找元素的第一个和最后一个位置
    【题目描述】给你一个按照非递减顺序排列的整数数组 ​​nums​​​,和一个目标值 ​​target​​。请你找出给定目标值在数组中的开始位置和结束位置。如果数组中不存在目......
  • 【LeetCode数组#1二分查找】二分查找、搜索插入、在排序数组中查找元素的第一个和最后
    二分查找题目力扣704题目链接给定一个n个元素有序的(升序)整型数组nums和一个目标值target,写一个函数搜索nums中的target,如果目标值存在返回下标,否则返回-1。......
  • 输出结果排序 sort命令
    (4条消息)shell中sort命令详解_绮梦寒宵的博客-CSDN博客_shellsortshellsort命令-Kimbo-博客园(cnblogs.com)du-h|sort-rh>/opt/fossx/data/wyyshell/anale......