• 排序


    1. 冒泡排序

    时间复杂度:最好O(n),平均和最坏情况O(n2)
    空间复杂度:O(1)
    稳定排序
    原理:从第一个元素开始,依次比较相邻两个元素,如果前者比后者大,那么就交换者两个元素,然后处理下一组,依次类推,直到排序完成。
    实现:

    1. publicvoid bubbleSort(int[] arr){
    2. boolean isChanged =false;
    3. for(int i =0; i < arr.length -1; i++){
    4. isChanged =false;
    5. for(int j =0; j < arr.length -1- i; j++){
    6. if(arr[j]> arr[j+1]){
    7. int tmp = arr[j];
    8. arr[j]= arr[j+1];
    9. arr[j+1]= tmp;
    10. isChanged =true;
    11. }
    12. }
    13. if(!isChanged)break;//本次没有发生交换,说明已经排好序了
    14. }
    15. }
    2. 选择排序

    时间复杂度:最好、平均和最坏情况O(n2)
    空间复杂度:O(1)
    不是稳定排序
    原理:从第一个元素开始,每次逐一扫描选择未排序部分的最小值,排在已排序部分后面,然后从下一个位置开始,继续进行相同的操作,直到排序完成。
    实现:

    1. /**
    2. * 选择排序
    3. */
    4. publicstaticvoid sort(int[] arr){
    5. //判断arr是否为空
    6. if(arr ==null)return;
    7. int minIndex;
    8. for(int i =0; i < arr.length -1; i++){
    9. minIndex = i;
    10. for(int j = i +1; j < arr.length; j++){
    11. if(arr[j]< arr[minIndex]){
    12. minIndex = j;
    13. }
    14. }
    15. if(minIndex != i){//最小值不是当前值,需要交换
    16. int tmp = arr[i];
    17. arr[i]= arr[minIndex];
    18. arr[minIndex]= tmp;
    19. }
    20. }
    21. }
    3. 快速排序

    时间复杂度:最好、平均情况O(nlogn),最坏情况O(n2)
    空间复杂度:平均情况O(logn),最坏情况O(n)
    不是稳定排序
    原理:每次选择一个数,将数组按照这个数分成左右两个部分,右边的比它大,左边的比他小然后对左右两部分分别进行同样的操作,直到数组排序完成
    实现:

    1. publicstaticvoid sort(int[] arr){
    2. sortCore(arr,0, arr.length -1);
    3. }
    4. /**
    5. * @param arr 排序的数组
    6. * @param start 开始位置
    7. * @param end 结束位置
    8. */
    9. privatestaticvoid sortCore(int[] arr,int start,intend){
    10. int poiv = partion(arr, start,end);
    11. if(poiv > start){
    12. sortCore(arr, start, poiv -1);
    13. }
    14. if(poiv >= start && poiv <end){
    15. sortCore(arr, poiv +1,end);
    16. }
    17. }
    18. privatestaticint partion(int[] arr,int start,intend){
    19. int tmp = arr[start];
    20. while(start <end){
    21. while(start <end&& arr[end]>= tmp)end--;
    22. if(start <end){
    23. arr[start]= arr[end];
    24. }
    25. while(start <end&& arr[start]< tmp) start++;
    26. if(start <end){
    27. arr[end]= arr[start];
    28. }
    29. }
    30. arr[start]= tmp;
    31. return start;
    32. }
    4. 归并排序

    时间复杂度:最好、平均和最坏情况O(nlogn)
    空间复杂度:O(n)
    稳定排序
    原理:首选将要排序的数组对半分,对各自部分进行排序。每部分继续进行相同的操作,直至最底层。然后合并两个相邻的部分,直到所有元素都排序完成
    实现:

    1. publicstaticvoid sort(int[] arr){
    2. //创建数组,辅助排序
    3. int[] copy =newint[arr.length];
    4. sortCore(arr, copy,0, arr.length -1);
    5. }
    6. /**
    7. * 归并排序核心实现
    8. * @param arr 排序的数组
    9. * @param copy 辅助空间
    10. * @param start 开始位置
    11. * @param end 结束位置
    12. * @param offset 索引相对于原数组的偏移
    13. */
    14. privatestaticvoid sortCore(int[] arr,int[] copy,int start,intend){
    15. if(start ==end){
    16. copy[start]= arr[start];
    17. return;}
    18. int mid =(end- start)/2+ start;
    19. //分成两部分,递归
    20. sortCore(arr, copy, start, mid);
    21. sortCore(arr, copy, mid +1,end);
    22. //合并两个部分,将合并结果存入
    23. int forward = mid;
    24. int behand =end;
    25. intlast=end;
    26. while(forward >= start && behand > mid){
    27. if(copy[forward]> copy[behand]){
    28. arr[last--]= copy[forward --];
    29. }else{
    30. arr[last--]= copy[behand --];
    31. }
    32. }
    33. while(forward >= start){
    34. arr[last--]= copy[forward --];
    35. }
    36. while(behand > mid){
    37. arr[last--]= copy[behand --];
    38. }
    39. //拷贝到copy数组
    40. for(int i = start; i <=end; i++){
    41. copy[i]= arr[i];
    42. }
    43. }
    5. 插入排序

    时间复杂度:最好O(n),平均和最外情况O(n2)
    空间复杂度:O(1)
    稳定排序
    原理:从数组第一个元素开始,依次比较前面已经排序的部分,插入合适的位置,前面排序部分比当前值大的部分向后移动一个。
    实现:

    1. publicstaticvoid sort(int[] arr){
    2. int tmp;//每次排序,存储当前的值
    3. for(int i =1; i < arr.length; i++){
    4. tmp = arr[i];//保存当前值
    5. int j;
    6. for(j = i; j >= fromIndex && tmp < arr[j -1]; j --){//遇到比当前值大的元素,则元素后移一位
    7. arr[j]= arr[j-1];
    8. }
    9. arr[j]= tmp;|
    10. }
    11. }
    6. 希尔排序

    时间复杂度:平均情况O(n1.25)
    空间复杂度:O(1)
    不是稳定排序
    原理:将无序数组分割为若干个子序列,子序列不是逐段分割的,而是相隔特定的增量的子序列,对各个子序列进行插入排序;然后再选择一个更小的增量,再将数组分割为多个子序列进行排序……最后选择增量为1,即使用直接插入排序,使最终数组成为有序。
    实现:

    1. publicstaticvoid sort(int[] arr){
    2. //checkRange(arr.length, fromIndex, toIndex);
    3. int adder = arr.length /2;//增量
    4. while(adder >0){
    5. //从adder开始,每次排序均与前面的adder(当adder是1时就是插入排序)处的元素比较
    6. for(int i = adder ; i < arr.length; i++){
    7. int j;
    8. int tmp = arr[i];
    9. for(j = i; j >= adder && tmp < arr[j - adder]; j = j - adder){
    10. arr[j]= arr[j - adder];
    11. }
    12. arr[j]= tmp;
    13. }
    14. adder /=2;
    15. }
    16. }
    7. 堆排序

    时间复杂度:最好、平均和最坏情况均为O(nlogn)
    空间复杂度:O(1)
    不是稳定排序
    原理:建立初始堆,从最后一个非叶结点开始,往前遍历,判断以该节点的开始的堆是否是符合,不符合则调整需要建立大顶堆,每次将子节点中较大地一个数往上移动,直到叶结点(堆:结点n的父节点为(n-1)/ 2,其左右子节点为2n+1和2n+2大根堆为根结点的值大于等于左右子结点的值),然后依次将堆顶值与为排序的最后一个值交换,然后调整前面的值为大顶堆,每次将最大的值排好序。
    实现:

    1. /**
    2. * 堆排序
    3. */
    4. publicstaticvoid sort(int[] arr){
    5. //建立初始堆,从最后一个非叶结点开始,往前遍历,判断以该节点的开始的堆是否是符合,不符合则调整
    6. //需要建立大顶堆,每次将子节点中较大地一个数往上移动,直到叶结点
    7. //节点n的父节点为(n-1)/ 2,其左右子节点为2*n+1和2*n+2
    8. //大根堆为根结点的值大于等于左右子结点的值
    9. for(int i =(arr.length -1-1)/2; i >=0; i--){
    10. adjustHeap(arr, i, arr.length-1);
    11. }
    12. //依次将堆顶值与为排序的最后一个值交换,然后调整前面的值为大顶堆
    13. for(int i = arr.length -1; i >=1; i--){
    14. //交换
    15. arr[0]^= arr[i];
    16. arr[i]^= arr[0];
    17. arr[0]^= arr[i];
    18. //调整
    19. adjustHeap(arr,0, i -1);
    20. }
    21. }
    22. /**
    23. * 调整为大顶堆
    24. * @param arr
    25. * @param i 以i为堆的堆顶
    26. * @param last 堆顶的最后一个结点的索引
    27. */
    28. privatestaticvoid adjustHeap(int[] arr,int i,intlast){
    29. //建立以i结点为根的堆,判断子结点是否大于该节点,并将较大地值拷贝,然后继续判断
    30. int tmp = arr[i];
    31. for(int j = i *2; j <=last; j *=2){
    32. //获得左右子树中较大的一个数的下标
    33. if(j <last&& arr[j]< arr[j+1]) j++;//存在右子结点且右子结点较大
    34. if(tmp >= arr[j])break;//根结点比较大,则完成
    35. //将较大的值作为根
    36. arr[i]= arr[j];
    37. i = j;//继续往下判断,j的位置的值是最初的根结点
    38. }
    39. arr[i]= tmp;//最后确定的位置,没有子结点或者比子结点的值大;
    40. }





  • 相关阅读:
    【转帖】android线程知识整理
    Andorid开发笔记
    Flex 4.6 手机项目第一次开发小记
    memory point
    两个sql server 2000的通用分页存储过程
    网页通用视频播放(asp.net2.0原作)
    c#操作XML常用方法
    也说项目开发经验
    SQL Server各种日期计算方法
    Server.Transfer()方法在页间传值
  • 原文地址:https://www.cnblogs.com/ggmfengyangdi/p/5703260.html
Copyright © 2020-2023  润新知