Introduction to Algorithms

5. 线性时间排序

  Method: 不通过比较数据进行排序,要求数组值在一定范围内;根据数组值的大小范围K,生成一个K大小的新数组,依序存储原数组的值的数量,最后取出新数组的内容即可。

 1 public class XianxingShijianPaixu {
 2     public int[] solution(int[] input, int k){
 3         int[] kElem = new int[k + 1];
 4         int n = input.length - 1;
 5         int[] output = new int[n + 1];
 6         for(int i = 0; i <= n; i++){
 7             kElem[input[i]] = kElem[input[i]] + 1;
 8         }
 9         for(int j = 1; j <= k; j++){
10             kElem[j] = kElem[j] + kElem[j - 1];
11         }
12         for(int h = 0; h <= n; h++){
13 //            System.out.println(input[h]+ " h:" + h);
14 //            System.out.println(kElem[input[h]]+ " h:" + h);
15 
16             output[kElem[input[h]]-1] = input[h];
17 //            System.out.println(input[h]+ " h:" + h);
18             kElem[input[h]]--;
19 //            System.out.println(kElem[input[h]]);
20 
21         }
22         return output;
23     }
24     public static void main(String[] args){
25 //        int[] x = {1,3,4,6,57,34,23,897,567,3,2,6,10};
26         int[] x = {2,8,7,1,3,5,6,4,0,5,3,2};
27 //        int[] x = {1,0,2};
28         int[] y = new XianxingShijianPaixu().solution(x, 8);                                                                                                                                                                                                                                                                
29 //        int[] y = new KuaiPai().secondPart(x, 0, x.length - 1);
30         System.out.println(y[5] + " " + y[6] + " ");
31     }
32 }
View Code

 

4. 快速排序

  Method:FirstPart使用位置标记i 和 j,保证i 位置处之前的均为比array[array.length - 1]小,array[i + 1]设置为array[array.length - 1],其后均为比array大的项;SencondPart两次递归使用FirstPart实现最终排序。(可以随机选择array[array.length - 1]值,便于改善平均时间复杂度)

 1 import java.util.Random;
 2 
 3 public class KuaiPai {
 4     
 5     int i1;
 6     public int firstPart(int[] input, int p, int r){
 7         int i = p - 1;
 8         int tmp = 0;
 9         for(int j = p; j < r; j++){
10             if(input[j] < input[r]){
11                 i++;
12                 tmp = input[j];
13                 input[j] = input[i];
14                 input[i] = tmp;
15             }
16         }
17         tmp = input[r];
18         input[r] = input[i + 1];
19         input[i + 1] = tmp; 
20         System.out.println(input[p] +" " + input[r]);
21         return i;
22                 
23     }
24     
25     public int firstPartRandom(int[] input, int p, int r){
26         Random random = new Random();
27         int i = random.nextInt(r - p) + p;
28         int tmp = input[r];
29         input[r] = input[i];
30         input[i] = tmp;
31         return firstPart(input, p, r);
32     }
33     
34     public int[] secondPart(int[] input, int p ,int r){
35 //        int i = 0;
36         if (p < r){
37             i1 = firstPartRandom(input, p , r);
38             System.out.println("i1: " + i1);
39             secondPart(input, p , i1);
40             secondPart(input, i1 + 2, r);
41         }
42         return input;
43     }
44     public static void main(String[] args){
45         int[] x = {1,3,4,6,57,34,23,897,567,3,2,6,10};
46 //        int[] x = {2,8,7,1,3,5,6,4};
47 //        int[] x = {1,0,2};
48 //        int y = new KuaiPai().firstPart(x, 0, x.length - 1 );                                                                                                                                                                                                                                                                
49         int[] y = new KuaiPai().secondPart(x, 0, x.length - 1);
50         System.out.println(y[2] + " " + y[12] + " ");
51     }
52 }
View Code

3. 堆排序(三步排完)

  Method:FirstPart假设左右两子堆是最大堆,与父堆比较生成新的一个最大堆,需要一次递归调用;SecondPart设置一个无序数组从Array.length - 1处开始调用F,保证生成一个最大堆;ThirdPart取出最大堆的最大值后,交换最后一值,调用F(array,0),完成过程。 this.arrayLength attention!

  1 //import java.lang.*;
  2 import java.lang.reflect.Array;
  3 public class DuiPaixu {
  4     int arrayLength;
  5     public int[] firstPart(int[] input){
  6         int n = input.length - 1;
  7         int left = 0;
  8         int right = 0;
  9         int max = 0;
 10         for(int i = 0; i < n; i++){
 11             if( 2 * i + 2 <= n){
 12                 left = input[2 * i + 1];
 13                 right = input[2 * i + 2];
 14                 if(left > input[i] && right > input[i]){
 15                     if(left < right){
 16                         max = right;
 17                         input[2 * i + 2] = input[i];
 18                         input[i] = max;
 19                         
 20                     }
 21                     else{
 22                         max = left;
 23                         input[2 * i + 1] = input[i];
 24                         input[i] = max;
 25                     }
 26                 }
 27                 else if(left > input[i]){
 28                     max = left;
 29                     input[2 * i + 1] = input[i];
 30                     input[i] = max;
 31                 }
 32                 else if(right > input[i]){
 33                     max = right;
 34                     input[2 * i + 2] = input[i];
 35                     input[i] = max;
 36                 }
 37             }
 38             if(2 * i + 2 > n && 2 * i + 1 == n){
 39                 left = input[2 * i + 1];
 40                 if(left > input[i]){
 41                     max = left;
 42                     input[2 * i + 1] = input[i];
 43                     input[i] = max;
 44                 }
 45             }
 46             
 47         }
 48         return input;
 49     }
 50     //T(n) = O(n) no better than following.
 51     
 52     public int[] firstPartBetter(int[] input, int i){
 53         int j = 2 * i + 1;
 54         int k = 2 * i + 2;
 55         int largest = 0;
 56         int tmp = 0;
 57         //具体情况具体写清晰
 58 //        this.arrayLength = input.length - 1;
 59 //        System.out.println(j + " k: " + k + " "+ arrayLength);
 60         if(k <= arrayLength){
 61             if(input[i] < input[j]){
 62                 largest = j;
 63             }
 64             else{
 65                 largest = i;
 66             }
 67             if(input[k] > input[largest]){
 68                 largest = k;
 69             }
 70 //            System.out.println(largest + " i: " + i);
 71             if(largest != i){
 72                 tmp = input[i];
 73                 input[i] = input[largest];
 74                 input[largest] = tmp;
 75                 firstPartBetter(input, largest);
 76             }
 77         }
 78         else if(k > arrayLength && j == arrayLength){
 79             if(input[i] < input[j]){
 80                 tmp = input[i];
 81                 input[i] = input[j];
 82                 input[j] = tmp;
 83             }
 84         }
 85         return input;
 86         
 87     }
 88     
 89     public int[] secondPart(int[] input){
 90 //        this.arrayLength = input.length - 1;
 91         System.out.println("test" + arrayLength);
 92         for(int i = arrayLength; i >= 0; i--){
 93 //            System.out.println(i);
 94             firstPartBetter(input, i);
 95         }
 96         return input;
 97     }
 98     
 99     public int[] thirdPart(int[] input){
100         this.arrayLength = input.length -1;
101         secondPart(input);
102         int tmp = 0;
103         for(int i = input.length - 1; i >= 0 ; i--){
104             tmp = input[i];
105             input[i] = input[0];
106             input[0] = tmp;
107             this.arrayLength = this.arrayLength - 1;
108             firstPartBetter(input, 0);
109         }
110         return input;
111     }
112     
113     public static void main(String[] args){
114         int[] x = {78,34,67,89,23,2,14,6,7,3,8,8,33,3,3,1,335,7};
115         int[] y = new DuiPaixu().thirdPart(x);
116         System.out.println(y[2] + " " + y[3]+ " " + y[17]);
117     }
118 }
View Code

2. 归并排序(分治法)

  方法:FirstPart对左右各已排序完成部分进行整合排序,SecondPart对大的待排序数组进行分治操作,具体分解流程见下图,其它递归算法也可参照。

  

 

 1 public class GuibingPaixu {
 2     public int[] firstPart(int[] input, int p, int q, int r){
 3         int n1 = q - p + 1;
 4         int n2 = r - q;
 5         int k = 0;
 6         int[] input1 = new int[n1];
 7         int[] input2 = new int[n2];
 8         for(int i = 0; i < n1; i++){
 9             input1[i] = input[p + i];
10 //            System.out.println(input1[i]+"/n");
11         }
12         for(int j = 0; j < n2; j++){
13             input2[j] = input[q + j + 1];
14         }
15         int m = 0;
16         int n = 0;
17         while(k < n1 + n2){
18             if(m < n1 && n < n2){
19                 if(input1[m] <= input2[n]){
20                     input[p + k] = input1[m];
21                     m++;
22                 }
23                 else{
24                     input[p + k] = input2[n];
25                     n++;
26                 }
27             }
28             else if(m >= n1 && n < n2){
29                 input[p + k] = input2[n];
30                 n++;
31             }
32             else{
33                 input[p + k] = input1[m];
34                 m++;
35             }
36             k++;
37         }
38         return input;
39     }
40     
41     public int[] secondPart(int[] input, int p, int r){
42         int q = 0;
43         if(p < r){
44             q = (p + r)/2;
45             secondPart(input, p, q);
46             System.out.println(q);
47             System.out.println("r:" + r);
48             secondPart(input, q + 1, r);
49             System.out.println( "right" + q + 1);
50             firstPart(input, p, q, r);
51             System.out.println( "first" + q);
52 
53         }
54         return input;
55     }
56     
57     
58     public static void main(String[] args){
59         int[] x = {5,7,8,9,23,56,1,2,3,4,5,6,7,89};
60         int[] x1 = {5,1,89,3,5,8,2,0,34,12,33,445,667,6,34};
61         int[] y = new GuibingPaixu().firstPart(x, 1, 5, 13);
62         int[] y1 = new GuibingPaixu().secondPart(x1, 0, 14);
63         System.out.println(y1[0] + " " + y1[1] + " " + y1[2] + " " + y1[14]);
64 //        System.out.println(y[0] + " " + y[1] + " " + y[2] + " " + y[13]);
65     }
66 }
View Code

1. 直接插入排序

  应用:属于比较排序的一种,最基础的排序方法,稳定,时间复杂度为O(n^2),空间复杂度为S(1).

  方法:设置待排数字角标为i,j = i, 把j对应数字与其前的字数逐个对比交换完成后,i++即可.

 1 public class Paixu {
 2     public int[] paixu(int[] input){
 3         int n = input.length - 1;
 4         for(int i = 1; i <= n; i++){
 5             int j = i;
 6             int tmp = 0;
 7             for(; j > 0 && input[j] < input[j - 1]; j--){
 8                 tmp = input[j - 1];
 9                 input[j - 1] = input[j];
10                 input[j] = tmp;
11             }
12 
13         }
14         return input;
15     }
16     //T(n) = O(n ^ 2); S(n) = O(1) 插入排序
17     public static void main(String[] args){
18         int[] x = {3,3,7,8,21,1};
19         int[] y = new Paixu().paixu(x);
20         System.out.println(y[0] + " " + y[1]);
21     }
22 }
View Code

 

posted @ 2017-10-15 21:16  BlueMonds  阅读(329)  评论(0编辑  收藏  举报