冒泡排序

原理:比较相邻两个数,假如前面的数大于(小于)后边的数,则二者交流方位,直到止境,重复(N-1)次,得到一个有序数列
算法复杂度:O(n^2)
排序进程:

  • 源数据: 7, 8, 3, 26, 99, 91
  • 第1轮: 7, 3, 8, 26, 91, 99
  • 第2轮: 3, 7, 8, 26, 91, 99
  • 数组c言语3轮: 3, 7, 8, 26, 91, 99
  • 第4轮: 3, 7, 8, 26, 91, 99
  • 第5轮: 3,排序算法c言语 7, 8, 2giti6, 91, 99
public class BubbleSort extends Sortgithub是干什么的 {
//冒泡排序
@Override
public void sort(int[] array) {
int length = array.length;
//recordValues(array,"数据:");
for (int i = 0; i < length - 1; i++) {
for (int j = 1; j < length - i;数组的界说 j++) {
//契合条件,gitee交流方位
if (array[j - 1] > array[j]) {
int tem = array[j];
arr复杂度比较ay[j] = array[j - 1];
array[j - 1] = tem;
}
}
//recordgit教程Values(array,"第"+(i+1)+"轮:");
}
}
}

刺进排序

原理:将一个数刺进到一个有序数列,得到一排序算法复杂度个新的有序数列
算法复杂度:O(n^2)
排序进程:

  • 源数据: 7, 8, 3, 26, 99, 91
  • 第1轮: 7, 8, 3, 26, 99, 91
  • 第2轮: 3, 7, 8, 26, 99, 91
  • 第3轮: 3, 7, 8, 26, 99, 91
  • 第4轮: 3, 7, 8,排序算法可视化 26, 99复杂度比较, 91
  • 第5轮: 3, 7, 8, 26, 91, 99
public class InsertionSort extends Sort {
@Override
public void sort(int[] array) {
// recordValues(arragithub永久回家地址y,"数据:");
int length =array.length;
for(int i=1;i<length;i++){
int tem =array[i];
int j=i-1;
for(;j>=0;j--){
if(tem<array[j]){
array[j+1] =array[j];
}else {
break;
}
}
array[j+1] =tem;
//rec数组和链表的差异ordValues(array,"第"+(i)+"轮:");
}
}复杂度英文
}

挑选排序

原理:从无序数组中选出一个最大值(gitlab最小值),放进有序数组
算法复杂度:O(n^2)
排序进程:

  • 第1轮: 3, 8, 7, 26, 99, 91
  • 第2轮: 3, 7,排序算法c言语 8, 26, 99, 91
  • 第3轮: 3, 7, 8, 26, 99, 91
  • 第4轮: 3, 7, 8, 26, 99, 91
  • 第5轮: 3, 7, 8, 26, 91, 99
  • 第6轮: 3, 7, 8, 26, 91, 99
/**
* 挑选排序
*/
public class SelectionSort extends Sort {
public void sort(int[] arra复杂度符号y) {
int length = array.length;
for (int i = 0; i < length;giti轮胎 i++) {
//从剩余数组里挑选gitlab最小的
for (int j = 1 + i; j < length; j++) {
if (array[j] < array[i]) {
int tem = array[i];
array[i] = array[j];
arra复杂度比较y[j] = tem;
}
}
//recordValues(array,"第"+(i+1)+"轮:");
}
}
}
}

快排

原理:找关键值,然后将数列分红两个数列,一个大于等于关键值的,一个小于等于关键值的,然后再对这两个数列进行递归
算法复杂度:O(nlogn)
算法进程:

  1. 找基准数,并将基准放到排序后的方位
  2. 递归基准两头的数组

排序进程:

  • 源数据: 7 8 3 26 99数组 91
  • 基准7: 3 7 8 26 99 91
  • 基准数组和链表的差异8: 3 7 8 2复杂度6 99 91
  • 基准26: 3 7 8 2github永久回家地址6 99 91
  • 基准99: 3 7 8 26 91 99
public c算法lass QuickSo排序算法rt extends Sorgithub中文官网网页t {
//寻找基准
public int findPartition(int[] array, int left, int right) {
int pivot = array[left];
while (left < right) {
while (pivot <= array[right] &数组的界说amp;& left < right) {
right--;
}
array[left] =算法的五个特性 ar算法的五个特性ray[righ复杂度最高的是t];
array[right] = pivot;
while (pivo算法工程师t > array[left] && left &lgithubt; right数组函数的使用方法) {
left++;
}
array[算法的时刻复杂度是指什么right] = array[left];
array[left] = pivot;
}
array[left] = pivot;
//recordValues(array,"基准"+pivot+":");
return l算法规划与剖析eft;
}
//快排
private void qu算法的时刻复杂度取决于ickSort(int[] array, int left, int right) {
if (left < right) {
int mid = findPartition(array, left, right);
quickSogiteert(算法的五个特性agithub永久回家地址rray, left, mid - 1);
quickSort(array, mid + 1, right);
}
}
@Overrid复杂度o(1)什么意思e
public void sort(int[] array) {
// recordValues(array,"数据:");
quickSort(array, 0, array.复杂度核算length - 1);
}
}

归并排序

原理:选用的是分治战略,将大问题分解成小问题数组的界说,递归求解
算法复杂度:O(nlogn)
算法进程:

  1. 递归将数组分红两个数组,直至无法再分
  2. 将割裂的后的数组,进行吞并排序

排序进程:

  • 源数据 7, 8, 3, 26, 99, 91
  • 2为中心点 7, 8, 3, 26, 99, 91
  • 1为中心点 7, 8, 3, 26, 99, 91
  • 0为中心点 7, 8, 3, 26, 99, 91
  • 0数据吞并 7, 8, 3, 26, 99, 91
  • 1数据吞并 3, 7, 8, 26, 99, 91
  • 4为中心点 3, 7, 8, 26, 99, 91
  • 3为中心点 3, 7, 8, 26, 99, 91
  • 3数据吞并 3, 7, 8, 26, 99, 91
  • 4数据吞并数组 3, 7, 8, 26, 91, 99
  • 2数据吞并 3, 7, 8, 26, 91, 99

将排序进程简化:

  • 源数据 7 8 3 26 99 9算法工程师1
  • 以第三个算法工程师和程序员差异数将数组分为两个数组
  • 7,8,3 — 26,99,91
  • 持续均分数组
  • 7,8 — 3 — 26,99 — 91
  • 持续均分数组
  • 7 — 8 — 3 — 26 — 99 — 91
  • 数组吞并
  • 7,8 — 3 —算法的有穷性是指 26,99 — 91
  • 持续吞并
  • 3,7,8 — 26,91,99
  • 持续吞并
  • 3,7,8,26,91,99
public c数组函数的使用方法lass MergSort extends Sort {
//数组吞并
private void merg(int[] array, int left, int mid, int right) {gitee
int[] arrayTem = new int[right - left + 1];
int leftIndex = left;
int rightI数组函数的使用方法ndex = m排序算法有哪些id + 1;
int index = 0;
while (leftIndex <= mid &算法是什么& rightIndex <= right) {
if (array[leftIndex] < array[rightIndex]) {
arrayTem[index] = array[leftIndex];
leftIndex++;
} else {
arrayT复杂度英文em[index] = array[rightIndex];
r排序算法可视化ightIndex++;
}
index++;
}
while (leftIndex <= mid) {
arr算法的五个特性ayTem[index] = array[leftIndex];
leftIndex++;
index++;
}
while (rightIndex <= right) {
arrayTem[index]复杂度剖析 = array[rightIndex]数组函数的使用方法;
rightIndex++;
index++;
}
index = 0;
for (; left <= right; left++) {
array[left] = arrayTem[index];
ind算法导论ex++;
}
}
//排序
prgithub永久回家地址ivate void mergSort(复杂度最高的是int[] array, int left, int right) {
if (left != right) {
int mid = (left + right) / 2;
recordValue算法工程师s(array,""+mid+"为中心点");
mergSo算法的五个特性rt(array, left, mid);
mergSort(array, mid + 1, r排序算法的稳定性ight);
merg(array, left, mi复杂度排序d, right);
// recordValues(array,""+mid+"数据吞并算法工程师");
}
}
@Overri算法de
public void sort(int[] array)数组词 {
mergSort(array, 0, array.length - 1数组的界说);
}
}

堆排序

原理:和选复杂度核算择排序相似,仅仅将挑选巨细这一步用堆来实现
堆的性质

  • 是一个彻底二叉树

  • 每个git指令节点(非叶子节点)的值,都大于等于(小于等于)其孩子节点的值

    大顶堆:array[i] >=git指令 max(array[2i+1],array[2(i+1)])
    小顶堆:array[i] <= min(arra复杂度剖析y[2i+1],array[2(i+1)])

算法工程师法复杂度:O(nlogn)
算法进程:

  1. 构建堆
  2. 从堆顶选出最大(小)值(要注意堆的调整)

常见排序算法介绍

public class HeapSort extends Sort {
@Override
public void sort(int[] array) {数组
buildMaxHeap(array);
he排序算法流程图apSort(array);
}
//堆排序
private void heapSort(int[] array) {
i数组指针nt len = array.length;
for (int i = array.length - 1; i >= 0; i--) {
int tem = array[0];
array[0] = array[i];
array[i] = tem;
adJustMaxHeap(array, 0,排序算法c言语 --len);
}
}
//最大堆调整
void adJustMaxHeap(int[] array, int index, int len) {
int largest = index;
int left =giti轮胎 leftC数组hildIgit指令ndex(git教程index);
int right = rightChildIndex(index);
if (left >= len) {
return;
}
if (ar排序算法的时刻复杂度ray[left] > array[ind数组指针ex]) {
largest = left;
}
if (right < len && array[r排序算法ight] &排序算法有哪些gt; array[largest]) {数组排序
largest = right;
}复杂度比较
if (l算法工程师和程序员差异argest != index) {排序算法c言语
int tem = array[largest];
array[largest] = array[index];
arra复杂度最高的是y[index] = tem;排序算法有哪些
adJustMaxHeap(array, la数组c言语rgest, len);算法剖析的意图是
}
}
//构建最大堆
private void排序算法有哪些 buildMaxHea数组公式p(int[] array) {
int len = array.length;
for (int i = len / 2; i >= 0; i--) {
adJustMaxHeap(array,i,len);
}
}
//左孩子
private int leftChildIndex(int parent) {
return parent * 2 + 1;
}
//右孩子
private int right排序算法cChildIndex(int parent) {
return (parent + 1) * 2;
}git教程
}

希尔排数组的界说序(缩小增量排序)

原理:是刺进排序的一种优算法化,先将整个序列分割成若干子序列分别进行直接刺进复杂度o排序,待整个序列中数根本有序后,再进行一次刺进排序

  • 源数据: 7 8 3 26 99 91
  • 步长3: 7 8 3 26 99 91
  • 步长1: 3 7 8 26 91 99
public class ShellSort extends Sort {
@Over排序算法的时刻复杂度ride
public void sort(int[] array) {
recordValues(array,"源数据:");
int len = array.length;
for (int gap = len / 2; gap > 0; gap =数组 g复杂度最优ap / 2) {
for (int i = gap; i < len; i++) {
if (ar算法规划与剖析ray[i] < array[i - gap]) {
int k = i;
int tem = array[i];
while (k - gap >= 0 && tem < array[k - gap]) {
array[k] = array[k - gap];
k = k - gap;
}
a复杂度最优rgit教程ray[k] = tem;
}
}
//recordValues(array,"步长giti"+gap+":");
}
}
}

希尔排序的复杂度很大程度上由挑选的增量序列决议,如今没有最优的增量序列

计数排序

原理:不是经过数据比较来进行排序,经过核算数据呈现次数,然后根据核算个数排出序列
算法复杂度:O(n+k)
算法进程:

  1. 核算每个数据呈现的次数
  2. 将数据一次数组指针输出
publ算法导论ic class CoutNumSort extends Sort {
public stgithub永久回家地址atic int SIZE =100;
@Override
public void sort(int[] array) {
int[] countNum = new int[SIZE+5];
fo排序算法c言语r(int i=0;i<array.length;i++){
countNum[array[i]]复杂度剖析++;
}
int index =0;
for(int i =0;i<SIZE;i++){
for(int j=0;j<countNum[i];j++){
a数组指针rray[ind数组指针ex]=i;
index++;
}
}
// recordValu数组去重es(array,"排序作用");
}
}

空间优化:选出最大值和最小值,将核算数组巨细开为 max-m排序算法的时刻复杂度in+1(这种优化和数据联络数组c言语很大)

public class Co复杂度比较utNumSort extendgitis Sort {
public static int SIZE =100;
@Override
public void sort(int[] array) {
int min,max;
min =max=array[0];
for(int i=0;i<array.length;i++){
if(min>array[i]){
min =array[i];
}
if(max<array[i]){
max=array[i];
}
}
int[] countNum = new int[max-min+1];
for(int i=0;i<array.length;i++){
countNum[array[i]-mi算法的时刻复杂度取决于n]++;
}
int index =0;
SI算法的五个特性ZE =max-min+1;
for(int i =0;复杂度剖析i<SIZE;i++){
fo算法r(int j=0;j<countNum[i];j++){
array[index]=i+min;
index++;
}
}
//recordValues(array,"排序作用");
}
}

怎样保证相同数据按照原本数据摆放

public class CoutNumSort extends Sort {
public static int SIZE =100;
@Override
pub复杂度最高的是lic void sort(int[] array) {
//这一部分作空间的优化
in数组指针t算法的时刻复杂度取决于 min,max;
min =max=array数组指针[0];
for(int i=0;i<array.length;i++){
if(min>a数组c言语rray[i]){
min =array[i]复杂度核算;
}
if(max<array[i]){
max=array[i];
}
}
int[] countNum = ne数组去重w int[max-min+1];
//数据核算
for(int i=0;i<array.length;i++){
countNum[array[i]-min]++;
}
//确认方位,坚持原有次序复杂度o(1)什么意思
for(int i=1;i<复杂度ocountNum.length;i++){
countNum[i]+=countNum[i-1];
}
int[] result = new int[array.length];
for(int i =array.length-1;i>=0;i--){
result[c数组排序ountNum[array[i]-min]-1] =array[i];
coun排序算法复杂度tNum[array[i]-min]--;
}
// recordValues(result,"排序作用:");
}
}

计数排序的局限性

计数排序主要被数据最大值和最小值的差值给约束住了,当差值较大时,就意味着算法工程师申请更多的空间,造成很多的糟蹋,
但在核数组和链表的差异算数值在一个固定规划的数据,比方身高,分数,体重之类的,功率仍是比较高的。

基数排序复杂度比较

原理:从低位到高位过比较每个排序算法的稳定性数据数位的值进行的排序,利用了计数排序
算法复杂度:O(n*m)

  • 数据: 7 8 3 26 99算法是什么 91
  • 第1轮:排序算法可视化 91 3 26 7 8 99
  • 第2轮: 3 7 8 26 91 99
public class RadixSort extends Sort {
@Override
public void sort(int[] a算法剖析的意图是rray) {
recordValues(array,"数据:");
int arrayLength = array.length;
int[] temArray = new int[arrayLength];
int[] bucks = new int[10];
i算法导论nt[] weights = new i数组函数的使用方法nt[8];
weights[0] = 1;
int numLength = maxLength(array);
initWeight(weights, numLength);
for (int i = 0; i < numLength; i++) {
//置空
for (int j = 0; j < bucks.复杂度排序length; j++) {
b复杂度最高的是ucks[j] = 0;
}
for (int j = 0;gitee j < array.length; j++) {
int digit = getDigit(array[j], w排序算法的时刻复杂度eights[i]);
bucks[digit]+数组去重+;
}排序算法
for (int j = 1; j复杂度 < bucks.length; j++) {
bucks[jgiti轮胎] += bucks[j - 1];
}
for (int复杂度符号 j = arrayLeng复杂度核算th - 1;github中文官网网页 j >= 0; j--) {
int digit = getDigit(array[j]排序算法总结, weights[i]);
temArray[bucks[digit] - 1] = array[j];
bucks[digit]--;数组的界说
}
for (int j = 0; j < array.length; j++) {
array[复杂度最高的是j] = temArr数组词ay[j];
}
recordV数组alues(array,"第"+(i+1)+"轮:");
}
}
//权重初始化
private void initWeight(int[] weights, int len) {
for (int i = 1; i <= len; i数组去重++) {
weights[i] = weights[i - 1] * 10;复杂度最优
}gitee
}
//最大长度排序算法c
private int maxLength(int[] array) {
int maxNum = array[0];
for (int i = 0; i < array.length; i++) {
if算法导论 (maxNum < array[i]) {
maxNum = array[排序算法流程图i];
}
}
return Integer.toHexString(maxNum).length();
}
//获取权重上数字
private int getD复杂度核算igit(排序算法有哪些int num, int weight) {
return (num / weight) % 10;
}
}

总结

排序算法 时刻复杂度 最差时刻 空间算法工程师和程序员差异复杂度 安稳性
冒泡排序 O(n2) O(n2) 1 算法是什么
挑选排序 O(n2) O(n2) 1 安稳
复杂度英文入排序 O(github永久回家地址n2) O(n2) 1排序算法c 安稳
快排 O(nlogn) O(n2) logn 不安稳
归并排序 O(nlogn) O(nlogn) n 安稳
堆排序 O(nlogn) O(nlogn) 1 不安稳
计数排序 O(n+k) O(n+k) n+k 安稳
基数排序 O(n*d) O(n*d) n+k 安稳
  • 排序算法当n值较小的时分,O(n2)和O(算法工程师nlogn)功率差不多,O(n2)甚至优于O排序算法可视化(nlogn)。
  • 当n值较大时O(n2)算法将不能挑选,通常情况下快排会优于其他排序算法可视化n(logn)算法。