版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/tanliqing2010/article/details/79641840
复杂度总结
一、冒泡排序
1、基本思想
- 比较相邻的两个元素,前面元素比后面大,就交换两个元素,一轮下来就可以得出最后一个元素就是最大的元素。
2、动态图
3、代码
/*************************************************************************
> File Name: BubbleSort.java
> Author:
> Mail:
> Created Time: Wed 21 Mar 2018 04:33:15 PM CST
************************************************************************/
import java.util.Arrays;
public class BubbleSort{
public void sort(int[] arr){
int length = arr.length;
int tmp;
for(int i = 0 ; i < length ; i++){
for(int j = 1 ; j < length-1-i;j++){
if (arr[j]>arr[j+1]){
tmp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tmp;
}
}
}
}
public static void main(String[] args){
int[] arr = {1,10 ,30,2,3,9,8,7,16};
BubbleSort sort =new BubbleSort();
sort.sort(arr);
System.out.println(Arrays.toString(arr));
}
}
二、选择排序
1、基本思想
- 把数据分为有序区和无序去
- 在无序区找到最小元素,然后放在有序区的末尾
- 需要标记无序区中最小元素的下标
2、动态图
3、代码
/*************************************************************************
> File Name: SelectSort.java
> Author:
> Mail:
> Created Time: Wed 21 Mar 2018 05:11:39 PM CST
************************************************************************/
import java.util.Arrays;
public class SelectSort{
public void sort(int[] arr){
int len = arr.length;
int k ;
for(int i = 0 ; i < len -1 ; i++){
k = i;
for(int j = i+1 ; j < len ;j++){
if (arr[k] > arr[j]){
k = j;
}
}
swap(arr , i , k);
}
}
public void swap(int[] arr , int i ,int j){
if ( i == j ) return;
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public static void main(String[] args){
int[] arr = {5,1,4,6,30,20,10,38};
SelectSort sort = new SelectSort();
sort.sort(arr);
System.out.println(Arrays.toString(arr));
}
}
三、插入排序
1、基本思想
- 认为第一个元素是已经排序好的,认为是一个有序区,之后的元素认为是一个无序区
- 取出无序区的第一个元素,从后向前与有序区元素进行比较,找到正确的位置就插入到该位置
2、动态图
3、代码
/*************************************************************************
> File Name: InsertSort.java
> Author:
> Mail:
> Created Time: Wed 21 Mar 2018 05:37:09 PM CST
************************************************************************/
import java.util.Arrays;
public class InsertSort{
public void sort(int[] arr){
int current ;
for(int i = 1 ; i < arr.length ; i++){
// 记录无序区的第一个元素,
current = arr[i];
int j = i -1;
// 1、从后往前循环有序区,找到current的位置
// 2、无序区需要做移动 , 其中i位置就是一个空位了
while(j >= 0 && arr[j] > current){
// 前面的元素往后移动
arr[j+1] = arr[j]
j--;
}
// 上面的while循环执行了j--操作
arr[j+1] = current;
}
}
public static void main(String[] args){
int[] arr = {2 ,1 ,4 ,6,3,40,32,12};
InsertSort sort = new InsertSort();
sort.sort(arr);
System.out.println(Arrays.toString(arr));
}
}
四、希尔排序
1、基本思想
2、动态图
3、代码
五、归并排序
1、基本思想
- 两个连续有序区间的合并动作
- 切分成足够小
- 递归思想
2、动态图
3、代码
/*************************************************************************
> File Name: MergeSort.java
> Author:
> Mail:
> Created Time: Thu 22 Mar 2018 10:51:33 AM CST
************************************************************************/
import java.util.Arrays;
public class MergeSort{
public void sort(int[] arr){
int[] auxArr = new int[arr.length];
mergeSort(arr , auxArr , 0 , arr.length - 1);
}
public void mergeSort(int[] arr, int[] auxArr , int low , int high){
int divideIndex = 0;
if(low < high){
divideIndex = (low + high) / 2 ;
mergeSort(arr , auxArr , low , divideIndex);
mergeSort(arr , auxArr , divideIndex + 1 , high);
merge(arr , auxArr , low , divideIndex , high);
}
}
public void merge(int[] arr , int[] auxArr , int low , int divideIndex , int high){
int i = low ;
int j = divideIndex + 1;
int k = 0;
// 左右两边都是有序的,合并,放置在临时数组中
while(i <= divideIndex && j <= high){
if (arr[i] > arr[j]){
auxArr[k++] = arr[j++];
}else{
auxArr[k++] = arr[i++];
}
}
// 左边还有数据多
while(i <= divideIndex){
auxArr[k++] = arr[i++];
}
// 右边还有数据多
while( j <= high ){
auxArr[k++] = arr[j++];
}
// 把临时数组中的放回原数组中
for(k=0 ,i=low ; i<=high;i++,k++){
arr[i] = auxArr[k];
}
}
public static void main(String[] args){
int[] arr = {94,12,34,76,26,9,0,37,55,76,37,5,68,83,90,37,12,65,76,49};
MergeSort sort = new MergeSort();
sort.sort(arr);
System.out.println(Arrays.toString(arr));
}
}
六、快速排序
1、基本思想
- 选取一个基准值
- 比基准值小的放在左边,大的放在右边
- 递归
2、动态图
3、代码
/*************************************************************************
> File Name: QuickSort.java
> Author:
> Mail:
> Created Time: Thu 22 Mar 2018 04:10:22 PM CST
************************************************************************/
import java.util.Arrays;
public class QuickSort{
public void quickSort(int[] arr){
sort(arr , 0 , arr.length - 1);
}
public void sort(int[] arr , int low , int high){
int index;
if(low < high){
index = partition(arr , low ,high);
sort(arr , low , index -1);
sort(arr , index + 1 , high);
}
}
public int partition(int[] arr , int i ,int j){
// 保存基准值,留出空位
int key = arr[i];
// 两个指针不能有交集
while(i < j){
// j指针往前走
while(i < j && arr[j] >=key){
j--;
}
if(i < j){
// j所在位置元素不满足条件,那么就放到前面,现在的空位就是j了
arr[i] = arr[j];
i++;
}
// i指针往后走
while(i< j && arr[i] <= key){
i++;
}
if(i < j){
//
arr[j] = arr[i];
j--;
}
}
arr[i] = key;
return i;
}
public static void main(String[] args){
int[] arr = {3, 4 , 20 ,1,5, 6,15,40,32};
QuickSort sort = new QuickSort();
sort.quickSort(arr);
System.out.println(Arrays.toString(arr));
}
}
七、堆排序
1、基本思想
- 把数组看成是一颗完全二叉树
- 最大堆: 父节点总是比子节点大;建堆的过程就是从树的中间开始调整树的结构
- 交换首尾元素,从树顶调整树的结构
2、动态图
3、代码
/*************************************************************************
> File Name: HeapSort.java
> Author:
> Mail:
> Created Time: Fri 23 Mar 2018 10:50:37 AM CST
************************************************************************/
import java.util.Arrays;
public class HeapSort{
public void sort(int[] arr){
int tmp ;
int len = arr.length;
buildHeap(arr);
for(int i = 0 ; i < len ; i++){
//交换第一个元素接最后一个元素
tmp = arr[0];
arr[0] = arr[len - 1 - i];
arr[len - 1 -i ] = tmp;
// 因为已经构建好了堆,现在只是调整了一个元素,那么从该元素的位置在进行微调即可
adjustHeap(arr , 0 , len -1 - i);
}
}
public void buildHeap(int[] arr){
int pos = (arr.length - 1) / 2;
// 构建堆,需要从下面往上面进行调整
for(int j = pos ; j>=0 ; j--){
adjustHeap(arr , j , arr.length -1 );
}
}
/**
* pos 待调整节点的索引
* length 待调整堆节点的数量
*/
public void adjustHeap(int[] arr , int pos , int length){
// 初始化左孩子节点索引
int i = pos * 2 + 1;
int tmp;
// 只要存在左孩子节点,就一直循环
while(i < length){
// 保存父节点,留出空位
tmp = arr[pos];
// 如果存在右孩子节点,且比左节点大
if( i+1 < length && arr[i+1] > arr[i] ){
i++;
}
// 与最大孩子节点进行比较,如果大,就交换一下
if(arr[i] > arr[pos]){
arr[pos] = arr[i];
arr[i] = tmp;
}else{
// 这里就是没有做交换,那么就不会在去孩子节点了
break;
}
// 因为交换了,那么孩子节点就存在不满足的情况了,需要更新父节点和孩子节点索引
pos = i;
i = 2 * pos + 1;
}
}
public static void main(String[] args){
int[] arr = {10 ,3 ,4,2,30, 20 ,11 ,28 , 18} ;
HeapSort sort = new HeapSort();
sort.sort(arr);
System.out.println(Arrays.toString(arr));
}
}