排序算法总是分不清,借了本数据结构来专门看了一下
说一下分类,主要有五类,插入排序,交换排序,选择排序,基数排序和归并排序
今天中午看了一下插入排序中的直接插入排序,交换排序的冒泡排序,选择排序中的冒泡排序
1.插入排序
将数组分成两个部分,一个是有序,一个是无序。将无序的每个元素插入到有序中,一共需要n - 1趟,最后一个元素不用计算
每一趟将第1个元素即array[i]元前面的i个元素比较,如果比array[i]大则后移一个位置。这样找到第i个元素的位置,插入
2.冒泡排序
将相邻两个元素比较,后一个元素i + 1比前一个元素i大交换位置。这样每一趟下来最大的就沉到最后一个元素的位置了。
所以需要n - 1趟,中间考虑到有正序的时候,设置一个标志,如果没有交换说明已经是正序,不用在排序了。
具体细节代码中有说明
3.直接选择排序
每一次从数组中选一个最小值放到最前面
这样需要n - 1趟,平时比较喜欢用这个,简单,但是效率不高
Rec.java
1 package com.gxf.sort; 2 3 /** 4 * 将关键字封装一下 5 * @author xiangfei 6 * 7 */ 8 public class Rec { 9 int key; 10 11 public Rec(int key){ 12 this.key = key; 13 } 14 public Rec(){ 15 16 } 17 18 /** 19 * 根据整型数组构造一个Rec[]数组 20 * @param array 21 * @return 22 */ 23 public Rec[] getRecArray(int array[]){ 24 Rec rec[] = new Rec[array.length]; 25 for(int i = 0; i < array.length; i++){ 26 rec[i] = new Rec(array[i]); 27 } 28 29 return rec; 30 } 31 }
Sort.java
1 package com.gxf.sort; 2 3 /** 4 * 排序类 5 * 这里主要实现三类简单的排序算法 6 * 直接插入排序、交换排序和选择排序中的 7 * 直接插入排序、冒泡排序和直接选择排序 8 * @author xiangfei 9 * 10 */ 11 public class Sort { 12 /** 13 * 直接插入排序算法 14 * 将后面的元素插入到前面的有序队列中n - 1趟 15 * 每一趟需要将比rec[i].key更大的元素后移,找出合适的位置 16 * 这里第一个元素不放值,用于暂存 17 * 开始将第一个元素作为有序队列 18 * @param rec 19 */ 20 public void insSort(Rec rec[]){ 21 //rec[0]不放值 22 for(int i = 1; i < rec.length;i++){ 23 int value = rec[i].key;//需要插入的元素 24 rec[0].key = rec[i].key;//这里需要保存要插入的元素,后面移动元素会覆盖 25 int j = i - 1; 26 while(value < rec[j].key){//后移元素,找到比value小或者等于的 27 rec[j + 1].key = rec[j].key; 28 j--;//前移 29 }//j为比rec[i]小或者等于的元素的位置 30 rec[j + 1].key = rec[0].key;//插入,完成一趟插入 31 } 32 //排完序后第一个元素置为0 33 rec[0].key = 0; 34 } 35 36 /** 37 * 冒泡排序 38 * 每一趟比较两个相邻元素的大小,大的元素往后移动,最大的元素移动到最后 39 * 这样最多需要n - 1趟 40 * 如果有正序的则不用排序,需要设置一个标志位,表明是否有交换 41 * @param rec 42 */ 43 public void bubbSort(Rec rec[]){ 44 boolean flag_exchange = false;//默认没有交换 45 //这里至少需要n - 1趟 46 for(int i = 0; i < rec.length - 1; i++){ 47 flag_exchange = false;//重置标志位没有交换 48 for(int j = 0; j < rec.length - i - 1; j++){//每一趟的排序,范围逐渐缩小 49 if(rec[j].key > rec[j + 1].key){//前一个元素比后一个元素大,需要交换 50 Rec temp = rec[j]; 51 rec[j] = rec[j + 1]; 52 rec[j + 1] = temp;//交换 53 flag_exchange = true;//设置有交换 54 } 55 } 56 if(!flag_exchange) 57 break;//没有交换,说明已经是正序,退出 58 } 59 } 60 61 /** 62 * 直接选择排序 63 * 每次选出最小的放到最前面,需要n - 1趟 64 * 每一趟从剩下的元素中选出最小的,放到最前面 65 * @param rec 66 */ 67 public void seleSort(Rec rec[]){ 68 //需要n - 1趟排序 69 for(int i = 0; i < rec.length - 1;i++){ 70 int min = i;//最小值的下标,默认为第一个元素 71 //从i ~ n - 1中找出最小的一个元素下标 72 for(int j = i; j < rec.length; j++){ 73 if(rec[j].key < rec[min].key) 74 min = j;//更新最小元素的下标 75 }//找出最小元素的下标 76 if(i != min){//如果最小元素不是第一个元素交换 77 Rec temp = rec[min]; 78 rec[min] = rec[i]; 79 rec[i] = temp; 80 }//交换完成 81 } 82 } 83 84 /** 85 * 这里用一个方法来show数组里面的内容,看一下排序是否正确 86 * @param rec 87 */ 88 public void showRec(Rec rec[]){ 89 for(int i = 0; i < rec.length; i++){ 90 System.out.print(rec[i].key + " "); 91 } 92 System.out.println(); 93 } 94 95 }
Test.java
package com.gxf.sort; public class Test { public static void main(String args[]){ Sort sort = new Sort(); Rec rec = new Rec(); int array[] = new int[]{0, 32, 1, 34, 54, 5, 6}; Rec array_test[] = rec.getRecArray(array); System.out.println("直接插入排序:"); sort.showRec(array_test);//print org sort.insSort(array_test); sort.showRec(array_test);//print changed System.out.println("冒泡排序:"); //bubblesort array_test = rec.getRecArray(array); sort.showRec(array_test);//print org sort.bubbSort(array_test); sort.showRec(array_test);//print changed System.out.println("直接选择排序:"); //select array_test = rec.getRecArray(array); sort.showRec(array_test);//print org sort.seleSort(array_test); sort.showRec(array_test);//print changed } }
时间: 2024-10-12 13:36:44