Skip to content

Commit

Permalink
Chapter 02 Optimized Selection Sort added.
Browse files Browse the repository at this point in the history
  • Loading branch information
liuyubobobo committed Nov 14, 2017
1 parent 108d1aa commit b624010
Show file tree
Hide file tree
Showing 34 changed files with 538 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
cmake_minimum_required(VERSION 3.5)
project(Optional_01_Optimized_Selection_Sort)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")

set(SOURCE_FILES main.cpp)
add_executable(Optional_01_Optimized_Selection_Sort ${SOURCE_FILES})
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//
// Created by Yuan Zhang on 11/14/17.
//

#ifndef OPTIONAL_01_OPTIMIZED_SELECTION_SORT_INSERTIONSORT_H
#define OPTIONAL_01_OPTIMIZED_SELECTION_SORT_INSERTIONSORT_H

#endif //OPTIONAL_01_OPTIMIZED_SELECTION_SORT_INSERTIONSORT_H
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@

//
// Created by liuyubobobo on 7/16/16.
//

#ifndef INC_04_INSERTION_SORT_ADVANCE_SELECTIONSORT_H
#define INC_04_INSERTION_SORT_ADVANCE_SELECTIONSORT_H

#include <iostream>
#include <algorithm>

using namespace std;


#include <iostream>
#include <algorithm>

using namespace std;


template<typename T>
void insertionSort(T arr[], int n){

for( int i = 1 ; i < n ; i ++ ) {

T e = arr[i];
int j;
for (j = i; j > 0 && arr[j-1] > e; j--)
arr[j] = arr[j-1];
arr[j] = e;
}

return;
}

#endif //INC_04_INSERTION_SORT_ADVANCE_SELECTIONSORT_H
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
//
// Created by liuyubobobo on 7/13/16.
//

#ifndef INC_04_INSERTION_SORT_ADVANCE_SORTTESTHELPER_H
#define INC_04_INSERTION_SORT_ADVANCE_SORTTESTHELPER_H

#include <iostream>
#include <algorithm>
#include <string>
#include <ctime>
#include <cassert>
#include <string>

using namespace std;


namespace SortTestHelper {

// 生成有n个元素的随机数组,每个元素的随机范围为[rangeL, rangeR]
int *generateRandomArray(int n, int range_l, int range_r) {

int *arr = new int[n];

srand(time(NULL));
for (int i = 0; i < n; i++)
arr[i] = rand() % (range_r - range_l + 1) + range_l;
return arr;
}

// 生成一个近乎有序的数组
// 首先生成一个含有[0...n-1]的完全有序数组, 之后随机交换swapTimes对数据
// swapTimes定义了数组的无序程度:
// swapTimes == 0 时, 数组完全有序
// swapTimes 越大, 数组越趋向于无序
int *generateNearlyOrderedArray(int n, int swapTimes){

int *arr = new int[n];
for(int i = 0 ; i < n ; i ++ )
arr[i] = i;

srand(time(NULL));
for( int i = 0 ; i < swapTimes ; i ++ ){
int posx = rand()%n;
int posy = rand()%n;
swap( arr[posx] , arr[posy] );
}

return arr;
}

// 拷贝整型数组a中的所有元素到一个新的数组, 并返回新的数组
int *copyIntArray(int a[], int n){

int *arr = new int[n];
//* 在VS中, copy函数被认为是不安全的, 请大家手动写一遍for循环:)
copy(a, a+n, arr);
return arr;
}

// 打印arr数组的所有内容
template<typename T>
void printArray(T arr[], int n) {

for (int i = 0; i < n; i++)
cout << arr[i] << " ";
cout << endl;

return;
}

// 判断arr数组是否有序
template<typename T>
bool isSorted(T arr[], int n) {

for (int i = 0; i < n - 1; i++)
if (arr[i] > arr[i + 1])
return false;

return true;
}

// 测试sort排序算法排序arr数组所得到结果的正确性和算法运行时间
template<typename T>
void testSort(const string &sortName, void (*sort)(T[], int), T arr[], int n) {

clock_t startTime = clock();
sort(arr, n);
clock_t endTime = clock();
cout << sortName << " : " << double(endTime - startTime) / CLOCKS_PER_SEC << " s"<<endl;

assert(isSorted(arr, n));

return;
}

};

#endif //INC_04_INSERTION_SORT_ADVANCE_SORTTESTHELPER_H
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#include <iostream>
#include <algorithm>
#include "SortTestHelper.h"
#include "SelectionSort.h"
#include "InsertionSort.h"

using namespace std;

// 感谢github @zhengquan45 提出, 可以对选择排序进行优化
// 在每一轮中, 可以同时找到当前未处理元素的最大值和最小值
template<typename T>
void selectionSort(T arr[], int n){

int left = 0, right = n - 1;
while(left < right){
int minIndex = left;
int maxIndex = right;

// 在每一轮查找时, 要保证arr[minIndex] <= arr[maxIndex]
if(arr[minIndex] > arr[maxIndex])
swap(arr[minIndex], arr[maxIndex]);

for(int i = left + 1 ; i < right; i ++)
if(arr[i] < arr[minIndex])
minIndex = i;
else if(arr[i] > arr[maxIndex])
maxIndex = i;

swap(arr[left], arr[minIndex]);
swap(arr[right], arr[maxIndex]);

left ++;
right --;
}

return;
}

int main() {

int n = 40000;

// 测试1 一般测试
cout<<"Test for random array, size = "<<n<<", random range [0, "<<n<<"]"<<endl;
int *arr1 = SortTestHelper::generateRandomArray(n,0,n);
int *arr2 = SortTestHelper::copyIntArray(arr1, n);
int *arr3 = SortTestHelper::copyIntArray(arr1, n);

SortTestHelper::testSort("Insertion Sort", insertionSort,arr1,n);
SortTestHelper::testSort("Selection Sort", selectionSort,arr2,n);
SortTestHelper::testSort("Selection Sort 2", selectionSort,arr3,n);

delete[] arr1;
delete[] arr2;
delete[] arr3;

cout<<endl;


// 测试2 有序性更强的测试
cout<<"Test for more ordered random array, size = "<<n<<", random range [0, 3]"<<endl;
arr1 = SortTestHelper::generateRandomArray(n,0,3);
arr2 = SortTestHelper::copyIntArray(arr1, n);
arr3 = SortTestHelper::copyIntArray(arr1, n);

SortTestHelper::testSort("Insertion Sort", insertionSort,arr1,n);
SortTestHelper::testSort("Selection Sort", selectionSort,arr2,n);
SortTestHelper::testSort("Selection Sort 2", selectionSort,arr3,n);

delete[] arr1;
delete[] arr2;
delete[] arr3;

cout<<endl;


// 测试3 测试近乎有序的数组
int swapTimes = 100;
cout<<"Test for nearly ordered array, size = "<<n<<", swap time = "<<swapTimes<<endl;
arr1 = SortTestHelper::generateNearlyOrderedArray(n,swapTimes);
arr2 = SortTestHelper::copyIntArray(arr1, n);
arr3 = SortTestHelper::copyIntArray(arr1, n);

SortTestHelper::testSort("Insertion Sort", insertionSort,arr1,n);
SortTestHelper::testSort("Selection Sort", selectionSort,arr2,n);
SortTestHelper::testSort("Selection Sort 2", selectionSort,arr3,n);

delete[] arr1;
delete[] arr2;
delete[] arr3;

return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package bobo.algo;

import java.util.*;

public class InsertionSort{

// 我们的算法类不允许产生任何实例
private InsertionSort(){}

public static void sort(Comparable[] arr){

int n = arr.length;
for (int i = 0; i < n; i++) {

// 寻找元素arr[i]合适的插入位置

// 写法1
// for( int j = i ; j > 0 ; j -- )
// if( arr[j].compareTo( arr[j-1] ) < 0 )
// swap( arr, j , j-1 );
// else
// break;

// 写法2
// for( int j = i; j > 0 && arr[j].compareTo(arr[j-1]) < 0 ; j--)
// swap(arr, j, j-1);

// 写法3
Comparable e = arr[i];
int j = i;
for( ; j > 0 && arr[j-1].compareTo(e) > 0 ; j--)
arr[j] = arr[j-1];
arr[j] = e;

}
}

private static void swap(Object[] arr, int i, int j) {
Object t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}

// 测试InsertionSort
public static void main(String[] args) {

int N = 20000;
Integer[] arr = SortTestHelper.generateRandomArray(N, 0, 100000);
SortTestHelper.testSort("bobo.algo.InsertionSort", arr);

return;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package bobo.algo;

import java.util.Arrays;

public class Main {

// 比较SelectionSort, SelectionSort2和InsertionSort两种排序算法的性能效率
// 优化后,插入排序比选择排序性能略好
// 对于有序性强的数组,插入排序远远优于选择排序
public static void main(String[] args) {

int N = 20000;

// 测试1 一般测试
System.out.println("Test for random array, size = " + N + " , random range [0, " + N + "]");

Integer[] arr1 = SortTestHelper.generateRandomArray(N, 0, N);
Integer[] arr2 = Arrays.copyOf(arr1, arr1.length);
Integer[] arr3 = Arrays.copyOf(arr1, arr1.length);

SortTestHelper.testSort("bobo.algo.InsertionSort", arr1);
SortTestHelper.testSort("bobo.algo.SelectionSort", arr2);
SortTestHelper.testSort("bobo.algo.SelectionSort2", arr3);

System.out.println();


// 测试2 有序性更强的测试
System.out.println("Test for more ordered random array, size = " + N + " , random range [0,3]");

arr1 = SortTestHelper.generateRandomArray(N, 0, 3);
arr2 = Arrays.copyOf(arr1, arr1.length);
arr3 = Arrays.copyOf(arr1, arr1.length);

SortTestHelper.testSort("bobo.algo.InsertionSort", arr1);
SortTestHelper.testSort("bobo.algo.SelectionSort", arr2);
SortTestHelper.testSort("bobo.algo.SelectionSort2", arr3);

System.out.println();


// 测试3 测试近乎有序的数组
int swapTimes = 100;
System.out.println("Test for nearly ordered array, size = " + N + " , swap time = " + swapTimes);

arr1 = SortTestHelper.generateNearlyOrderedArray(N, swapTimes);
arr2 = Arrays.copyOf(arr1, arr1.length);
arr3 = Arrays.copyOf(arr1, arr1.length);

SortTestHelper.testSort("bobo.algo.InsertionSort", arr1);
SortTestHelper.testSort("bobo.algo.SelectionSort", arr2);
SortTestHelper.testSort("bobo.algo.SelectionSort2", arr3);

return;
}
}
Loading

0 comments on commit b624010

Please sign in to comment.