内部排序算法总结(下)【C++实现】

news/2024/5/19 5:47:32 标签: c++, 数据结构, 排序算法, 选择排序, 堆排序

上节总结了基于交换的排序:冒泡排序和快速排序;以及基于插入的排序:简单插入排序和希尔排序。内部排序算法总结(上)【C++实现】

本节总结两种基于选择的排序:选择排序堆排序

CONTENT

一、 基于选择的排序

1. 选择排序

思想

(1)固定数组中的第一个元素,分别与剩余的所有元素进行比较,从而找到序列中的最小值和固定元素交换,如果固定元素就是最小值,则无需交换。

(2)在剩余未排序元素中继续寻找最小(大)元素,放到已排序序列的末尾。

时间复杂度

平均最好最坏
O(n2)O(n2)O(n2)

动画演示

在这里插入图片描述
代码

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

void selectSort(vector<int>& nums)
{
    int i, j, minn;
    for(i=0; i<nums.size();i++){
        minn = i;
        for(j=i+1; j<nums.size();j++){
            if(nums[j]<nums[minn])  minn = j;
        }
        swap(nums[i], nums[minn]);
    }
}

int main()
{
    int n;
    vector<int> nums;
    while(cin>>n){
        nums.push_back(n);
    }
    selectSort(nums);
    for(int num : nums){
        cout<<num<<" ";
    }
}

P.s:选择排序VS插入排序:
选择排序

从当前元素开始,向后遍历,找到最小的元素,与当前元素交换位置。

插入排序:

从当前元素开始,向前遍历(前面的数组已经为一有序数组),找到第一个比当前元素小的元素,将当前元素插在该元素后面。

因此,两种排序方法在实现方面的比较明显的区别就是,选择排序是向后遍历,而插入排序是向前遍历。在思想方面选择排序是选择出最小的元素,然后与当前元素交换,而插入排序需要将元素一步步后挪,然后将当前元素插入相应位置。

2. 堆排序

思想

(1)什么是堆?

堆:符合以下两个条件之一的完全二叉树

每个结点的值都大于其左孩子和右孩子结点的值,称之为大根堆;每个结点的值都小于其左孩子和右孩子结点的值,称之为小根堆。如下图

图片来源

在这里插入图片描述
我们用数组的方式来存储完全二叉树,如下所示

在这里插入图片描述
这里我们要用到完全二叉树的三条重要性质:

(1)对于完全二叉树中的第 i 个数,它的左子节点下标:left = 2i + 1
(2)对于完全二叉树中的第 i 个数,它的右子节点下标:right= left + 1
(3)对于有 n 个元素的完全二叉树(n≥2)(n≥2),它的最后一个非叶子结点的下标:n/2 - 1

【2】堆排序的思想:

(1)从下到上(从最后一个非叶子结点【下标为n/2-1】到根【下标为0】)构造一个大顶堆;

(2)取根顶数字:

交换根结点(数组的首元素,为当前完全二叉树的最大值)和最后一个叶子节点(数组的尾元素);

P.s:
(1)即把最大的值移到数组的末尾。
(2)根结点交换到数组的后面位置后,相当于从大顶堆中脱离了,以后构造大顶堆时不再考虑该元素。

(3)再从上到下将剩余元素构造成一个大顶堆(剩余元素指不包含(2)中交换到数组末尾的根结点的元素)

(4)重复上述操作,直到所有元素都从大顶堆中脱离。

时间复杂度

平均最好最坏
O(nlog(n))O(nlog(n))O(nlog(n))

动画效果

在这里插入图片描述
代码

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

// root为根结点下标
// 将以root为根结点的完全二叉树调整为大顶堆
void adjustHeap(vector<int>& nums, int root, int len)
{
    int left = root*2+1, right = root*2+2;
    int maxx = root;
    if(left<len && nums[maxx]<nums[left])   maxx = left;
    if(right<len && nums[maxx]<nums[right])   maxx = right;
    if(maxx!=root){
        swap(nums[maxx], nums[root]);
        adjustHeap(nums, maxx, len);
    }
}

void buidHeap(vector<int>& nums)
{
    int len = nums.size();
    for(int i=len/2-1; i>=0; i--){
        adjustHeap(nums, i, len);
    }
    for(int i=len-1; i>=0; i--){
        swap(nums[0], nums[i]);
        adjustHeap(nums, 0, i);
    }
}

int main()
{
    int n;
    vector<int> nums;
    while(cin>>n){
        nums.push_back(n);
    }
    buidHeap(nums);
    for(int num : nums){
        cout<<num<<" ";
    }
}


http://www.niftyadmin.cn/n/1084648.html

相关文章

7-EL表达式和JSTL表达式

引入jar包 一。EL表达式1.表达式语言&#xff0c;用于jsp网页中获取和计算数据2.语法&#xff1a;${表达式}3.用于取值&#xff1a;可以从pageContext,request,session,application这些域中获取后台数据。顺序是从小到大4.指定作用域来取值&#xff1a;${requestScope.对象名},…

程序员怎样开始享受喝茶的乐趣

从接触茶艺到现在,有三年多时间.从经验上看,喝茶对我们这些写程序的还是有不少正面作用的.调节心情,放松一下自是不在话下,选择了适合自己的茶还可以改善身体的健康状态. 些许经验简略地说一下,希望大家可以渐渐开始享受喝茶的味道. 1.准备工具 工具有两种:自由开发型和使用框…

523. 连续的子数组和

通过这道题&#xff0c;了解到了一个很有用的数学知识&#xff1a; 若 (a - b) 可以被k整除 则a % k b % k 即&#xff0c;若a-b是k的倍数&#xff0c;则a和b分别除以k得到的余数相同。 题目 题解&#xff1a; class Solution { public:bool checkSubarraySum(vector<…

模块(一)

一.模块 当程序开发时&#xff0c;代码越写越多&#xff0c;这样不利于维护。而把函数分组&#xff0c;放到不同的文件中&#xff0c;这样每个文件中的代码就变少。 而每个.py文件就叫一个模块 二.使用模块的好处 1.利于维护 2.当重新写一个代码时不需要重零开始可以直接调用 3…

wordnet java_wordnet 这是一款进行词义分析的 调用程序,可以 相似词计算,以及寻找父类词等 Java Develop 254万源代码下载- www.pudn.com...

文件名称: wordnet下载 收藏√ [5 4 3 2 1 ]开发工具: Java文件大小: 1229 KB上传时间: 2016-03-23下载次数: 0提 供 者: xxc详细说明&#xff1a;这是一款进行词义分析的 wordnet调用程序&#xff0c;可以进行相似词计算&#xff0c;以及寻找父类词等-wordnet use文件列…

原创:Js解析xml文件并简单实现省市区级联菜单(并解决各浏览器兼容性问题)....

原创&#xff1a;Js解析xml文件并简单实现省市区级联菜单(并解决各浏览器兼容性问题). 前不久日本发生了一场惹人非议的地震中,因此也引发了中国购买食盐的狂热份子!然后又因发了一场退盐事件.然后80,90后们并没有参与其中,说明掌握科学知识的重要性.作为一名合格的大学生应该…

ImportError: libopenblas.so.0: cannot open shared object file: No such file or directory

试试这个命令&#xff1a; sudo apt-get install libopenblas-dev 祝你成功&#xff01;

句子(一)

1.Sometimes a difficult state of affairs can bring out a persions best qualities. bring out:显示出&#xff08;一个人的品质&#xff09; 有时候困难的处境可以显示出一个人的最好的品质。