- 选择排序
package com.concurency.sort;
import edu.princeton.cs.algs4.StdDraw;
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.StdRandom;
// 选择排序
public class Selection {
protected static boolean less(double a,double b){
return a < b;
}
protected static void exchange(double[] a,int i,int j){
double t = a[i];
a[i] = a[j];
a[j] = t;
}
public static <T> boolean isSorted(double[] a){
for (int i = 1 ; i < a.length ; i++){
if(less(a[i],a[i -1]))return false;
}
return true;
}
protected static void show(double[] a){
for (double tComparable : a) {
StdOut.println(tComparable + "");
}
StdOut.println();
}
public static void sort(double[] a) {
int n = a.length;
for(int i = 0;i<n;i++){
int min = i;
for(int j = i+1; j<n;j++){
if(less(a[j],a[min])){
min = j;
}
}
//show(a, i, min);
exchange(a,i,min);
}
}
private static void show(double[] a, int i, int min) {
StdDraw.setYscale(-a.length + i + 0.8, i + 0.8);
StdDraw.setPenColor(StdDraw.LIGHT_GRAY);
for (int k = 0; k < i; k++)
StdDraw.filledRectangle(k, a[k] * 0.3, 0.25, a[k] * 0.3);
StdDraw.setPenColor(StdDraw.BLACK);
for (int k = i; k < a.length; k++)
StdDraw.filledRectangle(k, a[k] * 0.3, 0.25, a[k] * 0.3);
StdDraw.setPenColor(StdDraw.BOOK_RED);
StdDraw.filledRectangle(min, a[min] * 0.3, 0.25, a[min] * 0.3);
}
public static void main(String[] args) {
int n = 20;
StdDraw.setCanvasSize(160, 640);
StdDraw.setXscale(-1, n+1);
StdDraw.setPenRadius(0.006);
double[] a = new double[n];
for (int i = 0; i < n; i++)
a[i] = StdRandom.uniform(0.0, 1.0);
Selection.sort(a);
}
}
- 插入排序
package com.concurency.sort;
import edu.princeton.cs.algs4.StdDraw;
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.StdRandom;
// 插入排序
public class Insertion {
public static void sort(double[] a) {
int n = a.length;
// 书上为什么总是第一个为红色,是从0开始,如果从0开始,第一次必然不用比较,因为 j>0才成立,所以,i = 0 ,ex = 0,a[0]填充为红色
// 实际上,这完全是浪费时间
for(int i = 1;i<n;i++){
int ex = i;
for(int j = i; j>0 && less(a[j],a[j-1]); j--){
exchange(a,j,j-1);
ex--;
}
//show(a,i,ex);
}
}
// 灰色的元素没有被移动,黑色元素参与了比较,红色元素被交换
// 被交换的位置标为红色,已完成
// i为循环到的位置,从ex开始,到i都为黑色
private static void show(double[] a, int i, int ex) {
StdDraw.setYscale(-a.length + i + 0.8, i + 0.8);
StdDraw.setPenColor(StdDraw.BLACK);
for (int k = ex; k <= i; k++)
StdDraw.filledRectangle(k, a[k] * 0.3, 0.25, a[k] * 0.3);
StdDraw.setPenColor(StdDraw.LIGHT_GRAY);
for (int k = i +1 ; k < a.length; k++)
StdDraw.filledRectangle(k, a[k] * 0.3, 0.25, a[k] * 0.3);
for (int k = 0; k < ex; k++)
StdDraw.filledRectangle(k, a[k] * 0.3, 0.25, a[k] * 0.3);
StdDraw.setPenColor(StdDraw.BOOK_RED);
StdDraw.filledRectangle(ex, a[ex] * 0.3, 0.25, a[ex] * 0.3);
}
protected static boolean less(double a,double b){
return a < b;
}
protected static void exchange(double[] a,int i,int j){
double t = a[i];
a[i] = a[j];
a[j] = t;
}
public static <T> boolean isSorted(double[] a){
for (int i = 1 ; i < a.length ; i++){
if(less(a[i],a[i -1]))return false;
}
return true;
}
protected static void show(double[] a){
for (double tComparable : a) {
StdOut.println(tComparable + "");
}
StdOut.println();
}
public static void main(String[] args) {
int n = 100;
//StdDraw.setCanvasSize(200, 640);
//StdDraw.setXscale(-1, n+1);
//StdDraw.setPenRadius(0.006);
double[] a = new double[n];
for (int i = 0; i < n; i++)
a[i] = StdRandom.uniform(0.0, 1.0);
Insertion.sort(a);
Insertion.show(a);
}
}
- 插入排序哨兵
package com.concurency.sort;
import edu.princeton.cs.algs4.StdDraw;
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.StdRandom;
// 插入排序,首位哨兵
public class InsertionSentinel {
public static void sort(double[] a) {
int n = a.length;
sentinel(a);
// 书上为什么总是第一个为红色,是从0开始,如果从0开始,第一次必然不用比较,因为 j>0才成立,所以,i = 0 ,ex = 0,a[0]填充为红色
// 实际上,这完全是浪费时间
for(int i = 2;i<n;i++){
int ex = i;
for(int j = i; less(a[j],a[j-1]); j--){
exchange(a,j,j-1);
ex--;
}
//show(a,i,ex);
}
}
public static void sentinel(double[] a){
int n = a.length;
// 先找到最小值,并放入最左边,这样就可以省略 j>0,插入哨兵
int min = 0;
for(int i = 1;i<n;i++){
if(less(a[i],a[min])){
min = i;
}
}
exchange(a,0,min);
}
// 灰色的元素没有被移动,黑色元素参与了比较,红色元素被交换
// 被交换的位置标为红色,已完成
// i为循环到的位置,从ex开始,到i都为黑色
private static void show(double[] a, int i, int ex) {
StdDraw.setYscale(-a.length + i + 0.8, i + 0.8);
StdDraw.setPenColor(StdDraw.BLACK);
for (int k = ex; k <= i; k++)
StdDraw.filledRectangle(k, a[k] * 0.3, 0.25, a[k] * 0.3);
StdDraw.setPenColor(StdDraw.LIGHT_GRAY);
for (int k = i +1 ; k < a.length; k++)
StdDraw.filledRectangle(k, a[k] * 0.3, 0.25, a[k] * 0.3);
for (int k = 0; k < ex; k++)
StdDraw.filledRectangle(k, a[k] * 0.3, 0.25, a[k] * 0.3);
StdDraw.setPenColor(StdDraw.BOOK_RED);
StdDraw.filledRectangle(ex, a[ex] * 0.3, 0.25, a[ex] * 0.3);
}
protected static boolean less(double a,double b){
return a < b;
}
protected static void exchange(double[] a,int i,int j){
double t = a[i];
a[i] = a[j];
a[j] = t;
}
public static <T> boolean isSorted(double[] a){
for (int i = 1 ; i < a.length ; i++){
if(less(a[i],a[i -1]))return false;
}
return true;
}
protected static void show(double[] a){
for (double tComparable : a) {
StdOut.println(tComparable + "");
}
StdOut.println();
}
public static void main(String[] args) {
int n = 10;
//StdDraw.setCanvasSize(200, 640);
//StdDraw.setXscale(-1, n+1);
//StdDraw.setPenRadius(0.006);
double[] a = new double[n];
for (int i = 0; i < n; i++)
a[i] = StdRandom.uniform(0.0, 1.0);
InsertionSentinel.sort(a);
InsertionSentinel.show(a);
}
}
- 插入排序无交换
package com.concurency.sort;
import edu.princeton.cs.algs4.StdDraw;
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.StdRandom;
// 插入排序,不交换
public class InsertionNoExchange {
public static void sort(double[] a) {
int n = a.length;
sentinel(a);
for(int i = 2;i<n;i++){
//空出当前位置,给比自己大的数值挪位置
double current = a[i];
// 向前指针索引,一直向前
int preIndex;
double pre;
// 前一个元素
// 从索引号比自己小一位的元素开始比较,由于依然需要和0号位做比较,所以,preIndex >=0,
// 索引号一直向前 如果前一个比自己大,那么大数向后移动一位,如此循环,一旦遇到比自己小的数,立即终止循环
for(preIndex = i - 1,pre = a[preIndex];less(current,a[preIndex]); preIndex-- ,pre = a[preIndex]){
// 向后挪一位
a[preIndex+1] = pre;
}
a[preIndex + 1] = current;
}
}
public static void sentinel(double[] a){
int n = a.length;
// 先找到最小值,并放入最左边,这样就可以省略 j>0,插入哨兵
int min = 0;
for(int i = 1;i<n;i++){
if(less(a[i],a[min])){
min = i;
}
}
exchange(a,0,min);
}
// 灰色的元素没有被移动,黑色元素参与了比较,红色元素被交换
// 被交换的位置标为红色,已完成
// i为循环到的位置,从ex开始,到i都为黑色
private static void show(double[] a, int i, int ex) {
StdDraw.setYscale(-a.length + i + 0.8, i + 0.8);
StdDraw.setPenColor(StdDraw.BLACK);
for (int k = ex; k <= i; k++)
StdDraw.filledRectangle(k, a[k] * 0.3, 0.25, a[k] * 0.3);
StdDraw.setPenColor(StdDraw.LIGHT_GRAY);
for (int k = i +1 ; k < a.length; k++)
StdDraw.filledRectangle(k, a[k] * 0.3, 0.25, a[k] * 0.3);
for (int k = 0; k < ex; k++)
StdDraw.filledRectangle(k, a[k] * 0.3, 0.25, a[k] * 0.3);
StdDraw.setPenColor(StdDraw.BOOK_RED);
StdDraw.filledRectangle(ex, a[ex] * 0.3, 0.25, a[ex] * 0.3);
}
protected static boolean less(double a,double b){
return a < b;
}
protected static void exchange(double[] a,int i,int j){
double t = a[i];
a[i] = a[j];
a[j] = t;
}
public static <T> boolean isSorted(double[] a){
for (int i = 1 ; i < a.length ; i++){
if(less(a[i],a[i -1]))return false;
}
return true;
}
protected static void show(double[] a){
for (double tComparable : a) {
StdOut.println(tComparable + "");
}
StdOut.println();
}
public static void main(String[] args) {
int n = 10;
//StdDraw.setCanvasSize(200, 640);
//StdDraw.setXscale(-1, n+1);
//StdDraw.setPenRadius(0.006);
double[] a = new double[n];
for (int i = 0; i < n; i++)
a[i] = StdRandom.uniform(0.0, 1.0);
InsertionNoExchange.sort(a);
InsertionNoExchange.show(a);
}
}
- 希尔排序
-
package com.concurency.sort; import edu.princeton.cs.algs4.StdOut; import edu.princeton.cs.algs4.StdRandom; public class Shell { public static void sort(double[] a) { int n = a.length; int h = 1; // h 终究会比较大,序列 1,4,13,40,121,364 while (h < n/3){ h = 3 * h + 1; } // while (h >= 1) { for (int i = h; i < n; i++) { // 按照序列递减,将a[i] for (int j = i; j >= h && less(a[j], a[j - h]); j-=h) { exchange(a, j, j - h); } } h = h /3; } } protected static boolean less(double a,double b){ return a < b; } protected static void exchange(double[] a,int i,int j){ double t = a[i]; a[i] = a[j]; a[j] = t; } public static <T> boolean isSorted(double[] a){ for (int i = 1 ; i < a.length ; i++){ if(less(a[i],a[i -1]))return false; } return true; } protected static void show(double[] a){ for (double tComparable : a) { StdOut.println(tComparable + ""); } StdOut.println(); } public static void main(String[] args) { int n = 10; double[] a = new double[n]; for (int i = 0; i < n; i++) a[i] = StdRandom.uniform(0.0, 1.0); Shell.sort(a); Shell.show(a); } }
希尔排序最优序列
1、5、19、41、109、209、505、929、2161、3905、8929、16001、36289、64769、146305、260609(这是通过 9×4k-9×2k+1(k=1,2,3,4,5…) 和 4k-3×2k+1(k=2,3,4,5,6…) 综合得到的