【海贼王的数据航海】排序——冒泡|快速|归并排序|总结

简介: 【海贼王的数据航海】排序——冒泡|快速|归并排序|总结

1 -> 交换排序

基本思想:所谓交换,就是根据序列中两个记录的键值的比较结果来对换这两个记录在序列中的位置,交换排序的特点是:将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动。

1.1 -> 冒泡排序

冒泡排序的特性总结:

  1. 冒泡序列是一种非常容易理解的排序
  2. 时间复杂度:
  3. 空间复杂度:
  4. 稳定性:稳定

1.1.1 -> 代码实现

#define  _CRT_SECURE_NO_WARNINGS 1
 
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
 
// 打印
void PrintArray(int* a, int n)
{
  for (int i = 0; i < n; i++)
    printf("%d ", a[i]);
 
  printf("\n");
}
 
// 冒泡排序
void BubbleSort(int* a, int n)
{
  for (int j = 0; j < n; ++j)
  {
    bool exchange = false;
    for (int i = 1; i < n - j; i++)
    {
      if (a[i - 1] > a[i])
      {
        int tmp = a[i];
        a[i] = a[i - 1];
        a[i - 1] = tmp;
 
        exchange = true;
      }
    }
 
    if (exchange == false)
    {
      break;
    }
  }
}

1.2 -> 快速排序

快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法,其基本思想为:任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止。

1.2.1 -> hoare版本

代码实现:

#define  _CRT_SECURE_NO_WARNINGS 1
 
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
 
// 交换
void Swap(int* x, int* y)
{
  int tmp = *x;
  *x = *y;
  *y = tmp;
}
 
// 打印
void PrintArray(int* a, int n)
{
  for (int i = 0; i < n; i++)
    printf("%d ", a[i]);
 
  printf("\n");
}
 
// 快速排序hoare版本
int PartSort1(int* a, int left, int right)
{
  int keyi = left;
  while (left < right)
  {
    // 右边找小
    while (left < right && a[right] >= a[keyi])
    {
      --right;
    }
 
    // 左边找大
    while (left < right && a[left] <= a[keyi])
    {
      ++left;
    }
 
    Swap(&a[left], &a[right]);
  }
 
  Swap(&a[keyi], &a[left]);
 
  return left;
}

1.2.2 -> 挖坑法

#define  _CRT_SECURE_NO_WARNINGS 1
 
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
 
// 交换
void Swap(int* x, int* y)
{
  int tmp = *x;
  *x = *y;
  *y = tmp;
}
 
// 打印
void PrintArray(int* a, int n)
{
  for (int i = 0; i < n; i++)
    printf("%d ", a[i]);
 
  printf("\n");
}
 
// 快速排序挖坑法
int PartSort2(int* a, int left, int right)
{
  int keyi = left;
  while (left < right)
  {
    // 右边找小
    while (left < right && a[right] >= a[keyi])
    {
      --right;
    }
 
    // 左边找大
    while (left < right && a[left] <= a[keyi])
    {
      ++left;
    }
 
    Swap(&a[left], &a[right]);
  }
 
  Swap(&a[keyi], &a[left]);
 
  return left;
}

1.2.3 -> 前后指针法

#define  _CRT_SECURE_NO_WARNINGS 1
 
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
 
 
// 交换
void Swap(int* x, int* y)
{
  int tmp = *x;
  *x = *y;
  *y = tmp;
}
 
// 打印
void PrintArray(int* a, int n)
{
  for (int i = 0; i < n; i++)
    printf("%d ", a[i]);
 
  printf("\n");
}
 
// 快速排序前后指针法
int PartSort3(int* a, int left, int right)
{
  int prev = left;
  int cur = left + 1;
  int keyi = left;
  while (cur <= right)
  {
    if (a[cur] < a[keyi] && ++prev != cur)
    {
      Swap(&a[prev], &a[cur]);
    }
 
    ++cur;
  }
 
  Swap(&a[prev], &a[keyi]);
  keyi = prev;
 
  return keyi;
}

1.2.4 -> 快速排序(递归版)

void QuickSort(int* a, int left, int right)
{
  if (left >= right)
    return;
 
  int keyi = PartSort3(a, left, right);
  // [left, keyi-1] keyi [keyi+1, right]
 
  QuickSort(a, left, keyi - 1);
  QuickSort(a, keyi + 1, right);
}

1.2.5 -> 快速排序(非递归版)

typedef int STDataType;
typedef struct Stack
{
  STDataType* a;
  int top;
  int capacity;
}ST;
 
void STInit(ST* pst)
{
  assert(pst);
  pst->a = NULL;
 
  //pst->top = -1;   // top 指向栈顶数据
  pst->top = 0;   // top 指向栈顶数据的下一个位置
 
  pst->capacity = 0;
}
 
void STDestroy(ST* pst)
{
  assert(pst);
 
  free(pst->a);
  pst->a = NULL;
  pst->top = pst->capacity = 0;
}
 
void STPush(ST* pst, STDataType x)
{
  if (pst->top == pst->capacity)
  {
    int newCapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;
    STDataType* tmp = (STDataType*)realloc(pst->a, newCapacity * sizeof(STDataType));
    if (tmp == NULL)
    {
      perror("realloc fail");
      return;
    }
 
    pst->a = tmp;
    pst->capacity = newCapacity;
  }
 
  pst->a[pst->top] = x;
  pst->top++;
}
 
void STPop(ST* pst)
{
  assert(pst);
  assert(!STEmpty(pst));
 
  pst->top--;
}
 
STDataType STTop(ST* pst)
{
  assert(pst);
  assert(!STEmpty(pst));
 
  return pst->a[pst->top - 1];
}
 
bool STEmpty(ST* pst)
{
  assert(pst);
 
  /*if (pst->top == 0)
  {
    return true;
  }
  else
  {
    return false;
  }*/
 
  return pst->top == 0;
}
 
int STSize(ST* pst)
{
  assert(pst);
 
  return pst->top;
}
 
// 快速排序 非递归实现
void QuickSortNonR(int* a, int left, int right)
{
  ST st;
  STInit(&st);
  STPush(&st, right);
  STPush(&st, left);
 
  while (!STEmpty(&st))
  {
    int left = STTop(&st);
    STPop(&st);
 
    int right = STTop(&st);
    STPop(&st);
 
    //int keyi = PartSort3(a, left, right);
    int keyi = PartSort1(a, left, right);
 
    // [left, keyi-1] keyi [keyi+1, right]
 
    if (keyi + 1 < right)
    {
      STPush(&st, right);
      STPush(&st, keyi + 1);
    }
 
    if (left < keyi - 1)
    {
      STPush(&st, keyi - 1);
      STPush(&st, left);
    }
  }
 
  STDestroy(&st);
}

快速排序的特性总结:

  1. 快速排序整体性能和使用场景较好
  2. 时间复杂度:
  3. 空间复杂度:
  4. 稳定性:不稳定

2 -> 归并排序

2.1 -> 归并排序

基本思想:归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。 归并排序核心步骤:

归并排序的特性总结:

  1. 归并排序的缺点在于需要O(N)的空间复杂度,归并排序的思考更多的是解决磁盘中的外排序问题
  2. 时间复杂度:
  3. 空间复杂度:
  4. 稳定性:稳定

2.1.1 -> 代码实现

// 归并排序递归实现
void _MergeSort(int* a, int begin, int end, int* tmp)
{
  if (begin == end)
    return;
 
  int mid = (begin + end) / 2;
  // [begin, mid] [mid+1, end]
  _MergeSort(a, begin, mid, tmp);
  _MergeSort(a, mid + 1, end, tmp);
 
  // 归并两个区间
  // ...
 
  int begin1 = begin, end1 = mid;
  int begin2 = mid + 1, end2 = end;
  int i = begin;
  while (begin1 <= end1 && begin2 <= end2)
  {
    if (a[begin1] < a[begin2])
    {
      tmp[i++] = a[begin1++];
    }
    else
    {
      tmp[i++] = a[begin2++];
    }
  }
 
  while (begin1 <= end1)
  {
    tmp[i++] = a[begin1++];
  }
 
  while (begin2 <= end2)
  {
    tmp[i++] = a[begin2++];
  }
 
  memcpy(a + begin, tmp + begin, sizeof(int) * (end - begin + 1));
}
void MergeSort(int* a, int n)
{
  int* tmp = (int*)malloc(sizeof(int) * n);
 
  _MergeSort(a, 0, n - 1, tmp);
 
  free(tmp);
}
 
// 归并排序非递归实现
void MergeSortNonR(int* a, int n)
{
  int* tmp = (int*)malloc(sizeof(int) * n);
 
  // 1  2  4 ....
  int gap = 1;
  while (gap < n)
  {
    int j = 0;
    for (int i = 0; i < n; i += 2 * gap)
    {
      // 每组的合并数据
      int begin1 = i, end1 = i + gap - 1;
      int begin2 = i + gap, end2 = i + 2 * gap - 1;
 
      printf("[%d,%d][%d,%d]\n", begin1, end1, begin2, end2);
 
      if (end1 >= n || begin2 >= n)
      {
        break;
      }
 
      // 修正
      if (end2 >= n)
      {
        end2 = n - 1;
      }
 
      while (begin1 <= end1 && begin2 <= end2)
      {
        if (a[begin1] < a[begin2])
        {
          tmp[j++] = a[begin1++];
        }
        else
        {
          tmp[j++] = a[begin2++];
        }
      }
 
      while (begin1 <= end1)
      {
        tmp[j++] = a[begin1++];
      }
 
      while (begin2 <= end2)
      {
        tmp[j++] = a[begin2++];
      }
 
      // 归并一组,拷贝一组
      memcpy(a + i, tmp + i, sizeof(int) * (end2 - i + 1));
    }
    printf("\n");
 
    //memcpy(a, tmp, sizeof(int) * n);
    gap *= 2;
  }
 
  free(tmp);
}

3 -> 非比较排序

思想:计数排序又称为鸽巢原理,是对哈希直接定址法的变形应用。

操作步骤:

  1. 统计相同元素出现次数
  2. 根据统计的结果将序列回收到原来的序列中

计数排序的特性总结:

  1. 计数排序在数据范围集中时,效率很高,但适用范围及场景有限
  2. 时间复杂度:
  3. 空间复杂度:
  4. 稳定性:稳定

3.1 -> 代码实现

// 计数排序
void CountSort(int* a, int n)
{
  int min = a[0], max = a[0];
  for (int i = 0; i < n; i++)
  {
    if (a[i] < min)
    {
      min = a[i];
    }
 
    if (a[i] > max)
    {
      max = a[i];
    }
  }
 
  int range = max - min + 1;
  int* countA = (int*)malloc(sizeof(int) * range);
  memset(countA, 0, sizeof(int) * range);
 
  // 统计次数
  for (int i = 0; i < n; i++)
  {
    countA[a[i] - min]++;
  }
 
  // 排序
  int k = 0;
  for (int j = 0; j < range; j++)
  {
    while (countA[j]--)
    {
      a[k++] = j + min;
    }
  }
}

4 -> 排序算法复杂度及稳定性分析

5 -> 排序系列代码总结

往期:

【海贼王的数据航海】排序——概念|直接插入排序|希尔排序

【海贼王的数据航海】排序——直接选择排序|堆排序

Sort.h

#pragma once
 
#define  _CRT_SECURE_NO_WARNINGS 1
 
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
 
// 交换
void Swap(int* x, int* y);
 
// 打印
void PrintArray(int* a, int n);
 
// 排序实现的接口
 
// 插入排序
void InsertSort(int* a, int n);
 
// 希尔排序
void ShellSort(int* a, int n);
 
// 选择排序
void SelectSort(int* a, int n);
 
// 堆排序
void AdjustUp(int* a, int child);
void AdjustDown(int* a, int n, int root);
void HeapSort(int* a, int n);
 
// 冒泡排序
void BubbleSort(int* a, int n);
 
// 快速排序递归实现
// 快速排序hoare版本
int PartSort1(int* a, int left, int right);
 
// 快速排序挖坑法
int PartSort2(int* a, int left, int right);
 
// 快速排序前后指针法
int PartPort3(int* a, int left, int right);
void QuickSort(int* a, int left, int right);
 
// 快速排序 非递归实现
void QuickSortnonr(int* a, int left, int right);
 
// 归并排序递归实现
void MergeSort(int* a, int n);
 
// 归并排序非递归实现
void MergeSortnonr(int* a, int n);
 
// 计数排序
void CountSort(int* a, int n);

Sort.c

#include "Sort.h"
#include "Stack.h"
 
// 交换
void Swap(int* x, int* y)
{
  int tmp = *x;
  *x = *y;
  *y = tmp;
}
 
// 打印
void PrintArray(int* a, int n)
{
  for (int i = 0; i < n; i++)
    printf("%d ", a[i]);
 
  printf("\n");
}
 
// 插入排序
void InsertSort(int* a, int n)
{
  for (int i = 0; i < n - 1; ++i)
  {
    int end = i;
    int tmp = a[i + 1];
    while (end >= 0)
    {
      if (a[end] > tmp)
      {
        a[end + 1] = a[end];
        --end;
      }
      else
      {
        break;
      }
 
      a[end + 1] = tmp;
    }
  }
}
 
// 希尔排序
void ShellSort(int* a, int n)
{
  int gap = n;
  for (int i = 0; i < n - gap; i++)
  {
    int end = i;
    int tmp = a[end + gap];
    while (end >= 0)
    {
      if (a[end] > tmp)
      {
        a[end + gap] = a[end];
        end -= gap;
      }
      else
      {
        break;
      }
    }
 
    a[end + gap] = tmp;
  }
}
 
// 选择排序
void SelectSort(int* a, int n)
{
  int begin = 0, end = n - 1;
  while (begin < end)
  {
    int maxi = begin, mini = begin;
    for (int i = begin; i <= end; i++)
    {
      if (a[i] > a[maxi])
      {
        maxi = i;
      }
 
      if (a[i] < a[mini])
      {
        mini = i;
      }
    }
 
    Swap(&a[begin], &a[mini]);
    // 如果maxi和begin重叠,修正一下即可
    if (begin == maxi)
    {
      maxi = mini;
    }
 
    Swap(&a[end], &a[maxi]);
 
    ++begin;
    --end;
  }
}
 
// 堆排序
void AdjustUp(int* a, int child)
{
  int father = (child - 1) / 2;
  while (child > 0)
  {
    if (a[child] > a[father])
    {
      Swap(&a[child], &a[father]);
      //更新下标
      child = father;
      father = (father - 1) / 2;
    }
    else
    {
      break;//一旦符合小堆了,就直接退出
    }
  }
}
void AdjustDown(int* a, int n, int parent)
{
  int child = parent * 2 + 1;
  while (child < n)
  {
    // 找出小的那个孩子
    if (child + 1 < n && a[child + 1] > a[child])
    {
      ++child;
    }
 
    if (a[child] > a[parent])
    {
      Swap(&a[child], &a[parent]);
      parent = child;
      child = parent * 2 + 1;
    }
    else
    {
      break;
    }
  }
}
// 排升序
void HeapSort(int* a, int n)
{
  // 建大堆
  for (int i = (n - 1 - 1) / 2; i >= 0; --i)
  {
    AdjustDown(a, n, i);
  }
 
  int end = n - 1;
  while (end > 0)
  {
    Swap(&a[0], &a[end]);
    AdjustDown(a, end, 0);
    --end;
  }
}
 
// 冒泡排序
void BubbleSort(int* a, int n)
{
  for (int j = 0; j < n; ++j)
  {
    bool exchange = false;
    for (int i = 1; i < n - j; i++)
    {
      if (a[i - 1] > a[i])
      {
        int tmp = a[i];
        a[i] = a[i - 1];
        a[i - 1] = tmp;
 
        exchange = true;
      }
    }
 
    if (exchange == false)
    {
      break;
    }
  }
}
 
// 快速排序递归实现
// 快速排序hoare版本
int PartSort1(int* a, int left, int right)
{
  int keyi = left;
  while (left < right)
  {
    // 右边找小
    while (left < right && a[right] >= a[keyi])
    {
      --right;
    }
 
    // 左边找大
    while (left < right && a[left] <= a[keyi])
    {
      ++left;
    }
 
    Swap(&a[left], &a[right]);
  }
 
  Swap(&a[keyi], &a[left]);
 
  return left;
}
 
// 快速排序挖坑法
int PartSort2(int* a, int left, int right)
{
  int keyi = left;
  while (left < right)
  {
    // 右边找小
    while (left < right && a[right] >= a[keyi])
    {
      --right;
    }
 
    // 左边找大
    while (left < right && a[left] <= a[keyi])
    {
      ++left;
    }
 
    Swap(&a[left], &a[right]);
  }
 
  Swap(&a[keyi], &a[left]);
 
  return left;
}
 
// 快速排序前后指针法
int PartSort3(int* a, int left, int right)
{
  int prev = left;
  int cur = left + 1;
  int keyi = left;
  while (cur <= right)
  {
    if (a[cur] < a[keyi] && ++prev != cur)
    {
      Swap(&a[prev], &a[cur]);
    }
 
    ++cur;
  }
 
  Swap(&a[prev], &a[keyi]);
  keyi = prev;
 
  return keyi;
}
void QuickSort(int* a, int left, int right)
{
  if (left >= right)
    return;
 
  int keyi = PartSort3(a, left, right);
  // [left, keyi-1] keyi [keyi+1, right]
 
  QuickSort(a, left, keyi - 1);
  QuickSort(a, keyi + 1, right);
}
 
// 快速排序 非递归实现
void QuickSortNonR(int* a, int left, int right)
{
  ST st;
  STInit(&st);
  STPush(&st, right);
  STPush(&st, left);
 
  while (!STEmpty(&st))
  {
    int left = STTop(&st);
    STPop(&st);
 
    int right = STTop(&st);
    STPop(&st);
 
    //int keyi = PartSort3(a, left, right);
    int keyi = PartSort1(a, left, right);
 
    // [left, keyi-1] keyi [keyi+1, right]
 
    if (keyi + 1 < right)
    {
      STPush(&st, right);
      STPush(&st, keyi + 1);
    }
 
    if (left < keyi - 1)
    {
      STPush(&st, keyi - 1);
      STPush(&st, left);
    }
  }
 
  STDestroy(&st);
}
 
// 归并排序递归实现
void _MergeSort(int* a, int begin, int end, int* tmp)
{
  if (begin == end)
    return;
 
  int mid = (begin + end) / 2;
  // [begin, mid] [mid+1, end]
  _MergeSort(a, begin, mid, tmp);
  _MergeSort(a, mid + 1, end, tmp);
 
  // 归并两个区间
  // ...
 
  int begin1 = begin, end1 = mid;
  int begin2 = mid + 1, end2 = end;
  int i = begin;
  while (begin1 <= end1 && begin2 <= end2)
  {
    if (a[begin1] < a[begin2])
    {
      tmp[i++] = a[begin1++];
    }
    else
    {
      tmp[i++] = a[begin2++];
    }
  }
 
  while (begin1 <= end1)
  {
    tmp[i++] = a[begin1++];
  }
 
  while (begin2 <= end2)
  {
    tmp[i++] = a[begin2++];
  }
 
  memcpy(a + begin, tmp + begin, sizeof(int) * (end - begin + 1));
}
void MergeSort(int* a, int n)
{
  int* tmp = (int*)malloc(sizeof(int) * n);
 
  _MergeSort(a, 0, n - 1, tmp);
 
  free(tmp);
}
 
// 归并排序非递归实现
void MergeSortNonR(int* a, int n)
{
  int* tmp = (int*)malloc(sizeof(int) * n);
 
  // 1  2  4 ....
  int gap = 1;
  while (gap < n)
  {
    int j = 0;
    for (int i = 0; i < n; i += 2 * gap)
    {
      // 每组的合并数据
      int begin1 = i, end1 = i + gap - 1;
      int begin2 = i + gap, end2 = i + 2 * gap - 1;
 
      printf("[%d,%d][%d,%d]\n", begin1, end1, begin2, end2);
 
      if (end1 >= n || begin2 >= n)
      {
        break;
      }
 
      // 修正
      if (end2 >= n)
      {
        end2 = n - 1;
      }
 
      while (begin1 <= end1 && begin2 <= end2)
      {
        if (a[begin1] < a[begin2])
        {
          tmp[j++] = a[begin1++];
        }
        else
        {
          tmp[j++] = a[begin2++];
        }
      }
 
      while (begin1 <= end1)
      {
        tmp[j++] = a[begin1++];
      }
 
      while (begin2 <= end2)
      {
        tmp[j++] = a[begin2++];
      }
 
      // 归并一组,拷贝一组
      memcpy(a + i, tmp + i, sizeof(int) * (end2 - i + 1));
    }
    printf("\n");
 
    //memcpy(a, tmp, sizeof(int) * n);
    gap *= 2;
  }
 
  free(tmp);
}
 
// 计数排序
void CountSort(int* a, int n)
{
  int min = a[0], max = a[0];
  for (int i = 0; i < n; i++)
  {
    if (a[i] < min)
    {
      min = a[i];
    }
 
    if (a[i] > max)
    {
      max = a[i];
    }
  }
 
  int range = max - min + 1;
  int* countA = (int*)malloc(sizeof(int) * range);
  memset(countA, 0, sizeof(int) * range);
 
  // 统计次数
  for (int i = 0; i < n; i++)
  {
    countA[a[i] - min]++;
  }
 
  // 排序
  int k = 0;
  for (int j = 0; j < range; j++)
  {
    while (countA[j]--)
    {
      a[k++] = j + min;
    }
  }
}


Stack.h

#pragma once
 
#define  _CRT_SECURE_NO_WARNINGS 1
 
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
 
typedef int STDataType;
typedef struct Stack
{
  STDataType* a;
  int top;
  int capacity;
}ST;
 
void STInit(ST* pst);
void STDestroy(ST* pst);
void STPush(ST* pst, STDataType x);
void STPop(ST* pst);
STDataType STTop(ST* pst);
bool STEmpty(ST* pst);
int STSize(ST* pst);

Stack.c

#include "Stack.h"
 
void STInit(ST* pst)
{
  assert(pst);
  pst->a = NULL;
 
  //pst->top = -1;   // top 指向栈顶数据
  pst->top = 0;   // top 指向栈顶数据的下一个位置
 
  pst->capacity = 0;
}
 
void STDestroy(ST* pst)
{
  assert(pst);
 
  free(pst->a);
  pst->a = NULL;
  pst->top = pst->capacity = 0;
}
 
void STPush(ST* pst, STDataType x)
{
  if (pst->top == pst->capacity)
  {
    int newCapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;
    STDataType* tmp = (STDataType*)realloc(pst->a, newCapacity * sizeof(STDataType));
    if (tmp == NULL)
    {
      perror("realloc fail");
      return;
    }
 
    pst->a = tmp;
    pst->capacity = newCapacity;
  }
 
  pst->a[pst->top] = x;
  pst->top++;
}
 
void STPop(ST* pst)
{
  assert(pst);
  assert(!STEmpty(pst));
 
  pst->top--;
}
 
STDataType STTop(ST* pst)
{
  assert(pst);
  assert(!STEmpty(pst));
 
  return pst->a[pst->top - 1];
}
 
bool STEmpty(ST* pst)
{
  assert(pst);
 
  /*if (pst->top == 0)
  {
    return true;
  }
  else
  {
    return false;
  }*/
 
  return pst->top == 0;
}
 
int STSize(ST* pst)
{
  assert(pst);
 
  return pst->top;
}

感谢各位大佬支持!!!

互三啦!!!

目录
相关文章
|
3月前
|
搜索推荐
【海贼王的数据航海】排序——直接选择排序|堆排序
【海贼王的数据航海】排序——直接选择排序|堆排序
15 0
|
3月前
|
搜索推荐
【海贼王的数据航海】排序——概念|直接插入排序|希尔排序
【海贼王的数据航海】排序——概念|直接插入排序|希尔排序
22 0
|
3月前
|
存储 算法
【海贼王的数据航海】时间复杂度 | 空间复杂度
【海贼王的数据航海】时间复杂度 | 空间复杂度
18 0
|
3月前
|
人工智能 算法 搜索推荐
蓝桥杯宝藏排序题目算法(冒泡、选择、插入)
以下是内容的摘要: 本文介绍了三种排序算法:冒泡排序、选择排序和插入排序。冒泡排序通过不断交换相邻的逆序元素逐步排序,最坏情况下需要 O(n^2) 次比较。选择排序在每轮中找到剩余部分的最小元素并放到已排序序列的末尾,同样具有 O(n^2) 时间复杂度。插入排序则是将每个元素插入到已排序序列的正确位置,时间复杂度也是 O(n^2),但空间复杂度为 O(1)。
|
4月前
|
算法 前端开发 索引
2624. 蜗牛排序
2624. 蜗牛排序
28 0
|
算法 搜索推荐 前端开发
前端排序算法哪家强:冒泡、选择、插入、归并、快速,哪个才是最强者?
当谈到前端开发时,排序算法是必不可少的一部分。排序算法可以帮助我们对数据进行有效的排序,使其更具有结构和有序性。在前端领域中,有许多常见的排序算法,其中包括冒泡排序、选择排序、插入排序、归并排序和快速排序。让我们一起来了解这些算法以及它们的原理和特点,并通过具体的例子说明它们在实际开发中的应用。
116 0
前端排序算法哪家强:冒泡、选择、插入、归并、快速,哪个才是最强者?
|
存储 搜索推荐
7大排序算法-- 直接插入,希尔,冒泡,选择 --精解(上)
7大排序算法-- 直接插入,希尔,冒泡,选择 --精解
76 0
|
搜索推荐 算法
7大排序算法-- 直接插入,希尔,冒泡,选择 --精解(下)
7大排序算法-- 直接插入,希尔,冒泡,选择 --精解(下)
112 0
|
搜索推荐 算法
【排序算法 上】带你手撕常见排序 (插入,希尔,选择,堆排序) (动图详解)
【排序算法 上】带你手撕常见排序 (插入,希尔,选择,堆排序) (动图详解)
100 0
【排序算法 上】带你手撕常见排序 (插入,希尔,选择,堆排序) (动图详解)
|
搜索推荐 算法 C语言
【排序算法 下】带你手撕常见排序 (冒泡,快排,归并排序) (动图详解)
【排序算法 下】带你手撕常见排序 (冒泡,快排,归并排序) (动图详解)
148 0
【排序算法 下】带你手撕常见排序 (冒泡,快排,归并排序) (动图详解)