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

 

转载于:https://www.cnblogs.com/cenmny/p/7674270.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Preface This book provides a comprehensive introduction to the modern study of computer algorithms. It presents many algorithms and covers them in considerable depth, yet makes their design and analysis accessible to all levels of readers. We have tried to keep explanations elementary without sacrificing depth of coverage or mathematical rigor. Each chapter presents an algorithm, a design technique, an application area, or a related topic. Algorithms are described in English and in a "pseudocode" designed to be readable by anyone who has done a little programming. The book contains over 230 figures illustrating how the algorithms work. Since we emphasize efficiency as a design criterion, we include careful analyses of the running times of all our algorithms. The text is intended primarily for use in undergraduate or graduate courses in algorithms or data structures. Because it discusses engineering issues in algorithm design, as well as mathematical aspects, it is equally well suited for self-study by technical professionals. In this, the second edition, we have updated the entire book. The changes range from the addition of new chapters to the rewriting of individual sentences. To the teacher This book is designed to be both versatile and complete. You will find it useful for a variety of courses, from an undergraduate course in data structures up through a graduate course in algorithms. Because we have provided considerably more material than can fit in a typical one-term course, you should think of the book as a "buffet" or "smorgasbord" from which you can pick and choose the material that best supports the course you wish to teach. You should find it easy to organize your course around just the chapters you need. We have made chapters relatively self-contained, so that you need not worry about an unexpected and unnecessary dependence of one chapter on another. Each chapter presents the easier material first and the more difficult material later, with section boundaries marking natural stopping points. In an undergraduate course, you might use only the earlier sections from a chapter; in a graduate course, you might cover the entire chapter. We have included over 920 exercises and over 140 problems. Each section ends with exercises, and each chapter ends with problems. The exercises are generally short questions that test basic mastery of the material. Some are simple self-check thought exercises, whereas others are more substantial and are suitable as assigned homework. The problems are more elaborate case studies that often introduce new material; they typically consist of several questions that lead the student through the steps required to arrive at a solution. We have starred (⋆) the sections and exercises that are more suitable for graduate students than for undergraduates. A starred section is not necessarily more difficult than an unstarred one, but it may require an understanding of more advanced mathematics. Likewise, starred exercises may require an advanced background or more than average creativity. To the student We hope that this textbook provides you with an enjoyable introduction to the field of algorithms. We have attempted to make every algorithm accessible and interesting. To help you when you encounter unfamiliar or difficult algorithms, we describe each one in a step-bystep manner. We also provide careful explanations of the mathematics needed to understand the analysis of the algorithms. If you already have some familiarity with a topic, you will find the chapters organized so that you can skim introductory sections and proceed quickly to the more advanced material. This is a large book, and your class will probably cover only a portion of its material. We have tried, however, to make this a book that will be useful to you now as a course textbook and also later in your career as a mathematical desk reference or an engineering handbook. What are the prerequisites for reading this book? • You should have some programming experience. In particular, you should understand recursive procedures and simple data structures such as arrays and linked lists. • You should have some facility with proofs by mathematical induction. A few portions of the book rely on some knowledge of elementary calculus. Beyond that, Parts I and VIII of this book teach you all the mathematical techniques you will need. To the professional The wide range of topics in this book makes it an excellent handbook on algorithms. Because each chapter is relatively self-contained, you can focus in on the topics that most interest you. Most of the algorithms we discuss have great practical utility. We therefore address implementation concerns and other engineering issues. We often provide practical alternatives to the few algorithms that are primarily of theoretical interest. If you wish to implement any of the algorithms, you will find the translation of our pseudocode into your favorite programming language a fairly straightforward task. The pseudocode is designed to present each algorithm clearly and succinctly. Consequently, we do not address error-handling and other software-engineering issues that require specific assumptions about your programming environment. We attempt to present each algorithm simply and directly without allowing the idiosyncrasies of a particular programming language to obscure its essence. To our colleagues We have supplied an extensive bibliography and pointers to the current literature. Each chapter ends with a set of "chapter notes" that give historical details and references. The chapter notes do not provide a complete reference to the whole field of algorithms, however. Though it may be hard to believe for a book of this size, many interesting algorithms could not be included due to lack of space. Despite myriad requests from

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值