数据结构面试之十——排序1(直接插入、希尔、冒泡、直接选择排序)

简介: 九、数据结构面试之十——排序1(直接插入、希尔、冒泡、直接选择排序)

题注:《面试宝典》有相关习题,但思路相对不清晰,排版有错误,作者对此参考相关书籍和自己观点进行了重写,供大家参考。


九、数据结构面试之十——排序1(直接插入、希尔、冒泡、直接选择排序)


1.直接插入排序


【算法思想】:每次将一个待排序的元素,插入到前面已经排序的子序列中,直到全部元素插入完毕为止。


【算法实现】:


//最简实现排序[交换实现].


template <class T>

void directInsertSort(T arr[],int N)

{

      inti;

      intj;

      for( i = 1; i < N; i++)

      {

             for(j= i-1; j >= 0 && arr[j+1] < arr[j];j--)

             {

                    swap(arr[j+1],arr[j]);

             }//endfor

      }//endfor

}

//直接插入排序[移动版本]


template <class T>

void directInsertSort(T arr[], int N)

{

      inti;

      intj;

      for( i = 1; i < N; i++)

      {

             inttemp = arr[i];

             for(j = i-1; j >= 0 && temp < arr[j]; j--)

             {

                    arr[j+1]= arr[j];  //后移动

             }

             arr[j+1]= temp;        //找到插入的位置.

      }

}


2.希尔排序


【算法思想】:将待排序的序列按照步长划分子序列,对子序列进行直接插入排序,然后递减步长直至为1(最小步长),这样整个序列就会基本有序,然后进行最后一次直接插入排序即可。


【算法实现】:


template<class T>

void ShellSort(T arr[], int N)

{

      inti;

      intj;

      intstep;

      for( step = N/2; step > 0; step/=2)

      {

             for(i= step; i < N; i++) //注意此处递增的步长为1,依次比较!

             {

                    for(j= i-step; j >=0 && arr[j+step] < arr[j]; j-=step)

                    {

                           swap(arr[j+step],arr[j]);

                    }//endfor j

             }//endfor i

      }//endfor step

}



希尔排序,可以看做是直接插入排序的改进算法,在直接插入排序的基础上多了外层循环,依次递减步长,最终完成排序。



3. 冒泡排序


【算法思想】:1)将待排序的序列元素之间两两进行比较,如果第一个元素大于第二个元素,则进行交换;2)这样经过一趟排序之后,确保值最大的元素在最底部;3)排序完一次后N-1,重复1),2)知道N==0为止。


【算法实现】:


//经典冒泡


template<typename T>

void BubuleSort(T a[], int N)

{

      inti,j;

      for(i= 0; i < N; i++)

      {

             for(j= 0; j < N-i-1; j++)

             {

                    if(a[j]> a[j+1])

                    {

                           swap(a[j],a[j+1]);

                    }//endif j

             }//endfor j

      }//endfor i

}



//改进+是否交换标识



template<typename T>

void BubuleSort(T a[], int N)

{

      inti,j;

      boolbExchange = true;         //初始设定为true

      for(i= 0; i < N && bExchange; i++)

      {

             bExchange= false;        //进入循环则设定为false

             for(j= 0; j < N-i-1; j++)

             {

                    if(a[j]> a[j+1])

                    {

                           swap(a[j],a[j+1]);

                           bExchange = true;//存在交换则变为true.

                    }//endif j

             }//endfor j

      }//endfor i

}


4. 选择排序


【算法思想】:同直接插入排序,将元素分为有序区和无序区。所不同的是,直接插入排序是将无序区域中第一个元素插入到有序区域以形成更大的有序区;而选择排序是从无序区域中选择最小的元素放入有序区的最后。


【算法实现】:


template <class T>

void SelectSort(T arr[], int N)

{

      intminPos;

      for(int i = 0; i < N; i++)

      {

             minPos= i;

             for(intj=i+1; j<N; j++)

             {

                    if(arr[j]< arr[minPos])

                    {

                           minPos= j;

                    }//endif

             }//endfor

             if(minPos!= i)

             {

                    swap(arr[minPos],arr[i]);//交换

             }

      }

}


相关文章
|
11月前
|
存储 机器学习/深度学习 算法
C 408—《数据结构》图、查找、排序专题考点(含解析)
408考研——《数据结构》图,查找和排序专题考点选择题汇总(含解析)。
849 29
|
12月前
|
存储 人工智能 算法
【C++数据结构——内排序】二路归并排序(头歌实践教学平台习题)【合集】
本关任务是实现二路归并算法,即将两个有序数组合并为一个有序数组。主要内容包括: - **任务描述**:实现二路归并算法。 - **相关知识**: - 二路归并算法的基本概念。 - 算法步骤:通过比较两个有序数组的元素,依次将较小的元素放入新数组中。 - 代码示例(以 C++ 为例)。 - 时间复杂度为 O(m+n),空间复杂度为 O(m+n)。 - **测试说明**:平台会对你编写的代码进行测试,提供输入和输出示例。 - **通关代码**:提供了完整的 C++ 实现代码。 - **测试结果**:展示代码运行后的排序结果。 开始你的任务吧,祝你成功!
398 10
|
12月前
|
搜索推荐 算法 数据处理
【C++数据结构——内排序】希尔排序(头歌实践教学平台习题)【合集】
本文介绍了希尔排序算法的实现及相关知识。主要内容包括: - **任务描述**:实现希尔排序算法。 - **相关知识**: - 排序算法基础概念,如稳定性。 - 插入排序的基本思想和步骤。 - 间隔序列(增量序列)的概念及其在希尔排序中的应用。 - 算法的时间复杂度和空间复杂度分析。 - 代码实现技巧,如循环嵌套和索引计算。 - **测试说明**:提供了测试输入和输出示例,帮助验证代码正确性。 - **我的通关代码**:给出了完整的C++代码实现。 - **测试结果**:展示了代码运行的测试结果。 通过这些内容,读者可以全面了解希尔排序的原理和实现方法。
281 10
|
12月前
|
搜索推荐 C++
【C++数据结构——内排序】快速排序(头歌实践教学平台习题)【合集】
快速排序是一种高效的排序算法,基于分治策略。它的主要思想是通过选择一个基准元素(pivot),将数组划分成两部分。一部分的元素都小于等于基准元素,另一部分的元素都大于等于基准元素。然后对这两部分分别进行排序,最终使整个数组有序。(第一行是元素个数,第二行是待排序的原始关键字数据。本关任务:实现快速排序算法。开始你的任务吧,祝你成功!
318 7
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
1087 9
|
存储 算法
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
320 59
|
7月前
|
编译器 C语言 C++
栈区的非法访问导致的死循环(x64)
这段内容主要分析了一段C语言代码在VS2022中形成死循环的原因,涉及栈区内存布局和数组越界问题。代码中`arr[15]`越界访问,修改了变量`i`的值,导致`for`循环条件始终为真,形成死循环。原因是VS2022栈区从低地址到高地址分配内存,`arr`数组与`i`相邻,`arr[15]`恰好覆盖`i`的地址。而在VS2019中,栈区先分配高地址再分配低地址,因此相同代码表现不同。这说明编译器对栈区内存分配顺序的实现差异会导致程序行为不一致,需避免数组越界以确保代码健壮性。
153 0
栈区的非法访问导致的死循环(x64)
232.用栈实现队列,225. 用队列实现栈
在232题中,通过两个栈(`stIn`和`stOut`)模拟队列的先入先出(FIFO)行为。`push`操作将元素压入`stIn`,`pop`和`peek`操作则通过将`stIn`的元素转移到`stOut`来实现队列的顺序访问。 225题则是利用单个队列(`que`)模拟栈的后入先出(LIFO)特性。通过多次调整队列头部元素的位置,确保弹出顺序符合栈的要求。`top`操作直接返回队列尾部元素,`empty`判断队列是否为空。 两题均仅使用基础数据结构操作,展示了栈与队列之间的转换逻辑。
|
12月前
|
存储 C语言 C++
【C++数据结构——栈与队列】顺序栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现顺序栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 1.初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储
570 77
|
11月前
|
算法 调度 C++
STL——栈和队列和优先队列
通过以上对栈、队列和优先队列的详细解释和示例,希望能帮助读者更好地理解和应用这些重要的数据结构。
271 11