您的位置:首页 > 理论基础 > 数据结构算法

个人数据结构与算法学习总结-排序算法(冒泡、选择、插入、希尔排序)

2020-06-06 07:08 302 查看

排序算法

本总结主要是以“尚硅谷Java算法教程”的学习教程为主,加上一些个人的理解

目录

排序算法(Sort Algorithm),是将一组数据,依指定的顺序进行排列 的过程。
排序的分类:
1) 内部排序:
指将需要处理的所有数据都加载到内部存储器中进行排序。
2) 外部排序法:
数据量过大,无法全部加载到内存中,需要借助外部存储进行
排序。
3) 常见的排序算法分类(见下图):
4)常见的算法时间复杂度由小到大依次为:Ο(1)<Ο(log2n)<Ο(n)<Ο(nlog2n)<Ο(n2)<Ο(n^3)< Ο(n^k) <Ο(2^n) ,随着问题规模n的不断增大,上述时间复杂度不断增大,算法的执行效率越低

算法的时间复杂度说明

1、常数阶Ο(1)

无论代码执行了多少行,只要是没有循环等复杂结构,那这个代码的时间复杂度就都是O(1)

int i=1;
int j=2;
++i;
j++;
int m=i+j;

2、对数阶O(log2n)

int i =1;
while(i<n)
{
i=i*2;
}

3、线性阶O(n)

for(i=1;i<=n;i++)
{
j=i;
j++;
}

4、线性对数阶O(nlogN)

for(m=1;m<n;m+)
{
i = 1;
while (i < n) {
i = i * 2;
}
}

5、平方阶O(n^2)

for(x=1;i<=n;x++)
{
for (i = 1; i <= n; i++) {
j = i;
j++;
}
}

6、立方阶O(n³)、K次方阶O(n^k)
如上

冒泡排序

1、算法思想

排序序列从前向后(从下标较小的元素开始),依次比较
相邻元素的值,若发现逆序则交换,使值较大
的元素逐渐从前移向后部

2、动图实现

3、代码实现

package datastructure.sort;

import java.util.Arrays;

public class BubbleSort {
public static void main(String[] args) {
int[] arr = {1, 3, 6, 2, 856, 23, -123, 4};
Bubble(arr);
System.out.println(Arrays.toString(arr));

}

public static void Bubble(int[] arr) {
int temp;//临时变量
boolean flag = false; // 标识变量,表示是否进行过交换
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length - 1 - i; j++) {
// 如果前面的数比后面的数大,则交换
if (arr[j] > arr[j + 1]) {
flag = true;
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}

}
if (!flag) {// 在一趟排序中,一次交换都没有发生过,则说明排序已经完成,退出
break;
} else {
flag = false; //否则,重置标识
}
}
}
}

选择排序

1、算法思维

1) 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置
2)再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
3)重复第二步,直到所有元素均排序完毕。

2、图示

3、代码如下

package datastructure.sort;

import java.util.Arrays;

public class SelectSort {
public static void main(String[] args) {
int[] arr = {1, 3, 6, 2, 856, 23, -123, 4};
select(arr);
System.out.println(Arrays.toString(arr));

}

public static void select(int[] arr) {

for (int i = 0; i < arr.length - 1; i++) {
int min = i; //设定初始最小值

for (int j = i; j < arr.length; j++) {
if (arr[min] > arr[j]) {//如果存在最小值,则记录最小值
min = j;
}
}
if (min != i) { //将最小值和每次循环的最初位置进行交换
int index = arr[i];
arr[i] = arr[min];
arr[min] = index;
}
}
}
}

插入排序

1、算法思想

1)将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。
2)从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。)

2、图解

3、代码实现

package datastructure.sort;

import java.util.Arrays;

public class InsertSort {
public static void main(String[] args) {
int[] arr = {1, 3, 6, 2, 856, 23, -123, 4};
insert(arr);
System.out.println(Arrays.toString(arr));

}
public static void insert(int[] arr){
int index =0;
int insertVal =0;
for(int i=1;i<arr.length;i++){
insertVal = arr[i];
index =i-1;
// 给insertVal 找到插入的位置
// 说明
// 1. insertIndex >= 0 保证在给insertVal 找插入位置,不越界
// 2. insertVal < arr[insertIndex] 待插入的数,还没有找到插入位置
// 3. 就需要将 arr[insertIndex] 后移
while(index >=0 && insertVal<arr[index]){
arr[index+1]=arr[index];
index--;
}
// 当退出while循环时,说明插入的位置找到, insertIndex + 1

//这里我们判断是否需要赋值
if(index + 1 != i) {
arr[index + 1] = insertVal;
}

}
}
}

希尔排序

1、算法思维

希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。但希尔排序是非稳定排序算法。
希尔排序是基于插入排序的以下两点性质而提出改进方法的:
1)插入排序在对几乎已经排好序的数据操作时, 效率高, 即可以达到线性排序的效率
2)但插入排序一般来说是低效的, 因为插入排序每次只能将数据移动一位
希尔排序的基本思想是:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。

2、图示

3、代码实现

package datastructure.sort;

import java.util.Arrays;

public class ShellSort {
public static void main(String[] args) {
int[] arr = {1, 3, 6, 2, 856, 23, -123, 4};
shell(arr);
System.out.println(Arrays.toString(arr));
}
public static void shell(int[] arr){
for(int gap=arr.length/2;gap>0;gap/=2)
// 遍历各组中所有的元素(共gap组)
for(int i =gap;i<arr.length;i++){
for(int j =i-gap;j>=0;j-=gap){
// 如果当前元素大于加上步长后的那个元素,说明交换
if(arr[j]>arr[j+gap]){
int temp=arr[j];
arr[j]=arr[j+gap];
arr[j+gap]=temp;
}
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐