摘要:
数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率。
目录:
- 冒泡排序
- 选择排序
- 直接插入排序
- 二分法插入排序
正文:
一. 冒泡排序
冒泡排序算法的运作如下:(从后往前)
- 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
- 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
- 针对所有的元素重复以上的步骤,除了最后一个。
- 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
Java版本冒泡排序:
/**
* 冒泡排序
* @param list
*/
public static void bubble_sort(Integer[] list) {
for (int i = 0; i < list.length; i++) {
for (int j = i; j < list.length; j++) {
if (list[i] <= list[j]) {
Integer temp = list[i];
list[i] = list[j];
list[j] = temp;
}
}
}
print_list(list);
}
Python版本冒泡排序:
# 冒泡排序
def bubble_sort(lis):
for i in range(len(lis)):
for j in range(i, len(lis)):
if lis[i] <= lis[j]:
temp = lis[i]
lis[i] = lis[j]
lis[j] = temp
return lis
运行结果:
原始数据:
2 9 8 13 56 98 77 3 8
冒泡排序后的结果:
98 77 56 13 9 8 8 3 2
二. 选择排序
工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。 选择排序是不稳定的排序方法(比如序列[5, 5, 3]第一次就将第一个[5]与[3]交换,导致第一个5挪动到第二个5后面)。
Java版本选择排序:
/**
* 选择排序
* @param list
*/
public static void selection_sort(Integer[] list) {
for (int i = 0; i < list.length; i++) {
Integer max = i;
for (int j = i + 1; j < list.length; j++) {
if (list[j] >= list[max]) {
max = j;
}
}
if (i != max) {
int temp = list[max];
list[max] = list[i];
list[i] = temp;
}
}
print_list(list);
}
Python版本选择排序:
# 选择排序
def selection_srot(lis):
for i in range(len(lis)):
max_result = i
for j in range(i+1, len(lis)):
if lis[j] >= lis[max_result]:
max_result = j
lis[max_result], lis[i] == lis[i], lis[max_result]
return lis
运行结果:
原始数据:
2 9 8 13 56 98 77 3 8
选择排序后的结果:
98 77 56 13 9 8 8 3 2
三. 直接插入排序
基本思想是:把待排序的纪录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的纪录插入完为止,得到一个新的有序序列。
Java版本直接插入排序:
/**
* 直接插入排序
* @param list
*/
public static void direct_insertion_sort(Integer[] list) {
for (int i = 1; i < list.length; i++) {
if (list[i] > list[i-1] ) {
int temp = list[i];
int k = i-1;
for (int j = k; j >=0 && temp > list[j]; j--) {
list[j+1] = list[j];
k--;
}
list[k+1] = temp;
}
}
print_list(list);
}
运行结果:
原始数据:
2 9 8 13 56 98 77 3 8
直接插入排序后的结果:
98 77 56 13 9 8 8 3 2
四. 二分插入排序
基本思想是:二分法插入排序是在插入第i个元素时,对前面的0~i-1元素进行折半,先跟他们中间的那个元素比,如果小,则对前半再进行折半, 否则对后半进行折半,直到left>right,然后再把第i个元素前1位与目标位置之间的所有元素后移,再把第i个元素放在目标位置上。
Java版本二分插入排序:
/**
* 二分法插入排序
* @param list
*/
public static void dichotomy_insertion_sort(Integer[] list) {
// 从数据的第二个元素开始排序,第一个元素默认是已排序
for (int i = 1; i < list.length; i++) {
// 初始化默认插入的位置是原位置
int index = i;
// 需要插入的元素
int target = list[i];
// 寻找插入的下标
if (list[i] > list[i-1]) {
int start = 0;
int end = i-1;
for(;start < end;){
int mid = (start + end) >>> 1;
if (list[mid] > target) {
start = mid +1;
}else {
end = mid-1;
}
}
if (list[start] > target) {
index = start+1;
}else {
index = start;
}
}
// 插入下标到i-1依次往后移1位
for (int j = i; j > index; j--) {
list[j] = list[j-1];
}
list[index] = target;
System.out.println("第" +i + "次排序");
print_list(list);
System.out.println();
}
System.out.print("最终排序结果:");
print_list(list);
}
运行结果:
原始数据:
2 9 8 13 56 98 77 3 8
二分法插入排序过程:
第1次排序
9 2 8 13 56 98 77 3 8
第2次排序
9 8 2 13 56 98 77 3 8
第3次排序
13 9 8 2 56 98 77 3 8
第4次排序
56 13 9 8 2 98 77 3 8
第5次排序
98 56 13 9 8 2 77 3 8
第6次排序
98 77 56 13 9 8 2 3 8
第7次排序
98 77 56 13 9 8 3 2 8
第8次排序
98 77 56 13 9 8 8 3 2
最终排序结果:98 77 56 13 9 8 8 3 2
结论:
各种排序方式的时间复杂度
后续把其他排序方式也手动实践一下,厚积薄发。
参考文献:
Java 实现二分(折半)插入排序