整个数据结构被分为两部分,一部分为“排序”,一部位为“查找”。
排序就是将一串无意义的数据进行整理变成更有意义。关于排序算法主要分两类:比较排序,线性时间排序。比较排序依赖元素的比较和交换,找到合适的位置。线性排序依赖数据集合中的某些特征,所以不是所有场合都可以使用。
常用的排序包括:
1)冒泡排序:时间复杂度 O(n^2) 空间复杂度 O(1)
一种简单基础,但是低效的排序方式。两层for循环,内层每次相邻两个元素比较,外层每次循环判断出最大的元素。
2)插入排序:时间复杂度 O(n^2) 空间复杂度 O(1)
每次从未排序代数据集合中取出一个元素,插入到已排好序的集合中。外循环作基数,内循环保证基数左边的元素有序。
3)选择排序:时间复杂度 O(n^2) 空间复杂度 O(1)
两层for循环,外层每次循环判断出最小的元素,内层循环找到最小的元素放到指定位置。但是该排序不稳定。(不稳定的原因是相同元素的原顺序会被破坏)
4)归并排序:时间复杂度 O(n ) 空间复杂度 O(n)
该排序使用了分治算法,是冯·诺伊曼首次提出,让排序从平方复杂度优化到线性对数时间复杂度。是排序算法夸时代的意义。但是由于编码过于复杂就不写了。
5)快速排序:时间复杂度 O(n ) 空间复杂度 O(
)
根据冒泡排序衍化而来,效率比归并排序高。
寻找基准,比基准值大的放在基准值右边,比基准值小的,放在基准值左边。递归调用这个函数,使得整个数组有序。
冒泡排序代码:
//冒泡排序
public void sort() {
int[] nums = {23, 12, 34, 2, 67};
for (int i = 0; i < nums.length - 1; i++) {
//内循环减 i ,这是外循环每执行一次可以确保最大元素的位置
for (int j = 0; j < nums.length - 1 - i; j++) {
if (nums[j] > nums[j + 1]) {
int tmp = nums[j + 1];
nums[j + 1] = nums[j];
nums[j] = tmp;
}
System.out.println("内层 :第" + (j + 1) + "次排序后的结果:"+ Arrays.toString(nums));
}
System.out.println("外层 :第" + (i + 1) + "次排序后的结果:"+ Arrays.toString(nums));
}
}
插入排序代码:
//插入排序
private int[] insertSort(int[] arr) {
if (arr == null || arr.length < 2) {
return arr;
}
//i作为基数,每次要保证 i 左边的元素有序
for (int i = 1; i < arr.length; i++) {
//内循环每次保证 0~j 的元素是有序对的
for (int j = i; j > 0; j--) {
if (arr[j] < arr[j - 1]) {
int temp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = temp;
}
}
System.out.println("外层 :第" + (i) + "次排序后的结果:" + Arrays.toString(arrays));
}
return arr;
}
选择排序代码:
//选择排序
private void selectionSort(int[] arr) {
int len = arr.length;
int minIndex, temp;
for (int i = 0; i < len - 1; i++) {
minIndex = i; //每次都从已排序序列的末尾后一位开始
for (int j = i + 1; j < len; j++) {
if (arr[j] < arr[minIndex]) { //寻找最小的数
minIndex = j; //将最小数的索引保存
}
}
//放到已排序序列的末尾(即交换),该操作很有可能把稳定性打乱,所以选择排序是不稳定的排序算法
temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
System.out.println("外层 :第" + (i) + "次排序后的结果:" + Arrays.toString(arrays));
}
}
快速排序代码:
//快速排序
private void quickSort(int arr[], int left, int right) {
if (left >= right){
return;
}
int low = left; //(1)初始化
int high = right;
int temp;
temp = arr[low]; //(2)以第一个数组为比较值,保存到temp中
while (high > low) {
//(3)high--,找小值
while (high > low && arr[high] >= temp) high--;
arr[low] = arr[high]; //保存小值,到s[i]上
//(4)i++,找大值
while (high > low && arr[low] <= temp) low++;
arr[high--] = arr[low]; //保存大值 到s[high]上
}
//(5)将比较值放在s[i]上
arr[low] = temp;
/*(6)拆分成两个数组 s[0,i-1]、s[i+1,n-1]又开始排序 */
quickSort(arr, left, low - 1); //左
quickSort(arr, low + 1, right); //右
System.out.println("外层 :排序后的结果:" + Arrays.toString(arrays));
}