算法
一、算法的概述
二、排序算法
基本介绍
1. 排序算法的分类:
内部排序
:插入排序、选择排序、堆排序、冒泡排序、快速排序、归并排序、基数排序
->外部排序
:
2. 描述:
- 内部排序:
指将需要处理的所有都要加载到内部存储器中进行排序。
- 外部排序:
数据量过大,无法全部加载到内存中,需要借助外部存储进行排序
3. 时间频度:
时间频度: 一个算法话费的时间与算法种的语句执行次数成正比。哪个算法种语句执行次数多,他花费时间就多。一个算法的语句执行次数,称为语句 频度 或 时间频度。记为T(n)[举例说明]。
注意:忽略 常数项
,低次项
4. 时间复杂度
- 一般情况下,算法的基本操作语句的重复执行次数,是问题规模'n'的某个函数关系,用'T(n)'表示。
若有某个辅助函数'f(n)',使得当 n 趋近无穷大时,T(n)/f(n)的极限值为不等于零的常数,
则称'f(n)'是'T(n)'的同数量级函数。记'T(n)=O(f(n))', 'O(f(n))',算法的渐进时间复杂度,简称时间复杂度
- 'T(n)' 不同,但时间复杂度坑你相同,如:'T1(n)=n^2+7n+6' 和'T2(n)=n^2+3n+1',其实是时间复杂度,是同一个数量级的
常见的时间复杂度:
// 1. 线性阶:n
int i=0 ;
while(i<n){
// ...
i++;
}
// 2. 对数阶:O(log②N)
int i = 0;
while(i<n){
i *= 2
}
// 线性对数阶:O(nlogN)
int i=0,j;
while(i<n){
j=0 ;
while(j<m){
j *= 2 ;
}
i++ ;
}
常见算法的时间复杂度:
5. 空间复杂度:
基本介绍:
1. 冒泡排序
基本思想
通过对待排序序列从前向后
(从下标较小的元素开始),一次比较相邻元素的值,若发现逆序则交换,使值较大的元素逐渐从前向后移,就像水底下的气泡一样逐渐向上冒。
代码实现:
class BubbleSort{
/**
* 排序 --- 从小到大
* @param array
* @return
*/
public static int[] arraySort(int[] array){
int temp ;
for (int i=0 ;i<array.length-1;i++){ //外层循环控制排序趟数
for (int j=0 ;j<array.length-1-i;j++){ //内层循环控制每一趟排序多少次
if (array[j]>array[j+1]){
temp = array[j] ;
array[j] = array[j+1] ;
array[j+1] =temp ;
}
}
System.out.print("第"+i+"趟排序后的数组:");
System.out.println(Arrays.toString(array));
}
return array ;
}
/**
* 排序 --- 从小到大(优化)
* 结论:
* 在排序次数上,减少了;但在总的花费时间上可能更多
* @param array
* @return
*/
public static int[] arraySort3(int[] array){
int temp ;
boolean flag ; //标识是否进行或交换
for (int i=0 ;i<array.length-1;i++){ //外层循环控制排序趟数
flag = false ;
for (int j=0 ;j<array.length-1-i;j++){ //内层循环控制每一趟排序多少次
if (array[j]>array[j+1]){
flag = true ;
temp = array[j] ;
array[j] = array[j+1] ;
array[j+1] =temp ;
}
}
if (!flag){ //在一趟排序中,一次交换都没发生过
break;
}
System.out.print("第"+i+"趟排序后的数组:");
System.out.println(Arrays.toString(array));
}
return array ;
}
}
2. 选择排序:
基本思路
-
简单选择排序是最简单直观的一种算法,基本思想为每一趟从待排序的数据元素中选择最小(或最大)的一个元素作为首元素,直到所有元素排完为止,简单选择排序是不稳定排序。
-
在算法实现时,每一趟确定最小元素的时候会通过不断地比较交换来使得首位置为当前最小,交换是个比较耗时的操作。其实我们很容易发现,在还未完全确定当前最小元素之前,这些交换都是无意义的。我们可以通过设置一个变量min,每一次比较仅存储较小元素的数组下标,当 轮循环结束之后,那这个变量存储的就是当前最小元素的下标,此时再执行交换操作即可。代码实现很简单,一起来看下。
代码实现
class SelectSort{
/**
* 简单选择排序
* @param arr 数组
*/
public static void selectSort(int[] arr) {
for (int i = 0; i < arr.length - 1; i++) {
int min = i;//每一趟循环比较时,min用于存放较小元素的数组下标,这样当前批次比较完毕最终存放的就是此趟内最小的元素的下标,避免每次遇到较小元素都要进行交换。
for (int j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[min]) {
min = j;
}
}
//进行交换,如果min发生变化,则进行交换
if (min != i) {
swap(arr,min,i); //交换数组元素
}
}
}
}
3. 插入排序
基本思路
- 直接插入排序基本思想是每一步将一个待排序的记录,插入到前面已经排好序的有序序列中去,直到插完所有元素为止。
代码实现:
/**
* 插入排序
* @param arr 需要排序的数组
*/
public static void insertionSort(int[] arr) {
for (int i = 1; i < arr.length; i++) {
int j = i;
while (j > 0 && arr[j] < arr[j - 1]) {
swap(arr,j,j-1); //交换数组元素
j--;
}
}
}
4. 希尔排序(重难点)
参考网址:https://blog.csdn.net/qq_37592492/article/details/81157153
简单介绍
该方法因DL.Shell于1959年提出而得名。
- 1. `希尔排序(Shell Sort)`是`插入排序`的一种。也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。
- 2. 希尔排序是`非稳定排序算法`。
- 3. 希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,
每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。
基本定义:
(1). 基于插入排序的排序算法(插入排序的优化)
(2). 原因:对于大规模乱序数组插入排序很慢,因为它只会交换相邻的元素,因此元素只能一点一点地从数组的一端移动到另一端。例如:若值最小的元素正好在数组的尽头,要将它挪到正确的位置就要要进行 数组的长度-1 次移动。
(3). 希尔排序时先将任意间隔为h的元素都进行插入排序,同时,间隔h是一个递增序列中的一个值,且h按照递增序列递减,即这个h会随着每一次循环排序结束后越来越小,因此,排序的精度也会越来越高。
(4). 希尔排序的思想是使数组中任意间隔为h的元素都是有序的。这样的数组称为h有序数组。一个h有序数组就是h个互相独立的有序数组编织在一起组成的一个数组。
(5). 希尔排序更高效的原因是它权衡了子数组的规模和有序性。排序之初,各个子数组都很短,排序之后子数组都是部分有序的,这两种情况都很适合插入排序。
(6). 到现在为止,没有任何一个递增序列被发现是效率最高的,因此,透彻理解希尔排序的性能至今仍然是一个挑战。但我们还是知晓它的性能绝对是比一些初级排序高的。
基本思想:
- 希尔排序严格来说是基于插入排序的思想,又被称为缩小增量排序。
- 1、将包含n个元素的数组,分成n/2个数组序列,第一个数据和第n/2+1个数据为一对...
- 2、对每对数据进行比较和交换,排好顺序;
- 3、然后分成n/4个数组序列,再次排序;
- 4、不断重复以上过程,随着序列减少并直至为1,排序完成。
代码实现:
public class Test{
public static void main(String[] args) {
int[] ins = {2, 3, 5, 1, 23, 6, 78, 34, 23, 4, 5, 78, 34, 65, 32, 65, 76, 32, 76, 1, 9};
sort(ins);
System.out.println(Arrays.toString(ins));
}
public static void sort(int[] ins) {
int len = ins.length;
int gap = len >> 2;
int temp, j;
while (gap > 0) {
for (int i = gap; i < len; i++) {
temp = ins[j=i];
while (j - gap >= 0 && ins[j - gap] > ins[j]) {
ins[j] = ins[j -= gap];
}
ins[j] = temp;
}
gap >>= 1;
}
}
}