数据结构|排序总结(1)|直接插入排序

简介: 数据结构|排序总结(1)|直接插入排序

排序分类

插入排序:直接插入排序,希尔排序

选择排序:选择排序,堆排序

交换排序:冒泡排序,快速排序

归并排序

插入排序

直接插入排序

       相当于摸牌,例如我们现在手上有{2,4,5,6}这些牌,当下一张是3的时候我们要将3插入到2和4当中,那么对于数组我们就要 把4,5,6 都往后挪,给3让出一个位置,这里演示以下往后挪的过程。

现有2,4,5,6

3先和6比,3应该放在6的前面,也就是3和6交换,交换后2,4,5,3,6

3再和5比,3应该放在5的前面,也就是3和5交换,交换后2,4,3,5,6

3再和4比,3应该放在4的前面,也就是3和4交换,交换后2,3,4,5,6

3再和2比,3应该放在2的后面,3本来就在2的后面,那就不用交换了,这就结束了

       很明显,这个要用到循环,既然用到,那么就要有结束条件--------插入的数大于前一个数。

       这个是一个,模拟的过程,但我们一般情况下遇到的都是一个固定长度的数组,也就是说,在不动空间的条件下只是比较交换。

       假设现在是这样的一个数组{ 2,3,1,4,2,5,2,0}我们可以先从第一2位置开始排,接着就是3,1,4...把他们放到该放的位置

先排2,结果如下

第一趟:2,3,1,4,2,5,2,0

在排3,和他前面的2进行比较,不用交换,结果如下:

第二趟:2,3,1,4,2,5,2,0

在排1,和前面的3进行比较,需要交换结果如下:

213,4,2,5,2,0

没有到达循环结束条件(插入的数大于前一个数)所以需要继续和前面的二进行比较,进行交换,结果如下:

1,2,3,4,2,5,2,0,交换后也没有到达循环结束条件,但是1的前面已经没有数了,这样也是结束了1的排序,所以上面的循环结束条件应该在加一个插入的数下标已经为0;因此第三趟排序结果为:

第三趟:1,2,3,4,2,5,2,0

剩下的数依次类推...

#include<iostream>
#include<vector>
using namespace std;
void swap(int& a, int& b)
{
  int tmp=a;
  a = b;
  b = tmp;
}
int main()
{
  vector <int>arr = { 2,3,1,4,2,5,2,0};
  cout << "排序前:";
  for (int i = 0; i < arr.size(); i++)cout << arr[i] << ' ';
  for (int i = 1; i < arr.size(); i++)//i是要排的数
  {
    int t = i;
    for (int j = i - 1; j >=0; j--)//
    {
      if (arr[t] < arr[j])
      {
        swap(arr[t--], arr[j]);
      }
        
      else
        break;
    }
  }
  cout << endl<<"排序后:";
  for (int i = 0; i < arr.size(); i++)cout << arr[i] << ' ';
  return 0;
}

时间复杂度分析

时间复杂度最差的时候:也就是 逆序的时候,下面是他们每次交换后的样子

#include<iostream>
#include<vector>
using namespace std;
void swap(int& a, int& b)
{
  int tmp=a;
  a = b;
  b = tmp;
}
int main()
{
  vector <int>arr = {8,7,6,5,4,3,2,1,0};
  cout << "排序前:";
  for (int i = 0; i < arr.size(); i++)cout << arr[i] << ' ';
  cout << endl<<endl;
  for (int i = 1; i < arr.size(); i++)//i是要排的数
  {
    int t = i;
    for (int j = i - 1; j >=0; j--)//
    {
      if (arr[t] < arr[j])
      {
        swap(arr[t--], arr[j]);
        for (int i = 0; i < arr.size(); i++)cout << arr[i] << ' ';
        cout << endl;
      }
        
      else
        break;
    }
    //cout <<"比较:"<<i<<"次"<<endl;
    cout << endl;
  }
  cout << endl<<"排序后:";
  for (int i = 0; i < arr.size(); i++)cout << arr[i] << ' ';
  return 0;
}

每次交换的次数类似一个等差数列,因此时间复杂度就是O( )

时间复杂度最好的时候也就是正序的时候,每次交换后如下图所示:

#include<iostream>
#include<vector>
using namespace std;
void swap(int& a, int& b)
{
  int tmp=a;
  a = b;
  b = tmp;
}
int main()
{
  vector <int>arr = {0,1,2,3,4,5,6,7,8};
  cout << "排序前:";
  for (int i = 0; i < arr.size(); i++)cout << arr[i] << ' ';
  cout << endl<<endl;
  for (int i = 1; i < arr.size(); i++)//i是要排的数
  {
    int t = i;
    for (int j = i - 1; j >=0; j--)//
    {
      if (arr[t] < arr[j])
      {
        swap(arr[t--], arr[j]);
        for (int i = 0; i < arr.size(); i++)cout << arr[i] << ' ';
        cout << endl;
      }
        
      else
        break;
    }
    cout <<"比较:"<<i<<"次"<<endl;
    //cout << endl;
  }
  cout << endl<<"排序后:";
  for (int i = 0; i < arr.size(); i++)cout << arr[i] << ' ';
  return 0;
}

可以看出就算本身是有序的,也得过一遍才可以,因此时间复杂度是O(n)

目录
打赏
0
0
0
0
6
分享
相关文章
C 408—《数据结构》图、查找、排序专题考点(含解析)
408考研——《数据结构》图,查找和排序专题考点选择题汇总(含解析)。
82 29
【C++数据结构——内排序】二路归并排序(头歌实践教学平台习题)【合集】
本关任务是实现二路归并算法,即将两个有序数组合并为一个有序数组。主要内容包括: - **任务描述**:实现二路归并算法。 - **相关知识**: - 二路归并算法的基本概念。 - 算法步骤:通过比较两个有序数组的元素,依次将较小的元素放入新数组中。 - 代码示例(以 C++ 为例)。 - 时间复杂度为 O(m+n),空间复杂度为 O(m+n)。 - **测试说明**:平台会对你编写的代码进行测试,提供输入和输出示例。 - **通关代码**:提供了完整的 C++ 实现代码。 - **测试结果**:展示代码运行后的排序结果。 开始你的任务吧,祝你成功!
47 10
【C++数据结构——内排序】希尔排序(头歌实践教学平台习题)【合集】
本文介绍了希尔排序算法的实现及相关知识。主要内容包括: - **任务描述**:实现希尔排序算法。 - **相关知识**: - 排序算法基础概念,如稳定性。 - 插入排序的基本思想和步骤。 - 间隔序列(增量序列)的概念及其在希尔排序中的应用。 - 算法的时间复杂度和空间复杂度分析。 - 代码实现技巧,如循环嵌套和索引计算。 - **测试说明**:提供了测试输入和输出示例,帮助验证代码正确性。 - **我的通关代码**:给出了完整的C++代码实现。 - **测试结果**:展示了代码运行的测试结果。 通过这些内容,读者可以全面了解希尔排序的原理和实现方法。
64 10
|
2月前
|
【C++数据结构——内排序】快速排序(头歌实践教学平台习题)【合集】
快速排序是一种高效的排序算法,基于分治策略。它的主要思想是通过选择一个基准元素(pivot),将数组划分成两部分。一部分的元素都小于等于基准元素,另一部分的元素都大于等于基准元素。然后对这两部分分别进行排序,最终使整个数组有序。(第一行是元素个数,第二行是待排序的原始关键字数据。本关任务:实现快速排序算法。开始你的任务吧,祝你成功!
55 7
数据结构与算法学习十三:基数排序,以空间换时间的稳定式排序,速度很快。
基数排序是一种稳定的排序算法,通过将数字按位数切割并分配到不同的桶中,以空间换时间的方式实现快速排序,但占用内存较大,不适合含有负数的数组。
67 0
数据结构与算法学习十三:基数排序,以空间换时间的稳定式排序,速度很快。
数据结构与算法学习十一:冒泡排序、选择排序、插入排序
本文介绍了冒泡排序、选择排序和插入排序三种基础排序算法的原理、实现代码和测试结果。
49 0
数据结构与算法学习十一:冒泡排序、选择排序、插入排序
【用Java学习数据结构系列】七大排序要悄咪咪的学(直接插入,希尔,归并,选择,堆排,冒泡,快排)以及计数排序(非比较排序)
【用Java学习数据结构系列】七大排序要悄咪咪的学(直接插入,希尔,归并,选择,堆排,冒泡,快排)以及计数排序(非比较排序)
48 1
蓝桥杯宝藏排序 | 数据结构 | 快速排序 归并排序
蓝桥杯宝藏排序 | 数据结构 | 快速排序 归并排序
|
4月前
|
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
66 1
|
2月前
|
【C++数据结构——栈与队列】顺序栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现顺序栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 1.初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储
160 77
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等