数据结构常用排序算法

简介: 数据结构常用排序算法

1、冒泡排序


//冒泡排序
void BubbleSort(int* nums, int len)
{
  for (int i = 1; i < len; i++)
  {
    for (int j = 1; j < len - i + 1; j++)
    {
      if (nums[j] < nums[j - 1])
        swap(nums[j], nums[j - 1]);
    }
  }
}


2、快速排序  


//快速排序
void quickSort(int arr[], int left, int right) 
{
  int left = left;
  int right = right;
  int temp = 0;
  if (left < right) 
  {   
    //待排序的第一个元素作为基准元素
    temp = arr[left];  
    //从左右两边交替扫描,直到left = right
    while (left != right) 
    {   
      //从右往左扫描,找到第一个比基准元素小的元素
      while (right > left && arr[right] >= temp)
        right--;        
      arr[left] = arr[right];  //找到这种元素arr[right]后与arr[left]交换
      //从左往右扫描,找到第一个比基准元素大的元素
      while (left < right && arr[left] <= temp)
        left++;         
      arr[right] = arr[left];  //找到这种元素arr[left]后,与arr[right]交换
    }
    arr[right] = temp;      //基准元素归位
    quickSort(arr, left, left - 1);    //对基准元素左边的元素进行递归排序
    quickSort(arr, right + 1, right);  //对基准元素右边的进行递归排序
  }
}


3、插入排序


//插入排序
void insertSort(int* nums, int len)
{
  for (int i = 0; i < len; i++)
  {
    for (int j = i ; j > 0; j--)
    {
      if (nums[j] < nums[j - 1])
        swap(nums[j], nums[j - 1]);
    }
  }
}


4、选择排序


//选择排序
void slectSort(int* nums, int len)
{
  int mid = 0;
  for (int i = 0; i < len - 1; i++)
  {
    mid = i;
    for (int j = i + 1; j < len; j++)
    {
      if (nums[j] < nums[mid])
        mid = j;
    }
    swap(nums[mid], nums[i]);
  }
}


5、桶排序


//桶排序
vector<int> bucketSort(vector<int>& nums)
{
  int len = nums.size();
  if (len == 0) return {};
  //获取最大值及最小值
  int mins = *min_element(nums.begin(), nums.end());
  int maxs = *max_element(nums.begin(), nums.end());
  //初始化桶的个数 k=log(len),也可以随机初始化
  int n = 5;
  //初始化桶
  vector<vector<int>> res(5);
  int d = maxs - mins;
  //把所有元素放到各自桶中
  for (int i = 0; i < len; i++)
  {
    //计算元素所对应的桶的序号
    int index = (nums[i] - mins) * n / d;
    //下标索引从0开始
    if (index == n)
      index--;
    res[index].push_back(nums[i]);
  }
  for (int i = 0; i < n; i++)
  {
    sort(res[i].begin(), res[i].end());
  }
  vector<int> v;
  for (int i = 0; i < n; i++)
  {
    for (int j = 0; j < res[i].size(); j++)
      v.push_back(res[i][j]);
  }
  return v;
}


6、堆排序


#include <stdio.h>
void Swap(int *heap, int len);        /* 交换根节点和数组末尾元素的值 */
void BuildMaxHeap(int *heap, int len);/* 构建大顶堆 */
int main()
{
    int a[6] = {7, 3, 8, 5, 1, 2};
    int len = 6;    /* 数组长度 */
    int i;
    for (i = len; i > 0; i--)
    {
        BuildMaxHeap(a, i);
        Swap(a, i);
    }
    for (i = 0; i < len; i++)
    {
        printf("%d ", a[i]);
    }
    return 0;
}
//堆排序,大顶堆,构建大顶堆
void BuildMaxHeap(int* heap, int len)
{
  //最后一个非叶子节点为:len / 2 - 1
  for (int i = len / 2 - 1; i >= 0; i--)
  {
    //判断左子树是否满足大顶堆关系
    if (2 * i + 1 < len && heap[i] < heap[2 * i + 1])
    {
      int tem = heap[i];
      heap[i] = heap[2 * i + 1];
      heap[2 * i + 1] = tem;
      //交换之后要判断左子树与左子树的子树是否也满足该关系
      if ((2 * (2 * i + 1) + 1 < len && heap[2 * i + 1] < heap[2 * (2 * i + 1) + 1] )|| (2 * (2 * i + 1) + 2 < len && heap[2 * i + 1] < heap[2 * (2 * i + 1) + 2]))
      {
        BuildMaxHeap(heap, len);
      }
    }
    //判断右子树是否满足大顶堆关系
    if (2 * i + 2 < len && heap[i] < heap[2 * i + 2])
    {
      int tem = heap[i];
      heap[i] = heap[2 * i + 2];
      heap[2 * i + 2] = tem;
      //交换之后要判断右子树与右子树的子树是否也满足该关系
      if ((2 * (2 * i + 2) + 1 < len && heap[2 * i + 2] < heap[2 * (2 * i + 2) + 1]) || (2 * (2 * i + 2) + 2 < len && heap[2 * i + 2] < heap[2 * (2 * i + 2) + 2]))
      {
        BuildMaxHeap(heap, len);
      }
    }
  }
}
/* Function: 交换交换根节点和数组末尾元素的值*/
void Swap(int *heap, int len)
{
    int temp;
    temp = heap[0];
    heap[0] = heap[len-1];
    heap[len-1] = temp;
}


7、归并排序


void Merg(int* nums, int left, int right)
  {
    vector<int> temp(10);
    int mid = left + (right - left) / 2;
    int i = left, j = mid + 1, k = 0;
    while (i <= mid && j <= right)
    {
      if (nums[i] < nums[j])
        temp[k++] = nums[i++];
      else
        temp[k++] = nums[j++];
    }
    while (i <= mid)
      temp[k++] = nums[i++];
    while (j <= right)
      temp[k++] = nums[j++];
    for (i = left, k = 0; i <= right; i++, k++)
      nums[i] = temp[k];
  }
  void MergeSort(int* nums, int left, int right)
  {
    if (left < right)
    {
      int mid = left + (right - left) / 2;
      MergeSort(nums, left, mid);
      MergeSort(nums, mid + 1, right);
      Merg(nums, left, right);
    }
  }


相关文章
|
23天前
|
算法 数据处理 C语言
C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合
本文深入解析了C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合,旨在帮助读者掌握这一高效的数据处理方法。
34 1
|
2月前
|
存储 人工智能 算法
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
这篇文章详细介绍了Dijkstra和Floyd算法,这两种算法分别用于解决单源和多源最短路径问题,并且提供了Java语言的实现代码。
92 3
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
|
24天前
|
存储 算法 搜索推荐
Python 中数据结构和算法的关系
数据结构是算法的载体,算法是对数据结构的操作和运用。它们共同构成了计算机程序的核心,对于提高程序的质量和性能具有至关重要的作用
|
23天前
|
数据采集 存储 算法
Python 中的数据结构和算法优化策略
Python中的数据结构和算法如何进行优化?
|
1月前
|
算法
数据结构之路由表查找算法(深度优先搜索和宽度优先搜索)
在网络通信中,路由表用于指导数据包的传输路径。本文介绍了两种常用的路由表查找算法——深度优先算法(DFS)和宽度优先算法(BFS)。DFS使用栈实现,适合路径问题;BFS使用队列,保证找到最短路径。两者均能有效查找路由信息,但适用场景不同,需根据具体需求选择。文中还提供了这两种算法的核心代码及测试结果,验证了算法的有效性。
97 23
|
1月前
|
算法
数据结构之蜜蜂算法
蜜蜂算法是一种受蜜蜂觅食行为启发的优化算法,通过模拟蜜蜂的群体智能来解决优化问题。本文介绍了蜜蜂算法的基本原理、数据结构设计、核心代码实现及算法优缺点。算法通过迭代更新蜜蜂位置,逐步优化适应度,最终找到问题的最优解。代码实现了单链表结构,用于管理蜜蜂节点,并通过适应度计算、节点移动等操作实现算法的核心功能。蜜蜂算法具有全局寻优能力强、参数设置简单等优点,但也存在对初始化参数敏感、计算复杂度高等缺点。
60 20
|
1月前
|
机器学习/深度学习 算法 C++
数据结构之鲸鱼算法
鲸鱼算法(Whale Optimization Algorithm,WOA)是由伊朗研究员Seyedali Mirjalili于2016年提出的一种基于群体智能的全局优化算法,灵感源自鲸鱼捕食时的群体协作行为。该算法通过模拟鲸鱼的围捕猎物和喷出气泡网的行为,结合全局搜索和局部搜索策略,有效解决了复杂问题的优化需求。其应用广泛,涵盖函数优化、机器学习、图像处理等领域。鲸鱼算法以其简单直观的特点,成为初学者友好型的优化工具,但同时也存在参数敏感、可能陷入局部最优等问题。提供的C++代码示例展示了算法的基本实现和运行过程。
50 0
|
2月前
|
机器学习/深度学习 存储 缓存
数据结构与算法学习十:排序算法介绍、时间频度、时间复杂度、常用时间复杂度介绍
文章主要介绍了排序算法的分类、时间复杂度的概念和计算方法,以及常见的时间复杂度级别,并简单提及了空间复杂度。
41 1
数据结构与算法学习十:排序算法介绍、时间频度、时间复杂度、常用时间复杂度介绍
|
1月前
|
算法 vr&ar 计算机视觉
数据结构之洪水填充算法(DFS)
洪水填充算法是一种基于深度优先搜索(DFS)的图像处理技术,主要用于区域填充和图像分割。通过递归或栈的方式探索图像中的连通区域并进行颜色替换。本文介绍了算法的基本原理、数据结构设计(如链表和栈)、核心代码实现及应用实例,展示了算法在图像编辑等领域的高效性和灵活性。同时,文中也讨论了算法的优缺点,如实现简单但可能存在堆栈溢出的风险等。
42 0
|
2月前
|
存储 算法 Java
Set接口及其主要实现类(如HashSet、TreeSet)如何通过特定数据结构和算法确保元素唯一性
Java Set因其“无重复”特性在集合框架中独树一帜。本文解析了Set接口及其主要实现类(如HashSet、TreeSet)如何通过特定数据结构和算法确保元素唯一性,并提供了最佳实践建议,包括选择合适的Set实现类和正确实现自定义对象的hashCode()与equals()方法。
45 4