排序算法总结(java)



排序算法

排序是将无需的记录序列调整为有序记录序列的一种操作。

包括:冒泡排序,选择排序,堆排序,插入排序,希儿排序,快速排序,归并排序等。

(一)
冒泡排序

  1. 基本思想:

    每次进行相邻两个元素的比较,如果为逆序时即进行交换,直到没有反序的数据元素为止。

  2. 排序过程:

    设想被排序的数组R[1..N]垂直竖立,将每个数据元素看作有重量的气泡,根据轻气泡不能在重气泡之下的原则,从下往上扫描数组R,凡扫描到违反本原则的轻气泡,就使其向上"漂浮",如此反复进行,直至最后任何两个气泡都是轻者在上,重者在下为止。

  1. 示例:对36 23 87 16 11
    进行冒泡排序的过程:

初始时:36
23 87 16 11

第一趟:23
36 16 11 87

第二趟:23
16 11 36 87

第三趟:16
11 23 36 87

第四趟:11
16 23 36 87

代码如下所示


1.  
/**

2.  
 *
冒泡排序算法

3.  
 *

4.  
 *
@author
stecai

5.  
 */

6.  
public
class BubbleSort {

7.  
   
/**

8.  
   
 * 排序算法的实现,对数组中指定的元素进行排序

9.  
   
 *

10. 
   
 * @param arr
待排序的数组

11. 
   
 * @param from
待排序的数组

12. 
   
 * @param end
排到哪里

13. 
   
 */

14. 
   
public
static
void sort(Integer[] arr) {

15. 
       
if (arr ==
null || arr.length
< 2) {

16. 
           
return;

17. 
       
}

18.

19. 
       
//
需arr.length - 1轮比较

20. 
       
for (int
i = 0, iend = arr.length - 1; i < iend; i++) {

21. 
           
//
每轮循环中从第一个元素开始向后比较起泡

22. 
           
for (int
j = 0, jEnd = iend - i; j < jEnd; j++) {

23. 
               
//
按照一种规则(后面元素不能小于前面元素)排序

24. 
               
if ((arr[j].compareTo(arr[j + 1])) > 0) {

25. 
                   
//
交换数组中的两个元素的位置

26. 
                   
swap(arr, j, j + 1);

27. 
               
}

28. 
           
}

29. 
       
}

30. 
   
}

31.

32. 
   
/**

33. 
   
 * 交换数组中的两个元素的位置

34. 
   
 *

35. 
   
 * @param arr
待交换的数组

36. 
   
 * @param i
第一个元素

37. 
   
 * @param j
第二个元素

38. 
   
 */

39. 
   
private
static
void swap(Integer[] arr,
int i,
int j) {

40. 
       
Integer tmp = arr[i];

41. 
       
arr[i] = arr[j];

42. 
       
arr[j] = tmp;

43. 
   
}

44.  
}

(二)
选择排序

  1. 基本思想:

    每一趟在n-i+1(i=1,2,3,...,n-1)个记录中选取关键字最小的记录作为有序序列中的第i个记录。

  2. 排序过程:
  1. 将整个记录序列划分为有序区域和无序区域,有序区域位于最左端,无序区域位于右端,初始状态有序区域为空,无序区域含有待排序的所有n个记录。
  2. 设置一个整型变量index,用于记录在一趟的比较过程中,当前关键字值最小的记录位置。开始将它设定为当前无序区域的第一个位置,即假设这个位置的关键字最小,然后用它与无序区域中其他记录进行比较,若发现有比它的关键字还小的记录,就将index改为这个新的最小记录位置,随后再用a[index].key
    与后面的记录进行比较,并根据比较结果,随时修改index的值,一趟结束后index中保留的就是本趟选择的关键字最小的记录位置。
  3. 将index位置的记录交换到无序区域的第一个位置,使得有序区域扩展了一个记录,而无序区域减少了一个记录。
  4. 不断重复 (2)、(3),直到无序区域剩下一个记录为止。此时所有的记录已经按关键字从小到大的顺序排列就位。
  1. 示例:对36 23 87 16 11
    进行选择排序的过程:

初始时:36
23 87 16 11

第一趟:11
[36 23 87 16]

第二趟:11
16 [36 23 87]

第三趟:11
16 23 [36 87]

第四趟:11
16 23 36 [87]



:11
16 23 36 87

代码如下所示


1.  
/**

2.  
 *
选择排序算法

3.  
 *

4.  
 *
@author
stecai

5.  
 */

6.  
public
class
SelectSort {

7.  
   
/**

8.  
   
 * 对数组中指定的元素进行排序

9.  
   
 *

10. 
   
 * @param
arr 待排序的数组

11. 
   
 */

12. 
   
public
static
void
sort(Integer[] arr) {

13. 
       
//
最小索引

14. 
       
int
minIndex;

15.

16. 
       
//
循环整个数组

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

18. 
           
//
假设每轮第一个元素为最小元素

19. 
           
minIndex = i;

20.

21. 
           
//
从假设的最小元素的下一元素开始循环

22. 
           
for
(int
j = i + 1; j < arr.length;
j++) {

23. 
               
//
如果发现有比当前更小元素,则记下该元素的索引于minIndex中

24. 
               
if
((arr[j].compareTo(arr[i])) < 0) {

25. 
                   
 minIndex = j;

26. 
               
}

27. 
           
}

28.

29. 
           
//
与每轮的第一个元素交换

30. 
           
if
(i != minIndex) {

31. 
               
swap(arr, i, minIndex);

32. 
           
}

33. 
       
}

34. 
   
}

35.

36. 
   
/**

37. 
   
 * 交换数组中的两个元素的位置

38. 
   
 *

39. 
   
 * @param
arr 待交换的数组

40. 
   
 * @param
i 第一个元素

41. 
   
 * @param
j 第二个元素

42. 
   
 */

43. 
   
private
static
void
swap(Integer[] arr, int
x, int
y) {

44. 
       
int
temp = arr[x];

45. 
       
arr[x] = arr[y];

46. 
       
arr[y] = temp;

47. 
   
}

48.  
}

(三)
堆排序

  1. 基本思想:

    将堆看成是一棵以k1为根的完全二叉树,则这棵完全二叉树中的每个非终端结点的值均不大于(或不小于)其左、右孩子结点的值。由此可以看出,若一棵完全二叉树是堆,则根结点一定是这n个结点中的最小者或最大者。

  2. 堆的定义

    N个元素的序列K1,K2,K3,...,Kn.称为堆,当且仅当该序列满足特性:

    Ki≤K2i
    Ki ≤K2i+1(1≤
    I≤ [N/2])

  3. 排序过程:

首先将待排序的记录序列构造一个堆,此时,选出了堆中所有记录的最小者或最大者,然后将它从堆中移走,并将剩余的记录再调整成堆,这样又找出了次小(或次大)的记录,以此类推,直到堆中只有一个记录为止,每个记录出堆的顺序就是一个有序序列。

代码如下所示


1.  
/**

2.  
 *
堆排序算法

3.  
 *

4.  
 *
@author
stecai

5.  
 */

6.  
public
class HeapSort {

7.  
   
/**

8.  
   
 * 对数组中指定的元素进行排序

9.  
   
 *

10. 
   
 * @param
arr 待排序的数组

11. 
   
 * @param from
待排序的数组

12. 
   
 * @param end
排到哪里

13. 
   
 */

14. 
   
public
static
void sort(Integer[]
arr, int from,
int end) {

15. 
       
//
创建初始堆

16. 
       
initialHeap(arr, from, end);

17.

18. 
       
/*

19. 
       
 * 对初始堆进行循环,每轮循环后丢弃最后一个叶子节点,再看作一个新的堆

20. 
       
 */

21. 
       
for (int
i = end - from + 1; i >= 2; i--) {

22. 
           
//
根节点与最后一个叶子节点交换位置,即数组中的第一个元素与最后一个元素互换

23. 
           
swap(arr, from, i - 1);

24.

25. 
           
//
交换后需要重新调整堆

26. 
           
adjustNote(arr, 1, i - 1);

27. 
       
}

28. 
   
}

29.

30. 
   
/**

31. 
   
 * 初始化堆

32. 
   
 *

33. 
   
 * @param arr
排序数组

34. 
   
 * @param from
从哪里开始排序

35. 
   
 * @param end
排到哪里

36. 
   
 */

37. 
   
private
static
void initialHeap(Integer[] arr,
int from,
int end) {

38. 
       
//
对所有的非叶子节点(半数)进行循环,且从最一个非叶子节点开始

39. 
       
for (int
i = (end - from + 1) / 2; i >= 1; i--) {

40. 
           
adjustNote(arr, i, end - from + 1);

41. 
       
}

42. 
   
}

43.

44. 
   
/**

45. 
   
 * 从父、左右子节点三个节点中选择一个最大节点与父节点转换

46. 
   
 *

47. 
   
 * @param arr
待排序数组

48. 
   
 * @param parentNodeIndex
要调整的节点,与它的子节点一起进行调整

49. 
   
 * @param len
树的节点数

50. 
   
 */

51. 
   
private
static
void adjustNote(Integer[] arr,
int parentNodeIndex,
int len) {

52. 
       
int minNodeIndex = parentNodeIndex;

53.

54. 
       
//
如果有左子树,i * 2为左子节点索引

55. 
       
if (parentNodeIndex * 2 <= len) {

56. 
           
//
如果父节点小于左子树时

57. 
           
if ((arr[parentNodeIndex - 1].compareTo(arr[parentNodeIndex
* 2 - 1])) < 0) {

58. 
               
//
记录最大索引为左子节点索引

59. 
               
minNodeIndex = parentNodeIndex * 2;

60. 
           
}

61.

62. 
           
//
再进一步断判是否有右子树

63. 
           
if (parentNodeIndex * 2 + 1 <= len) {

64. 
               
//
如果右子树比最大节点更大

65. 
               
if ((arr[minNodeIndex - 1].compareTo(arr[parentNodeIndex
* 2])) < 0) {

66. 
                   
//
记录最大索引为右子节点索引

67. 
                   
minNodeIndex = parentNodeIndex * 2 + 1;

68. 
               
}

69. 
           
}

70. 
       
}

71.

72. 
       
/*

73. 
       
 *  如果在父节点、左、右子节点三都中,最大节点不是父节点时需交换,把最大的与父节点交换,继续创建大顶堆

74. 
       
 */

75. 
       
if (minNodeIndex != parentNodeIndex) {

76. 
           
swap(arr, parentNodeIndex - 1, minNodeIndex - 1);

77.

78. 
           
//
交换后可能需要重建堆,原父节点可能需要继续下沉.是否有子节点,只需判断是否有左子树即可知道

79. 
           
if (minNodeIndex * 2 <= len) {

80. 
               
adjustNote(arr, minNodeIndex, len);

81. 
           
}

82. 
       
}

83. 
   
}

84.

85. 
   
/**

86. 
   
 * 交换数组中的两个元素的位置

87. 
   
 *

88. 
   
 * @param arr
待交换的数组

89. 
   
 * @param i
第一个元素

90. 
   
 * @param j
第二个元素

91. 
   
 */

92. 
   
public
static
void swap(Integer[] arr,
int x,
int y) {

93. 
       
int temp = arr[x];

94. 
       
arr[x] = arr[y];

95. 
       
arr[y] = temp;

96. 
   
}

97.  
}

(四)
插入排序

  1. 基本思想:

    每次将一个待排序的数据元素,插入到前面已经排好序的数列中的适当位置,使数列依然有序;直到待排序数据元素全部插入完为止。

  2. 排序过程:

    将待排序表看做是左、右两部分,其中左边为有序区,右边为无序区,整个排序过程就是将右边无序区中的记录依次按关键字大小逐个插入到左边有序区中,以构成新的有序区,直到全部记录都排好序。

  3. 示例:对36
    23 87 16 11

    进行插入排序的过程:

    初始:36 23 87 16 11

    一趟:23 36
    87 16 11

    二趟:23 36
    87 16 11

    三趟:16 23 36 87
    11

    四趟:11 16 23 36 87

代码如下所示


1.  
/**

2.  
 *
插入排序算法

3.  
 *

4.  
 *
@author
stecai

5.  
 */

6.  
public
class InsertSort {

7.  
   
/**

8.  
   
 * 对数组中指定的元素进行排序

9.  
   
 *

10. 
   
 * @param arr
待排序的数组

11. 
   
 * @param from
待排序的数组

12. 
   
 * @param end
排到哪里

13. 
   
 */

14. 
   
public
static
void sort(Integer[] arr,
int from,
int end) {

15. 
       
//
从待排序数组断的第二个元素开始循环,到最后一个元素(包括)止

16. 
       
for (int
i = from + 1; i <= end; i++) {

17. 
           
//
对有序数组进行循环,且从有序数组最第一个元素开始向后循环
找到第一个大于待插入的元素

18. 
           
for (int
j = 0; j < i; j++) {

19. 
               
//
待插入到有序数组的元素

20. 
               
Integer insertedElem = arr[i];

21.

22. 
               
//
从有序数组中最一个元素开始查找第一个大于待插入的元素

23. 
               
if ((arr[j].compareTo(insertedElem)) > 0) {

24. 
                   
//
找到插入点后,从插入点开始向后所有元素后移一位

25.

26. 
                   
move(arr, j, i - 1);

27. 
                   
//
将待排序元素插入到有序数组中

28. 
                   
arr[j] = insertedElem;

29. 
                   
break;

30. 
               
}

31. 
           
}

32. 
       
}

33. 
   
}

34.

35. 
   
/**

36. 
   
 * 数组元素后移

37. 
   
 *

38. 
   
 * @param arr
待移动的数组

39. 
   
 * @param startIndex
从哪个开始

40. 
   
 * @param endIndex
到哪个元素止

41. 
   
 */

42. 
   
private
static
void move(Integer[] arr,
int startIndex,
int endIndex) {

43. 
       
for (int
i = endIndex; i >= startIndex; i--) {

44. 
           
arr[i + 1] = arr[i];

45. 
       
}

46. 
   
}

47.  
}

(五)
希儿排序

  1. 基本思想:

    希儿排序又称为缩小增量排序,是将待排序的记录划分成几组,从而减少参与直接插入排序的数据量,当经过几次分组排序后,记录的排列已经基本有序,这个时候再对所有的记录实施直接插入排序。

  2. 排序过程:

    假设带排序的记录为n个,先取整数step
    < n作为步长,通常选取step = n / 2 (n / 2表示不大于n
    / 2的最大整数),将所有距离为step的记录构成一组,从而将整个待排序记录序列分割称为step个子序列。反复比较相距step的两数,当两个数不等时,将小的交换到前面,直到所有相距step的两数符合从小到大的顺序,倍减步长,重复上面分组,直到步长为1,即将所有记录放在一组进行一次直接插入排序,最终将所有记录重新排列成按关键字有序的序列。

  3. 示例:对4 1 10 2 16 9 3 14进行希儿排序的过程:
  • 因为关键字有8个,第一次步长step
    = 8 / 2 = 4

    初始:4
    1
    10 2
    16
    9
    3 14

    一趟:4
    1
    3 2
    16
    9
    10 14
    (只有10,3这一组不符合,按升序排列)

  • 第二次步长step = 4 / 2 = 2

初始:4
1 3 2
16 9
10 14

二趟:3
1 4 2
10 9
16 14
(2组都按升序排列)

  • 第三次步长step = 2 / 2 = 1

    初始:3 1 4 2 10 9 16 14

    三趟:1 2 3 4 9 10 14 16
    (按升序排列)

代码如下所示


1.  
/**

2.  
 *
希尔排序算法

3.  
 *

4.  
 *
@author
stecai

5.  
 */

6.  
public
class ShellSort {

7.  
   
/**

8.  
   
 * 对数组中指定的元素进行排序

9.  
   
 *

10. 
   
 * @param arr
待排序的数组

11. 
   
 */

12. 
   
public
static
void sort(Integer[] arr) {

13. 
       
//
给size指定数组的长度

14. 
       
int size = arr.length;

15.

16. 
       
// step是给定的增量值当增量为一时,所有数据放在同一组中

17. 
       
for (int
step = size / 2; step >= 1; step /= 2) {

18. 
           
//
从step开始,循环扫描至末尾

19. 
           
for (int
i = step; i < size; i++) {

20. 
               
int k;

21. 
               
int temp = arr[i];

22.

23. 
               
//
循环判断

24. 
               
for (k = i - step; k >= 0 && arr[k] > temp; k -= step) {

25. 
                   
arr[k + step] = arr[k];

26. 
               
}

27.

28. 
               
arr[k + step] = temp;

29. 
           
}

30. 
       
}

31. 
   
}

32.  
}

(六)
快速排序

  1. 基本思想:

    通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

    θ(n)。

  2. 排序过程:

    设要排序的数组是A[0]……A[N-1]。

  1. 设置两个变量i、j,排序开始的时候:i=0,j=N-1;
  2. 以第一个数组元素作为关键数据,赋值给key,即key=A[0];
  3. 从j开始向前搜索,即由后开始向前搜索(j--),找到第一个小于key的值A[j],将A[j]和A[i]互换;
  4. 从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于key的A[i],将A[i]和A[j]互换;
  5. 重复第3、4步,直到i=j;
    (3,4步中,没找到符合条件的值,即3中A[j]不小于key,4中A[i]不大于key的时候改变j、i的值,使得j=j-1,i=i+1,直至找到为止。找到符合条件的值,进行交换的时候i,
    j指针位置不变。另外,i==j这一过程一定正好是i+或j-完成的时候,此时令循环结束)。
  1. 示例:对36 23 87 16 11
    进行快速排序的过程:

    初始:36 23 87 16 11
    (i = 0, j = 4, key = 36)

    一趟:11
    23 87 16 11  (i = 0, j = 4, j位置覆盖i位置)

    二趟:11 23 87 16
    87  (i = 2, j = 4, i++, i位置是比key大,i覆盖j位置)

    三趟:11
    23 1616 87
     
    (i = 2, j = 3, j--, j位置比key小,j覆盖i位置)

    四趟:11 23 16
    3687  (i = 3, j = 3, i++, i == j, key覆盖i位置)

    递归:左边 11 23 16

    右边 87

代码如下所示


1.  
/**

2.  
 *
快速排序算法

3.  
 *

4.  
 *
@author
stecai

5.  
 */

6.  
public
class QuickSort {

7.  
   
/**

8.  
   
 * 待排序数组

9.  
   
 *

10. 
   
 * @param arr
待排序的数组

11. 
   
 * @param low
低指针

12. 
   
 * @param high
高指针

13. 
   
 */

14. 
   
public
static
void
sort(Integer[] arr, int
low, int high) {

15. 
       
int i;

16.

17. 
       
//
如果low小于high则循环

18. 
       
if (low < high) {

19. 
           
//
给定中间值

20. 
           
i = partition(arr, low, high);

21.

22. 
           
//
递归左半部分

23. 
           
sort(arr, low, i - 1);

24.

25. 
           
//
递归右半部分

26. 
           
sort(arr, i + 1, high);

27. 
       
}

28. 
   
}

29.

30. 
   
/**

31. 
   
 * 快速排序,给定中间值

32. 
   
 *

33. 
   
 * @param arr
待排序的数组

34. 
   
 * @param low
低指针

35. 
   
 * @param high
高指针

36. 
   
 * @return
调整后中枢位置

37. 
   
 */

38. 
   
private
static
int partition(Integer[] arr,
int low,
int high) {

39. 
       
//
取最小的值作为比较开始值

40. 
       
int pivot = arr[low];

41.

42. 
       
while (low < high) {

43. 
           
while (low < high && arr[high] >= pivot) {

44. 
               
//
如果高位大于pivot则high--

45. 
               
high--;

46. 
           
}

47.

48. 
           
//
跳出循环后直接将a[high]的值赋给a[low],并且low自加

49. 
           
if (low < high) {

50. 
               
arr[low] = arr[high];

51. 
               
low++;

52. 
       
    }

53.

54. 
           
while (low < high && arr[low] < pivot) {

55. 
               
//
往反方向开始扫描,如果a[low]小于
pivot则low++

56. 
               
low++;

57. 
           
}

58.

59. 
           
//
跳出循环后直接将a[low]的值赋给a[high],并且high自减

60. 
           
if (low < high) {

61. 
               
arr[high] = arr[low];

62. 
               
high--;

63. 
           
}

64. 
       
}

65.

66. 
       
arr[high] = pivot;

67.

68. 
       
//
返回中间值

69. 
       
return low;

70. 
   
}

71.  
}

(七)
归并排序

  1. 基本思想:

    归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide
    and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序,称为二路归并

  2. 排序过程:

    比较a[i]和a[j]的大小,若a[i]≤a[j],则将第一个有序表中的元素a[i]复制到r[k]中,并令i和k分别加上1;否则将第二个有序表中的元素a[j]复制到r[k]中,并令j和k分别加上1,如此循环下去,直到其中一个有序表取完,然后再将另一个有序表中剩余的元素复制到r中从下标k到下标t的单元。归并排序的算法我们通常用递归实现,先把待排序区间[s,t]以中点二分,接着把左边子区间排序,再把右边子区间排序,最后把左区间和右区间用一次归并操作合并成有序的区间[s,t]。

  3. 示例:对4 1 10 2 16 9 3 14
    进行插入归并的过程:

    初始:4 1 10 2 16 9 3 14

    一趟:[1, 4], [2, 10], [9, 16], [3, 14]

    二趟:[1, 2, 4, 10], [3, 9, 14, 16]

    三趟:[1, 2, 3, 4, 9, 10, 14, 16]

代码如下所示


1.  
/**

2.  
 *
归并排序算法

3.  
 *

4.  
 *
@author
stecai

5.  
 */

6.  
public
class MergeSort {

7.  
   
/**

8.  
   
 * 将两个(或两个以上)有序表合并成一个新的有序表

9.  
   
 *

10. 
   
 * @param arr
待排序数组

11. 
   
 * @param low
低指针

12. 
   
 * @param high
高指针

13. 
   
 * @return
输出有序数组

14. 
   
 */

15. 
   
public
static
int[] sort(int[]
arr, int low,
int high) {

16. 
       
int mid = (low + high) / 2;

17.

18. 
       
if (low < high) {

19. 
           
//
左边

20. 
           
sort(arr, low, mid);

21. 
           
//
右边

22. 
           
sort(arr, mid + 1, high);

23. 
           
//
左右归并

24. 
           
merge(arr, low, mid, high);

25. 
       
}

26.

27. 
       
return arr;

28. 
   
}

29.

30. 
   
/**

31. 
   
 * 数组合并,合并过程中对两部分数组进行排序

32. 
   
 *

33. 
   
 * @param arr
待排序数组

34. 
   
 * @param low
低指针

35. 
   
 * @param mid
中间值

36. 
   
 * @param high
高指针

37. 
   
 */

38. 
   
private
static
void merge(int[]
arr, int low,
int mid,
int high) {

39. 
       
int[] temp =
new
int[high - low + 1];

40. 
       
//
左指针

41. 
       
int i = low;

42. 
       
//
右指针

43. 
       
int j = mid + 1;

44. 
       
int k = 0;

45.

46. 
       
//
把较小的数先移到新数组中

47. 
       
while (i <= mid && j <= high) {

48. 
           
if (arr[i] < arr[j]) {

49. 
               
temp[k++] = arr[i++];

50. 
           
} else {

51. 
               
temp[k++] = arr[j++];

52. 
           
}

53. 
       
}

54.

55. 
       
//
把左边剩余的数移入数组

56. 
       
while (i <= mid) {

57. 
           
temp[k++] = arr[i++];

58. 
       
}

59.

60. 
       
//
把右边边剩余的数移入数组

61. 
       
while (j <= high) {

62. 
           
temp[k++] = arr[j++];

63. 
       
}

64.

65. 
       
//
把新数组中的数覆盖nums数组

66. 
       
for (int
k2 = 0; k2 < temp.length; k2++) {

67. 
           
arr[k2 + low] = temp[k2];

68. 
       
}

69. 
   
}

70.  
}

运行实例比较


排序法


平均时间


最差情形


稳定度


额外空间


备注


冒泡


O(n2)


O(n2)


稳定


O(1)


n小时较好


选择


O(n2)


O(n2)


不稳定


O(1)


n小时较好



O(nlogn)


O(nlogn)


不稳定


O(1)


n大时较好


插入


O(n2)


O(n2)


稳定


O(1)


大部分已排序时较好


希尔


O(nlogn)


O(ns) 1<s<2


不稳定


O(1)


s是所选分组


快速


O(nlogn)


O(n2)


不稳定


O(nlogn)


n大时较好


归并


O(nlogn)


O(nlogn)


稳定


O(1)


n大时较好

参考:

  1. http://wenku.baidu.com/view/bddf836cbe23482fb4da4c38.html
  2. http://wenku.baidu.com/view/6382f3bfc77da26925c5b043.html
  3. http://wenku.baidu.com/view/4c2890abdd3383c4bb4cd255.html
  4. http://wenku.baidu.com/view/56306f0303d8ce2f006623bf.html
  5. http://wenku.baidu.com/view/192e6f0e763231126edb11e3.html
  6. http://wenku.baidu.com/view/4a0c4718f12d2af90342e60c.html
  7. http://baike.baidu.com/link?url=ahN1k6xgm0rpMiS7KDHxNWLobbiH7WLBgB92qShxsycCH_S4LY8bC-RKoU1MHCc7MIAYNqwD1NndnCgeAdnXRq
时间: 2024-11-05 12:25:35

排序算法总结(java)的相关文章

7种基本排序算法的Java实现

7种基本排序算法的Java实现 转自我的Github 以下为7种基本排序算法的Java实现,以及复杂度和稳定性的相关信息. 以下为代码片段,完整的代码见Sort.java 插入排序 1 /** 2 * 直接插入排序 3 * 不稳定 4 * 时间复杂度:O(n^2) 5 * 最差时间复杂度:O(n^2) 6 * 空间复杂度:O(1) 7 * 使用场景:大部分元素有序 8 * @param elements 9 * @param comparator 10 * @param <T> 11 */ 1

[转]各种排序算法及其java程序实现

原文:http://blog.csdn.net/t12x3456/article/details/7430700 各种排序算法:冒择路(入)兮(稀)快归堆,桶式排序,基数排序 冒泡排序,选择排序,插入排序,稀尔排序,快速排序,归并排序,堆排序,桶式排序,基数排序 一.冒泡排序(BubbleSort)1. 基本思想: 两两比较待排序数据元素的大小,发现两个数据元素的次序相反时即进行交换,直到没有反序的数据元素为止.2. 排序过程: 设想被排序的数组R[1..N]垂直竖立,将每个数据元素看作有重量的

常见排序算法总结(java实现)

所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作.常见的排序算法有选择排序,插入排序,希尔排序,归并排序和快速排序 由于在排序的过程中不可避免的要涉及到比较和交换,所以将他们抽取为两个单独的函数,如下所示 //为了排序代码的通用性,这里假定待排序的元素实现了Comparable接口 private static boolean less(Comparable v ,Comparable w){ return v.compareTo(w)<0; } priva

排序算法----快速排序java

快速排序是对冒泡排序的一种改进,平均时间复杂度是O(nlogn) import java.util.Arrays; import java.util.Scanner; public class test02{ public static void main(String[] args) { int n = 1; while (n != 0){ Scanner scanner = new Scanner(System.in); n = scanner.nextInt(); int s[] = ne

经典排序算法(Java版)

经典排序算法(Java版)  转载 1.冒泡排序 Bubble Sort最简单的排序方法是冒泡排序方法.这种方法的基本思想是,将待排序的元素看作是竖着排列的“气泡”,较小的元素比较轻,从而要往上浮.在冒泡排序算法中我们要对这个“气泡”序列处理若干遍.所谓一遍处理,就是自底向上检查一遍这个序列,并时刻注意两个相邻的元素的顺序是否正确.如果发现两个相邻元素的顺序不对,即“轻”的元素在下面,就交换它们的位置.显然,处理一遍之后,“最轻”的元素就浮到了最高位置:处理二遍之后,“次轻”的元素就浮到了次高位

几大排序算法的Java实现

很多的面试题都问到了排序算法,中间的算法和思想比较重要,这边我选择了5种常用排序算法并用Java进行了实现.自己写一个模板已防以后面试用到.大家可以看过算法之后,自己去实现一下. 1.冒泡排序:大数向下沉,小数向上浮. package TestProject; /** * 冒泡排序 * @author xuhui * */ public class SortAll { public static void main(String[] args){ int[] a = {0,8,1,2,8,6,1

算法基础——经典八大排序算法的Java及Python实现

概述 八大排序算法不用多说了,程序员算法基础必须要掌握的,现在总结一下加深记忆.下图是这八大排序算法的分类.名称.时间空间复杂度,以及稳定性. 代码 以下是经典八大排序算法的Java及Python代码,都是基于经典算法书籍<算法导论>里的伪代码实现的,我在关键语句部分附上了注释. 按照上图中的顺序分别介绍八大排序算法的实现(升序),前面是Java,后面是Python.Java的排序函数写在了一个类里,Python的排序函数则直接写出来了. 直接插入排序 public class InsertS

程序员必须掌握的8大排序算法(Java版)

程序员必须掌握的8大排序算法(Java版) 提交 我的评论 加载中 已评论 程序员必须掌握的8大排序算法(Java版) 2015-07-28 极客学院 极客学院 极客学院 微信号 jikexueyuan00 功能介绍 极客学院官方帐号,最新课程.活动发布.欢迎大家反馈问题哟^_^ 本文由网络资料整理而来,如有问题,欢迎指正! 分类: 1)插入排序(直接插入排序.希尔排序) 2)交换排序(冒泡排序.快速排序) 3)选择排序(直接选择排序.堆排序) 4)归并排序 5)分配排序(基数排序) 所需辅助空

几大排序算法的Java实现(原创)

几大排序算法的Java实现 更新中... 注: 该类中附有随机生成[min, max)范围不重复整数的方法,如果各位看官对此方法有什么更好的建议,欢迎提出交流. 各个算法的思路都写在该类的注释中了,同时也方便各位进行本地环境验证. 目前已完成的排序算法有:冒泡排序.选择排序.插入排序. 暂时只提供这些排序算法的基本版,对算法的改进暂时不做考虑. 如果想看的更直观些,欢迎访问一个可视化的排序网站 import static org.junit.Assert.*; import java.util.

排序算法之 Java简单快速排序算法

package net.qh.test.sort; import java.util.ArrayList; import java.util.Calendar; import java.util.List; /** * Created by Administrator on 2016/03/01. */ public class SimpleQuick { public int[] sort(int[] arr,int left,int right){ if ( arr == null || a