目录
相关文章
- 学习数据结构理论+算法时间复杂度
- 学习有序二叉树+平衡二叉树+红黑树
- 学习冒泡排序+选择排序并使用java写代码
- 学习插入排序+希尔排序并使用java写代码
- 学习堆排序+基数排序并使用java写代码
- 学习递归+归并排序+快速排序并使用java写代码
冒泡排序
把一个无序的数组变成有序的数组。
前后两两数据进行比较,大的数据往后走,小的数据往前走。
例子:
待排序组:5、7、4、2、0、3、6、1,用冒泡排序进行排序,步骤如下:
- 第一轮:
- 有两个游标卡尺分别指向5和7,让5和7进行比较,5<7,位置不动;
- 游标往后走,指向7和4,7>4,换位置;
- 游标往后走,指向7和2,7>2,换位置;
- 游标往后走,指向7和0,7>0,换位置;
- 游标往后走,指向7和3,7>3,换位置;
- 游标往后走,指向7和6,7>6,换位置;
- 游标往后走,指向7和1,7>1,换位置;
- 游标往后走,其中有一个游标没有数据指向,越界了,第一轮结束,7到达正确的位置;
- 有两个游标卡尺分别指向5和7,让5和7进行比较,5<7,位置不动;
- 第二轮:
- 两个游标卡尺分别指向5和4,5>4,换位置;
- 游标往后走,指向5和2,5>2,换位置;
- 游标往后走,指向5和0,5>0,换位置;
- 游标往后走,指向5和3,5>3,换位置;
- 游标往后走,指向5和6,5<6,位置不动;
- 游标往后走,指向6和1,6>1,换位置;
- 6到达正确位置,第二轮结束;
- 两个游标卡尺分别指向5和4,5>4,换位置;
- 一直这样两两比较,大的数据往后走,小的数据往前走;每一轮结束,一个数据到达正确位置,直到都到达正确位置。
时间复杂度:
轮次 | 比较次数 |
---|---|
第一轮 | x-1 |
第二轮 | x-2 |
第三轮 | x-3 |
第四轮 | x-4 |
…… | …… |
第k轮 | 1 |
y
=
(
x
−
1
)
+
(
x
−
2
)
+
(
x
−
3
)
+
(
x
−
4
)
+
⋯
+
1
=
(
x
−
1
)
+
(
x
−
2
)
+
(
x
−
3
)
+
(
x
−
4
)
+
⋯
+
(
x
−
(
x
−
1
)
)
y=(x-1)+(x-2)+(x-3)+(x-4)+\dots+1 =(x-1)+(x-2)+(x-3)+(x-4)+\dots+(x-(x-1))
y=(x−1)+(x−2)+(x−3)+(x−4)+⋯+1=(x−1)+(x−2)+(x−3)+(x−4)+⋯+(x−(x−1))
将求和顺序反过来,从
1
加到
x
−
1
:
y
=
1
+
2
+
3
+
⋯
+
(
x
−
1
)
将求和顺序反过来,从 1 加到 x - 1:y = 1 + 2 + 3 + \dots + (x - 1)
将求和顺序反过来,从1加到x−1:y=1+2+3+⋯+(x−1)
这是一个等差数列,首项
a
1
=
1
,末项
a
n
=
x
−
1
,项数
n
=
1
。
这是一个等差数列,首项 a_1 = 1,末项a_n = x - 1,项数n = 1。
这是一个等差数列,首项a1=1,末项an=x−1,项数n=1。
根据等差数列的公式:
S
=
n
(
a
1
+
a
n
)
2
S = \frac{n(a_1 + a_n)}{2}
S=2n(a1+an)代入得
y
=
(
x
−
1
)
(
1
+
(
x
−
1
)
)
2
=
x
2
−
x
2
y= \frac{(x - 1)(1 + (x - 1))}{2} = \frac{x^2-x}{2}
y=2(x−1)(1+(x−1))=2x2−x
得出时间复杂度是:
O
(
n
2
)
O(n^2)
O(n2)
java代码:
package com.xxx;
import java.util.Arrays;
//冒泡排序
public class BubbleSort {
public static void main(String[] args) {
//定义一个数组,数组的长度是8
int[] arr = {5,7,4,2,0,3,1,6};
//调用 BubbleSort 类中的 sort 方法,对传入的整数数组 arr 进行冒泡排序
sort(arr);
//打印结果
System.out.println(arr);//引用类型打印的是地址
System.out.println(Arrays.toString(arr));//使用打印方法,打印值
}
public static void sort(int[] arr) {
//有多少数据,进行多少轮循环
for(int j=0;j<arr.length;j++) {
//定义一个游标变量i
for(int i=0;i<arr.length-1;i++) {
//如果i>i+1,那么值进行交换
if(arr[i]>arr[i+1]) {
int temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
}
}
}
}
}
优化代码:
public static void sort(int[] arr) {
for(int j=0;j<arr.length;j++) {
//定义一个布尔变量 flag,用于标记本轮是否发生了交换,每轮开始时,假设没有发生交换
boolean flag = false;
//定义一个游标变量i
for(int i=0;i<arr.length-1;i++) {
//如果i>i+1,那么值进行交换
if(arr[i]>arr[i+1]) {
int temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
//发生了交换,标记 flag 为 true
flag = true;
}
}
//如果本轮没有发生交换,说明数组已经有序,提前结束排序
if (!flag) {
break;
}
}
}
选择排序
默认待排序数组中的第一个为最小值,找待排序数组中真正的最小值,真正的最小值和默认的最小值进行交换;每一轮可以让一个数据到达正确的位置。
例子:
待排序组:5、7、4、1、3、0、2、6,用选择排序进行排序,步骤如下:
- 往后面遍历,找到正真的最小值,两个数据进行交换:0与5交换位置;
- 交换后,0所在的位置不在遍历,从第二个位置开始,默认为最小值往后便利;
- 往后遍历,发现真正的最小值是1,1和7进行交换;
- 交换后,0和1所在的位置不在遍历,从第三个位置开始,默认为最小值往后便利;
- ……
- 往后一直遍历,一直到数值到达正确的位置,结束。
时间复杂度:
轮次 | 运算次数 |
---|---|
第一轮 | x-1 |
第二轮 | x-2 |
第三轮 | x-3 |
第四轮 | x-4 |
…… | …… |
第x-1轮 | 1 |
等差数列求和:
y
=
(
1
+
x
−
1
)
(
x
−
1
)
2
y=\frac{(1+x-1)(x-1)}{2}
y=2(1+x−1)(x−1)
得出时间复杂度是:
O
(
n
2
)
O(n^2)
O(n2)
java代码:
package com.xxx;
import java.util.Arrays;
//选择排序
public class SelectSort {
public static void main(String[] args) {
int[] arr = {5,7,4,1,3,0,2,6};
sort(arr);
System.out.println(Arrays.toString(arr));
}
public static void sort(int[] arr) {
for(int j=0;j<arr.length;j++) {
int min = arr[j];//记录当前位置是最小值
int position = j;//记录真正最小值的下标
//找到真正的最小值
for(int i=1+j;i<arr.length;i++) {
if(arr[i]<min) {
min =arr[i];
position = i;
}
}
//min里存的是真正的最小值
//position存的是真正最小值的下标
arr[position] = arr[j];
arr[j] = min;
}
}
}