【算法和数据结构】—— 1.选择排序、插入排序
2017-07-11 19:05
567 查看
1、O(n^2)排序算法之选择排序**
2、O(n^2)排序算法之插入排序**
2、int类型数组的选择排序算法
3、实现了Comparable接口的类,支持泛型排序
1、实现了Comparable接口的类
2、支持泛型排序实现类
改进版插入排序:
耗时改进点:每次两两比较后如果有需要都互换位置(耗时:交换每次都需要三次赋值操作,访问数组和访问相应下标的数组数据),改进后每次将每次都要交换操作变成有必要时一次赋值来节省时间
实现思路:因为每一趟遍历排序后(0 —> i-1下标的元素已排好序); 下一趟开始遍历前先复制一份i 下标的元素,然后将i 下标元素和 i - 1 下标元素比较,没互换的需要,此趟直接排序完成(非常省时);如有需要互换,将 i - 1下标元素放到 i 下标位置,原复制出来的 i 下标元素值再和 i - 2下标元素比较,如有需要互换,将 i - 2 下标元素放到 i - 1 下标位置;没需要互换,将复制出来的 i 下标元素值放在 i - 1 下标位置,此趟排序完成 … 即上一趟排好序的数不断往前推, i 下标元素找到属于自己的位置, 就是每一趟排序完成。
时间复杂度:==> 对于几乎有序的数组,插入排序效果非常高,时间复杂度近乎O(n)
2、O(n^2)排序算法之插入排序**
一、O(n^2)排序算法之选择排序
1、实现思路: 从最左边下标开始,将该下标的元素和它右边所有元素比较,每一趟遍历找出最小元素的下标,然后将最小下标的元素和该下标元素互换,即每一趟遍历都将最小值放在开始遍历的最左的下标位置2、int类型数组的选择排序算法
package com.algorithm.demo; /** * * @author eric * 从最左边下标开始,将该下标的元素和它右边所有元素比较,每一趟遍历找出最小元素的下标 * 然后将最小下标的元素和每一趟遍历开始的最左边下标的元素互换,即每一趟遍历都将最小值放在开始遍历的最左的下标位置 */ public class SelectionSort { // 我们的算法类不允许产生任何实例 private SelectionSort() { } public static void sort(int[] arr) { // 左边要比较到倒数第二个下标 int len = arr.length; for (int i = 0; i < len - 1; i++) { // 寻找[i, n)区间里的最小值的索引 int minIndex = i; for (int j = i + 1; j < len; j++) { // 每一趟遍历找出最小元素的下标 if (arr[j] < arr[minIndex]) { minIndex = j; } } // 交换开始遍历的最左和最小下标的元素 swap(arr, i, minIndex); } } /** * 交换两个下标的元素 * * @param arr 要排序的数组 * @param i 下标1 * @param j 下标2 */ private static void swap(int[] arr, int i, int j) { int t = arr[i]; arr[i] = arr[j]; arr[j] = t; } public static void main(String[] args) { int[] arr = { 10, 9, 8, 7, 6, 5, 4, 1, 2, 3, 0 }; SelectionSort.sort(arr); for (int i = 0; i < arr.length; i++) { System.out.print(arr[i]); System.out.print(' '); } System.out.println(); } }
3、实现了Comparable接口的类,支持泛型排序
1、实现了Comparable接口的类
package com.algorithm.demo; /** * * @author eric * */ // 实现了Comparable接口的类,支持排序 public class Student implements Comparable<Student> { private String name; private int score; public Student(String name, int score) { this.name = name; this.score = score; } // 定义Student的compareTo函数 // 如果分数相等,则按照名字的字母序排序 // 如果分数不等,则分数高的靠前 @Override public int compareTo(Student that) { if (this.score == that.score) return this.name.compareTo(that.name); if (this.score < that.score) return 1; else if (this.score > that.score) return -1; else // this.score == that.score return 0; } // 定义Student实例的打印输出方式 @Override public String toString() { return "Student: " + this.name + " " + Integer.toString(this.score); } }
2、支持泛型排序实现类
package com.algorithm.demo; public class SelectionSort2 { // 我们的算法类不允许产生任何实例 private SelectionSort2(){} /** * 支持泛型比较 * @param arr */ public static <T extends Comparable<T>> void sort(T[] arr){ int len = arr.length; for (int i = 0; i < len - 1; i++) { // 寻找[i, n)区间里的最小值的索引 int minIndex = i; for (int j = i + 1; j < len; j++) { // 使用compareTo方法比较两个Comparable对象的大小 if (arr[j].compareTo(arr[minIndex]) < 0) { minIndex = j; } } swap(arr, i, minIndex); } } private static void swap(Object[] arr, int i, int j) { Object t = arr[i]; arr[i] = arr[j]; arr[j] = t; } public static void main(String[] args) { // 测试Integer Integer[] a = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 }; SelectionSort2.sort(a); for (int i = 0; i < a.length; i++) { System.out.print(a[i]); System.out.print(' '); } System.out.println(); // 测试Double Double[] b = { 4.4, 3.3, 2.2, 1.1 }; SelectionSort2.sort(b); for (int i = 0; i < b.length; i++) { System.out.print(b[i]); System.out.print(' '); } System.out.println(); // 测试String String[] c = { "D", "C", "B", "A" }; SelectionSort2.sort(c); for (int i = 0; i < c.length; i++) { System.out.print(c[i]); System.out.print(' '); } System.out.println(); // 测试自定义的类 Student Student[] d = new Student[4]; d[0] = new Student("D", 90); d[1] = new Student("C", 100); d[2] = new Student("B", 95); d[3] = new Student("A", 95); SelectionSort2.sort(d); for (int i = 0; i < d.length; i++) System.out.println(d[i]); } }
二、插入排序
1、普通插入排序实现思路:从右边开始起将相邻元素两两比较后排序。第一趟将最左边两个元素比较排序,右边的大于(或小于)左边的话,两者调换元素位置;第二趟从最左边三个元素右边开始将两两比较排序,…… 最后一次是所有元素的相邻元素从右边开始将两两比较排序for (int i = 1; i < len; i++) { // 寻找元素arr[i]合适的插入位置 for( int j = i; j > 0 && arr[j].compareTo(arr[j-1]) < 0 ; j--) { swap(arr, j, j-1); } }
改进版插入排序:
耗时改进点:每次两两比较后如果有需要都互换位置(耗时:交换每次都需要三次赋值操作,访问数组和访问相应下标的数组数据),改进后每次将每次都要交换操作变成有必要时一次赋值来节省时间
实现思路:因为每一趟遍历排序后(0 —> i-1下标的元素已排好序); 下一趟开始遍历前先复制一份i 下标的元素,然后将i 下标元素和 i - 1 下标元素比较,没互换的需要,此趟直接排序完成(非常省时);如有需要互换,将 i - 1下标元素放到 i 下标位置,原复制出来的 i 下标元素值再和 i - 2下标元素比较,如有需要互换,将 i - 2 下标元素放到 i - 1 下标位置;没需要互换,将复制出来的 i 下标元素值放在 i - 1 下标位置,此趟排序完成 … 即上一趟排好序的数不断往前推, i 下标元素找到属于自己的位置, 就是每一趟排序完成。
int len = arr.length; for (int i = 1; i < len; i++) { T e = arr[i]; int j = i; // j 保存元素e应该插入的位置 for( ; j > 0 && arr[j-1].compareTo(e) > 0 ; j--) { arr[j] = arr[j-1]; // 前一趟排好序的数组和e值比较,不断往前推移 } arr[j] = e; }
时间复杂度:==> 对于几乎有序的数组,插入排序效果非常高,时间复杂度近乎O(n)
相关文章推荐
- 算法和数据结构-选择排序、插入排序及希尔排序 java实现
- 数据结构与算法——三种基础排序算法C#实现(冒泡排序、选择排序、插入排序)
- OC学习之道:数据结构中几种常见的排序算法:选择排序,插入排序.快速排序
- 数据结构&算法实践—【排序|选择排序】堆排序
- java数据结构之插入排序(选择排序(直接选择排序、堆排序))
- 选择排序、快速排序、希尔排序、堆排序不是稳定的排序算法,而冒泡排序、插入排序、归并排序和基数排序
- 数据结构之基础排序(选择排序、插入排序、冒泡排序)
- 【数据结构和算法那些事】--【2】--选择排序
- java基本算法总结(冒泡排序、选择排序、插入排序)
- 内部排序冒泡排序、插入排序、选择排序、快速排序的算法和PHP实现
- java-算法-选择排序、插入排序
- 【算法】希尔排序,快速排序,选择排序,插入排序,冒泡排序
- 【算法基础】冒泡、选择、插入排序(三种基本排序)
- 【算法与数据结构必备】PHP常用排序算法:冒泡,快速排序,插入排序(一维数组)
- 算法:冒泡排序(Bubble Sort)、插入排序(Insertion Sort)和选择排序(Selection Sort)总结
- 冒泡排序、选择排序、插入排序 算法实现(C++)
- 算法和数据结构---排序--简单选择排序
- c语言中冒泡排序、插入排序、选择排序算法比较
- 冒泡排序、选择排序、插入排序 算法实现
- Python实现各类数据结构和算法---直接选择排序