• 排序


      1 1.冒泡排序
      2 时间复杂度:O(n²)
      3 冒泡排序算法的运作如下:(从后往前)
      4 1)比较相邻的元素。如果第一个比第二个大,就交换他们两个。
      5 2)对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
      6 3)针对所有的元素重复以上的步骤,除了最后一个。
      7 4)持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
      8 代码实现:
      9 
     10 package cn.lpq.sort;
     11 
     12 public class BubbleSort {
     13     public static void main(String[] args) {
     14         System.out.println("排序前:");
     15         int[] arr={51, 46, 20, 18, 65, 97, 82, 30, 77, 50,2,33,12,100 };
     16         printSort(arr);
     17         System.out.println("排序后:");
     18         bubbleSort(arr);
     19         printSort(arr);
     20 
     21     }
     22     public static void bubbleSort(int[]arr){
     23         for(int x=0;x<arr.length-1;x++){
     24             for(int y=0;y<arr.length-1-x;y++){
     25                 if(arr[y]>arr[y+1]){
     26                     int temp=arr[y];
     27                     arr[y]=arr[y+1];
     28                     arr[y+1]=temp;
     29                 }
     30             }
     31 
     32         }
     33     }
     34     public static void printSort(int []arr){
     35         StringBuilder res=new StringBuilder();
     36         res.append("[");
     37         for(int i=0;i<arr.length;i++){
     38             if(i==arr.length-1)
     39                 res.append(arr[i]+"]");
     40             else
     41                 res.append(arr[i]+",");
     42         }
     43         System.out.println(res.toString());
     44     }
     45 }
     46 1
     47 2
     48 3
     49 4
     50 5
     51 6
     52 7
     53 8
     54 9
     55 10
     56 11
     57 12
     58 13
     59 14
     60 15
     61 16
     62 17
     63 18
     64 19
     65 20
     66 21
     67 22
     68 23
     69 24
     70 25
     71 26
     72 27
     73 28
     74 29
     75 30
     76 31
     77 32
     78 33
     79 34
     80 35
     81 36
     82 37
     83 结果:
     84 冒泡排序结果
     85 2.选择排序:
     86 时间复杂度:O(n²)
     87 选择排序(Selection sort)同样也是最经典最简单的排序算法之一,特点就是简单直观。
     88 排序的原理:首先在未排序的序列里找到最小(大)元素,放到序列的首端,再从剩余元素中找到最小(大)的元素,放到序列的尾端。依次循环,直到排序完成。
     89 代码实现:
     90 
     91 package cn.lpq.sort;
     92 
     93 public class SelectSort {
     94     public static void main(String[] args) {
     95         int[] arr={11,9,3,44,12,98,292,34,522,232};
     96         System.out.println("选择排序前:");
     97         printSort(arr);
     98         selectSort(arr);
     99         System.out.println("选择排序后:");
    100         printSort(arr);
    101     }
    102     public static void selectSort(int[]arr){
    103         for(int x=0;x<arr.length-1;x++){
    104             for(int y=x+1;y<arr.length;y++){
    105                 if(arr[x]>arr[y]){
    106                     int temp=arr[y];
    107                     arr[y]=arr[x];
    108                     arr[x]=temp;
    109 
    110                 }
    111             }
    112 
    113         }
    114     }
    115     public static void printSort(int []arr){
    116         StringBuilder res=new StringBuilder();
    117         res.append("[");
    118         for(int i=0;i<arr.length;i++){
    119             if(i==arr.length-1)
    120                 res.append(arr[i]+"]");
    121             else
    122                 res.append(arr[i]+",");
    123         }
    124         System.out.println(res.toString());
    125     }
    126 }
    127 1
    128 2
    129 3
    130 4
    131 5
    132 6
    133 7
    134 8
    135 9
    136 10
    137 11
    138 12
    139 13
    140 14
    141 15
    142 16
    143 17
    144 18
    145 19
    146 20
    147 21
    148 22
    149 23
    150 24
    151 25
    152 26
    153 27
    154 28
    155 29
    156 30
    157 31
    158 32
    159 33
    160 34
    161 35
    162 36
    163 37
    164 结果:
    165 选择排序结果
    166 
    167 3.快速排序:
    168 快排思想:
    169 快速排序的原理:选择一个关键值作为基准值。比基准值小的都在左边序列(一般是无序的),比基准值大的都在右边(一般是无序的)。一般选择序列的第一个元素。
    170 一次循环:从后往前比较,用基准值和最后一个值比较,如果比基准值小的交换位置,如果没有继续比较下一个,直到找到第一个比基准值小的值才交换。找到这个值之后,又从前往后开始比较,如果有比基准值大的,交换位置,如果没有继续比较下一个,直到找到第一个比基准值大的值才交换。直到从前往后的比较索引>从后往前比较的索引,结束第一次循环,此时,对于基准值来说,左右两边就是有序的了,接着分别比较左右两边的序列,重复上述的循环。
    171 时间复杂度为:nlog(n)
    172 
    173 package cn.dataStructures.Sort;
    174 //快速排序算法--利用递归
    175 public class QuickSort {
    176     public static void main(String[] args) {
    177         int []arr={12,20,5,16,15,1,2,100,30,45,23,9};
    178         int low=0;
    179         int high=arr.length-1;
    180         quickSort(arr,low,high);
    181         printSortArr(arr);
    182     }
    183     public static void quickSort(int [] arr,int low,int high){
    184         int start=low;//设置可以移动的最小值
    185         int end=high;//设置可以移动的最大值
    186         int key=arr[low];//设置标识
    187         while(start<end){//整体大循环
    188             while(start<end&&arr[end]>=key)//先从循环后面的,从后向前,找小于key的
    189                 end--;
    190             if(arr[end]<=key){
    191                 int temp=arr[end];
    192                 arr[end]=arr[start];
    193                 arr[start]=temp;
    194             }
    195             while(start<end&&arr[start]<=key)//循环前面的,从前往后找大于key的值
    196                 start++;
    197             if(arr[start]>=key){
    198                 int temp=arr[start];
    199                 arr[start]=arr[end];
    200                 arr[end]=temp;
    201             }
    202         }
    203         //递归调用
    204         if(low<start)
    205             quickSort(arr,low,start-1);
    206         if(end<high)
    207             quickSort(arr,end+1,high);
    208 
    209     }//打印输出数组
    210     public static void printSortArr(int []arr){
    211         StringBuilder res=new StringBuilder();
    212         res.append("[");
    213         for(int i=0;i<arr.length;i++){
    214             if(i==arr.length-1){
    215                 res.append(arr[i]+"]");
    216             }
    217             else{
    218                 res.append(arr[i]+",");
    219             }
    220         }
    221         System.out.println(res.toString());
    222     }
    223 }
    224 1
    225 2
    226 3
    227 4
    228 5
    229 6
    230 7
    231 8
    232 9
    233 10
    234 11
    235 12
    236 13
    237 14
    238 15
    239 16
    240 17
    241 18
    242 19
    243 20
    244 21
    245 22
    246 23
    247 24
    248 25
    249 26
    250 27
    251 28
    252 29
    253 30
    254 31
    255 32
    256 33
    257 34
    258 35
    259 36
    260 37
    261 38
    262 39
    263 40
    264 41
    265 42
    266 43
    267 44
    268 45
    269 46
    270 47
    271 48
    272 49
    273 50
    274 51
    275 52
    276 结果:
    277 快速排序结果
    278 4.归并排序:
    279 时间复杂度为:nlog(n)
    280 排序原理:
    281 (1)申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
    282 (2)设定两个指针,最初位置分别为两个已经排序序列的起始位置
    283 (3)比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
    284 (4)重复步骤3直到某一指针达到序列尾
    285 (5)将另一序列剩下的所有元素直接复制到合并序列尾
    286 
    287 package cn.dataStructures.Sort;
    288 
    289 /**
    290  * **归并排序(理解描述)**:
    291  * 思想:
    292  * 1.对原始序列arr进行一半分割,设置原始序列的第一个索引low和最后一个索引值high,并创建临时序列
    293  * 2.求出原始序列的中间索引mid=(low+high)/2,根据mid对序列分割
    294  * 3.判断low是否小于high,满足则递归调用步骤1和2,一直对分割的序列再分割,直到剩余一个元素为止
    295  * 4.对分割的序列分别根据其索引指向的元素值进行比较,小的则放入临时序列中,各序列索引加1、、
    296  * 5.对剩余没有加入到临时序列中的元素直接添加到临时序列的最后的位置
    297  * 6.将临时序列赋值给原始序列,此时原始序列就是已经排好序的序列
    298  * @author lpq
    299  *
    300  */
    301 
    302 public class MergeSort {
    303     public static void main(String[] args) {
    304         System.out.println("排序前:");
    305         int[] arr={51, 46, 20, 18, 65, 97, 82, 30, 77, 50 };
    306         printSort(arr);
    307         mergeSort(arr,0,arr.length-1);
    308         System.out.println("排序后:");
    309         printSort(arr);
    310     }
    311     //切分原始数组
    312     public static void mergeSort(int[]arr,int low,int high){
    313         int mid=(low+high)/2;//将序列按中间分开
    314 
    315         if(low<high){
    316             //分开左边
    317             mergeSort(arr,low,mid);
    318             //右半边
    319             mergeSort(arr,mid+1,high);
    320             //将左右已经排序好的合并
    321             merge(arr,low,mid,high);
    322         }
    323 
    324 
    325     }
    326     public static void merge(int[]arr,int low,int mid,int high){
    327         /**
    328          * 这里的start和end分别是左半边序列和右半边序列的其实指针,分别指向各半边序列的第一个位置,随着的元素的比较而发生改变
    329          * 而low和high是不发生改变的,一般来说low指的是序列的第一个索引0即low=0,high=arr.lenth-1,
    330          * low和length值不发生改变
    331          */
    332         //临时数组(序列)
    333         int [] temp=new int[high-low+1];
    334         //左半边序列的指针(一般指向第一个位置low)
    335         int start=low;
    336         //右半边序列的指针
    337         int end=mid+1;
    338         //临时数组序列的索引
    339         int k=0;
    340         //把小的元素加入到临时数组中
    341         while(start<=mid&&end<=high){
    342             if(arr[start]<arr[end])
    343                 temp[k++]=arr[start++];
    344             else
    345                 temp[k++]=arr[end++];
    346         }
    347         //把左边剩余元素加入到临时数组的后面
    348         while(start<=mid)//这里不能用if判断,因为if只能判断一次,while只要满足条件就会一直循环判断下去
    349             temp[k++]=arr[start++];
    350         //把右半边剩余元素加入到临时数组的后面
    351         while(end<=high)
    352             temp[k++]=arr[end++];
    353         //将排序好的临时数组复制给原始数组arr
    354         for(int i=0;i<temp.length;i++){
    355             arr[i+low]=temp[i];
    356         }
    357     }
    358     public static void printSort(int []arr){
    359         StringBuilder res=new StringBuilder();
    360         res.append("[");
    361         for(int i=0;i<arr.length;i++){
    362             if(i==arr.length-1)
    363                 res.append(arr[i]+"]");
    364             else
    365                 res.append(arr[i]+",");
    366         }
    367         System.out.println(res.toString());
    368     }
    369 }
    370 
    371 1
    372 2
    373 3
    374 4
    375 5
    376 6
    377 7
    378 8
    379 9
    380 10
    381 11
    382 12
    383 13
    384 14
    385 15
    386 16
    387 17
    388 18
    389 19
    390 20
    391 21
    392 22
    393 23
    394 24
    395 25
    396 26
    397 27
    398 28
    399 29
    400 30
    401 31
    402 32
    403 33
    404 34
    405 35
    406 36
    407 37
    408 38
    409 39
    410 40
    411 41
    412 42
    413 43
    414 44
    415 45
    416 46
    417 47
    418 48
    419 49
    420 50
    421 51
    422 52
    423 53
    424 54
    425 55
    426 56
    427 57
    428 58
    429 59
    430 60
    431 61
    432 62
    433 63
    434 64
    435 65
    436 66
    437 67
    438 68
    439 69
    440 70
    441 71
    442 72
    443 73
    444 74
    445 75
    446 76
    447 77
    448 78
    449 79
    450 80
    451 81
    452 82
    453 83
    454 84
    455 85
    456 结果:
    457 归并排序结果
    458 时间复杂度分析:
    459 递归法分析:
    460 因为归并排序实现要将原始序列分为2部分,然后将这2个序列排序好后再赋值给临时序列temp,假设原始序列的元素个数为N,则时间复杂度的主要表达式为:T(N)=2T(N/2)+N;
    461 1.首先将N/2带入主要表达式。结果:2T(N/2)=2(2T(N/4))+N=4T(N/4)+N,根据主要表达式可知:2T(N/2)=T(N)-N,所以可简化为:T(N)=4T(N/4)+2N
    462 2.将N/4带入主表达式,同理可得到:T(N)=8T(N/8)+3N,可类比为:T(N)=2^kT(N/2^k)+kN
    463 3.利用k=log(N),可得T(N)=NT(1)+Nlog(N)=Nlog(N)+N
    464 4.时间复杂度为:O(Nlog(N))
    465 二分搜索法:
    466 二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。
    467 注意:二分查找前提条件是:该序列有序
    468 
    469 package cn.lpq.sort;
    470 
    471 import java.util.Arrays;
    472 
    473 //二分查找前提是该数组有序
    474 public class BinarySerch {
    475     public static void main(String[] args) {
    476         int []arr={11,22,33,44,55,66,77};
    477         Arrays.sort(arr);//对数组排序
    478         System.out.println(binarySerch(arr,55));
    479     }
    480     public static int binarySerch(int[]arr,int value){
    481         int min=0;
    482         int max=arr.length-1;
    483         int mid=(min+max)/2;
    484         while(arr[mid]!=value){
    485             if(arr[mid]>value){
    486                 max=mid-1;
    487             }
    488             else if(arr[mid]<value){
    489                 min=mid+1;
    490             }
    491             mid=(min+max)/2;
    492         }
    493         if(min>max){
    494             return -1;//说明数组为空或所查找元素不存在
    495         }
    496         return mid;
    497 
    498     }
    499 }
  • 相关阅读:
    Awesome Ubuntu中文
    OpenCV 2.4.0 + IPP + TBB, checked
    (MSys+MinGW )FFmpeg工程编译 FFplay Gary's Blog A C++ programmer 博客频道 CSDN.NET
    OpenCV installation for Ubuntu 12.04 | Raben Systems, Inc.
    安装Ubuntu 12.04后没有休眠(hibernate)选项
    Entity Framework 4.1
    三行代码实现阿拉伯数字转中文大小写<转>
    DataGridViewCell赋值
    数据库事务嵌套用法
    WCF传递DataTable时需要填写表名
  • 原文地址:https://www.cnblogs.com/nidegui/p/13710291.html
Copyright © 2020-2023  润新知