冒泡排序、选择排序、插入排序、希尔排序、归并排序-Java基础

悠悠 2022-01-11 05:17 402阅读 0赞

* 1. 传统的冒泡排序

* 时间复杂度为O(n2) 最好情况为o(n)

* 特点:1、冒泡排序是一种用时间换空间的排序方法,n小的时候好

* 2、最坏情况是把顺序的排列变成逆序,或者把逆序的数列变成顺序,最差时间复杂度O(N^2)只是表示其操作次数的数量级

3、最好的情况是数据本来就有序,复杂度为O(n)

* 冒泡的思想:从序列的一端到另一端一直进行冒泡,依次比较相邻的两个数的大小,如果不符合要排序的进行交换。、

* 双层for循环,i=0到length-1;j=0到length-i-1,依次比较大小进行交换位置

//2. 改进的冒泡排序

* 3. 选择排序

* 双层循环,时间复杂度和冒泡一模一样,都是O(n2)

* 不稳定

* 算法思想:初始化第一个i为最小值,然后找到序列中的最小值与第一个i进行交换,依次找到最小的元素,

* 进行双层for循环,i=0到length;初始化最小元素的下标。j=i+到length,依次比较大小,将最小元素下标进行更新,在i循环层进行交换位置

* 4. 插入排序

* 稳定,简单

* 算法思想:数组分为两个区域,一个已排序,一个未排序,初始化中已排序为空,第一轮,取出第一个数,然后插入到已排序区域中,此时已排序为空,就不做比较。

* 第二轮继续将未排序数组拿出一个,插入到已排序区域中,挨个遍历比较,然后进行排序交换。依次循环

* 最好情况的时间复杂度是 O(n),最坏情况的时间复杂度是 O(n2)

* 5. 希尔排序

* 最好情况的时间复杂度是 O(n),最坏情况的时间复杂度是 O(n2)

* 不稳定,复杂,

* 算法思想:插入排序的高级版本,插入排序对于大规模的乱序数组的时候效率较低,每次只移动一位,希尔排序可以快速插入,跳跃移动数据

* 设置排序区间,例如设置为4,则首先将第五个数据与第一个数据比较,然后交换,指针右移动,第6个数据与第二个数据比较。依次右移指针,进行比较,

* 如果交换数据后,发现减去区间得到的位置还存在数据,那么继续进行比较。当最后一个元素比较完之后,较大的数据大多调整到数组后半部分。

* 然后缩小去京,进行比较,直到区间缩小到1;区间为1的时候,也就是插入排序。

* 6. 归并排序

* 时间复杂度,O(N*log2N) 较为稳定,也较为复杂

* 归并排序每次递归都要用到一个辅助表,长度与待排序的表长度相同,虽然递归次数是O(log2n),但每次递归都会释放掉所占的辅助空间,

* n大时好,归并比较占用内存,内存随n的增大而增大,但却是效率高且稳定的排序算法。

* 算法思想:主要采用分治的思想,将数组一分两半,递归切分,直到切分到单个元素,然后进行重新排序组合。

* 需要数据量较小的情况

package pratice618;

public class testBubbleSort {
/**
* @param ycy
* 多种排序算法的代码实现和说明
*/
/**
* 传统的冒泡排序
* 时间复杂度为O(n2) 最好情况为o(n)
* 特点: 1、冒泡排序是一种用时间换空间的排序方法,n小的时候好
* 2、最坏情况是把顺序的排列变成逆序,或者把逆序的数列变成顺序,最差时间复杂度O(N^2)只是表示其操作次数的数量级
3、最好的情况是数据本来就有序,复杂度为O(n)
* 冒泡的思想:从序列的一端到另一端一直进行冒泡,依次比较相邻的两个数的大小,如果不符合要排序的进行交换。、
* 双层for循环,i=0到length-1;j=0到length-i-1,依次比较大小进行交换位置
*/
public static void bubbleSort(int array[]){ //传统的冒泡排序,时间复杂度为O(n2)
int count=0;
for(int i=0;iarray[j+1]){ //从大到小,或者从小到大
temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
count++;
}
}
}
System.out.println(“循环次数”+count);
}
//改进的冒泡排序
public static void improvebubbleSort(int array[]){ //临时遍历来标记该数组是否已经有序
int count=0;
for(int i=0;iarray[j+1]){ //从大到小,或者从小到大
temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
isSort = false;
count++;
}

  1. \}
  2. if(isSort)\{
  3. break;
  4. \}
  5. \}
  6. System.out.println("循环次数"+count);
  7. \}
  8. /\*\*
  9. \* 选择排序
  10. \* 双层循环,时间复杂度和冒泡一模一样,都是O(n2)
  11. \* 不稳定
  12. \* 算法思想:初始化第一个i为最小值,然后找到序列中的最小值与第一个i进行交换,依次找到最小的元素,
  13. \* 进行双层for循环,i=0length;初始化最小元素的下标。j=i+到length,依次比较大小,将最小元素下标进行更新,在i循环层进行交换位置
  14. \*/
  15. public static void selectSort(int array\[\])\{ //选择最小的数字放在最左或者最右
  16. for(int i=0;i<array.length;i++)\{
  17. int min = i;
  18. for(int j=i+1;j<array.length;j++)\{
  19. if(array\[j\]<array\[min\])\{ //找到最小的元素
  20. min = j;
  21. \}
  22. \}
  23. int tempt = array\[i\]; //最小的元素与第i个元素进行位置的交换
  24. array\[i\] = array\[min\];
  25. array\[min\] = tempt;
  26. \}
  27. \}
  28. /\*\*
  29. \* 插入排序
  30. \* 稳定,简单
  31. \* 算法思想:数组分为两个区域,一个已排序,一个未排序,初始化中已排序为空,第一轮,取出第一个数,然后插入到已排序区域中,此时已排序为空,就不做比较。
  32. \* 第二轮继续将未排序数组拿出一个,插入到已排序区域中,挨个遍历比较,然后进行排序交换。依次循环
  33. \* 最好情况的时间复杂度是 O(n),最坏情况的时间复杂度是 O(n2)
  34. \*/
  35. public static void insertSort(int array\[\])\{ //选择最小的数字放在最左或者最右
  36. //
  37. for(int i=1;i<array.length;i++)\{
  38. int value = array\[i\];
  39. int j=0;
  40. for(j=i-1;j>=0;j--)\{
  41. if(array\[j\]>value)\{
  42. array\[j+1\] = array\[j\]; //移动元素,将需要插入的元素,插入到已经排序的数组中,所以是从i-1到0进行插入比较
  43. \}else\{
  44. break; //找到合适的位置不需要再进行比较
  45. \}
  46. \}
  47. array\[j+1\] = value;
  48. System.out.println("array\[j+1\] "+array\[j+1\]);
  49. \}
  50. \}
  51. /\*\*
  52. \* 希尔排序
  53. \* 最好情况的时间复杂度是 O(n),最坏情况的时间复杂度是 O(n2)
  54. \* 不稳定,复杂,
  55. \* 算法思想:插入排序的高级版本,插入排序对于大规模的乱序数组的时候效率较低,每次只移动一位,希尔排序可以快速插入,跳跃移动数据
  56. \* 设置排序区间,例如设置为4,则首先将第五个数据与第一个数据比较,然后交换,指针右移动,第6个数据与第二个数据比较。依次右移指针,进行比较,
  57. \* 如果交换数据后,发现减去区间得到的位置还存在数据,那么继续进行比较。当最后一个元素比较完之后,较大的数据大多调整到数组后半部分。
  58. \* 然后缩小去京,进行比较,直到区间缩小到1;区间为1的时候,也就是插入排序。
  59. \*/
  60. public static void hillSort(int array\[\])\{
  61. int length = array.length;
  62. //设置区间
  63. int interval = 1;
  64. while(interval < length)\{
  65. interval = interval\*3 + 1; //设置区间 4
  66. \}
  67. while(interval > 0)\{
  68. for(int i=interval;i<length;i++)\{ //区间后一部分的数据
  69. int j = i-interval; //区间前一部分的数据
  70. int temp = array\[i\];
  71. while(j>=0 && array\[j\] > temp)\{
  72. //跨区间循环
  73. array\[j+interval\] = array\[j\]; //转换过程想要根据interval的值进行变换,所以下标值都需要采用interval进行转换
  74. j = j - interval; //为下一步根据区间赋值做准备
  75. //System.out.println("j: "+j);
  76. \}
  77. array\[j+interval\] = temp; //更改array\[j\]的值
  78. \}
  79. interval = interval / 3; //更新区间大小 4, 1, 0
  80. //System.out.println("interval "+interval);
  81. \}
  82. \}
  83. /\*\*
  84. \* 归并排序
  85. \* 时间复杂度,O(N\*log2N) 较为稳定,也较为复杂
  86. \* 归并排序每次递归都要用到一个辅助表,长度与待排序的表长度相同,虽然递归次数是O(log2n),但每次递归都会释放掉所占的辅助空间,
  87. \* n大时好,归并比较占用内存,内存随n的增大而增大,但却是效率高且稳定的排序算法。
  88. \* 算法思想:主要采用分治的思想,将数组一分两半,递归切分,直到切分到单个元素,然后进行重新排序组合。
  89. \* 需要数据量较小的情况
  90. \*/
  91. public static void mergeSort(int array\[\])\{
  92. int temparray\[\] = new int\[array.length\];
  93. mSort(array, temparray, 0, array.length-1);
  94. \}
  95. public static void mSort(int array\[\], int temparray\[\],int start, int end)\{
  96. if(start >= end)\{ //start >= end 等于号,切分到单个元素
  97. return;
  98. \}
  99. int middle =start + (end - start) /2; //每个小数组的中间值,需要考虑start
  100. //分解数组
  101. mSort(array, temparray, start, middle);
  102. mSort(array, temparray, middle+1, end);
  103. //合并
  104. merge(array, temparray, start, end, middle);
  105. \}
  106. public static void merge(int array\[\], int temparray\[\],int start, int end, int middle)\{
  107. for(int i = start;i<=end;i++)\{
  108. temparray\[i\] = array\[i\]; //对原来的数组进行复制,首先复制的是单个元素,然后逐渐合并为小数组
  109. \}
  110. int left = start;
  111. int right = middle + 1;
  112. for(int j=start;j<=end;j++)\{
  113. if(left > middle)\{ //左边数据排序完成
  114. array\[j\] = temparray\[right++\];
  115. \}else if(right > end)\{ //右边数据排序完成
  116. array\[j\] = temparray\[left++\];
  117. \}else if(temparray\[right\] < temparray\[left\])\{ //右边的首位排入进来,右边下标进行+1
  118. array\[j\] = temparray\[right++\];
  119. \}else\{ //左边的首位排入进来,左边下标进行+1
  120. array\[j\] = temparray\[left++\];
  121. \}
  122. \}
  123. \}
  124. /\*\*
  125. \* 测试相关算法
  126. \* @author ycy
  127. \*/
  128. public static void main(String\[\] args) \{
  129. // TODO Auto-generated method stub
  130. int array\[\] = \{5,7,3,2\};
  131. for(int i=0;i<array.length;i++)\{
  132. System.out.print(array\[i\] + " ");
  133. \}
  134. System.out.println("\*\*\*\*\*\*\*\*\*\*\*\*\*\*");
  135. bubbleSort(array);
  136. //测试改进冒泡排序,这个需要数据较多情况下,能够看到效果
  137. int array1\[\] = \{5,7,3,2\};
  138. improvebubbleSort(array1);
  139. for(int i=0;i<array.length;i++)\{
  140. System.out.print(array\[i\] + " ");
  141. \}
  142. //测试插入排序
  143. System.out.println("\*\*\*\*\*\*\*\*\*\*\*\*\*\*");
  144. int array2\[\] = \{5,7,3,2\};
  145. insertSort(array2);
  146. for(int i=0;i<array2.length;i++)\{
  147. System.out.print(array2\[i\] + " ");
  148. \}
  149. //测试希尔排序
  150. System.out.println("\*\*\*\*\*\*\*\*\*\*\*\*\*\*");
  151. int array3\[\] = \{5,7,3,2,1,4,6,9,8,10\};
  152. hillSort(array3);
  153. for(int i=0;i<array3.length;i++)\{
  154. System.out.print(array3\[i\] + " ");
  155. \}
  156. //测试归并排序
  157. System.out.println("\*\*\*\*\*\*\*\*\*\*\*\*\*\*");
  158. int array4\[\] = \{5,7,3,2,1,4,6,9,8,10\};
  159. mergeSort(array4);
  160. for(int i=0;i<array4.length;i++)\{
  161. System.out.print(array4\[i\] + " ");
  162. \}
  163. \}

}

扫码关注一起随时随地学习!!!就在洋葱攻城狮,更多精彩,等你来!!

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3ljeTA3MDY_size_16_color_FFFFFF_t_70

发表评论

表情:
评论列表 (有 0 条评论,402人围观)

还没有评论,来说两句吧...

相关阅读