数据结构(二):排序

一、 堆排序

堆:        

        大顶堆:每个结点的值都大于或等于其左右孩子结点的值,即arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2]

        小顶堆:每个结点的值都小于或等于其左右孩子结点的值,即arr[i] <= arr[2i+1] && arr[i] <= arr[2i+2] 。

        堆排序是利用这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序

实现过程:

①将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。

②将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。

③如此反复执行,便能得到一个有序序列了。

C++代码实现:

#include <iostream>
#include <vector>
using namespace std;

// 调节节点
void heapify(vector<int>& arr,int n,int i)
{
    if(i>n)return;
    int left=2*i+1;
    int right=2*i+2;
    int max=i,max_value;
    if(arr[left]>=arr[max]&&left<=n)max=left;
    if(arr[right]>=arr[max]&&right<=n)max=right;
    if(max!=i)
    {
        max_value=arr[max];
        arr[max]=arr[i];
        arr[i]=max_value;
        heapify(arr,n,max);
    }
}

// 构造大顶堆
void build(vector<int>& arr,int n)
{
    if(n<1)return;
    for(int i=(n+1)/2-1;i>=0;i--)
    {
        heapify(arr,n,i);
    }
}

//堆排序
void heapsort(vector<int>& arr)
{
    int n=arr.size()-1;
    for(int i=n;i>0;i--)
    {
        build(arr,i);
        int max=arr[0];
        arr[0]=arr[i];
        arr[i]=max;
    }
}

int main()
{
    vector<int> arr={1,3,2,6,4,7,5,10,9};
    heapsort(arr);
    for(int i=0;i<arr.size();i++)
    {
        cout<<arr[i]<<endl;
    }
}

二、快速排序

基本思想:

        通过一趟排序将待排数组分隔成独立的两部分,左边一部分均比基准值小,右边一部分均比基准值大,分别对这两部分记录继续进行排序,以达到整个序列有序。

实现过程:

①设置左右指针low、high,初始值分别为数组起始序号、末尾序号;设置基准值key,默认基准值为数组第一位,即第一位为空。

②从后面开始向前搜索(high--),找到第一个小于key的arr[high],就将arr[high]赋给arr[low],此时序号为high的位置为空;此时从前面开始向后搜索(low++),找到第一个大于key的arr[low],就将arr[low]赋给arr[high],此时序号为low的位置为空。

③重复步骤②,直到low=high,则将基准值插入该位置,此时基准左边全部小于基准值,右边全部大于基准值。

#include <iostream>
#include <vector>
using namespace std;

// 快速排序
void quicksort(vector<int>& arr,int i,int j)    // arr为待排序数组,i和j分别为左边界和右边界
{
    if(i>=j)return;                             //递归结束条件
    int low=i,high=j,key=arr[low];             //low和high为左右指针,key为基准,现在可以看做low的位置是空的
    while(low<high)
    {
        while(low<high&&arr[high]>key)         //从右到左,寻找比基准小的数
        {
            high--;
        }
        if(low<high)
        {
            arr[low]=arr[high];   
        }
        while(low<high&&arr[low]<key)        //从左到右,寻找比基准大的数
        {
            low++;
        }
        if(low<high)
        {
            arr[high]=arr[low];
        }
    }
    arr[low]=key;                           //当前low=high,左边全部小于基准,右边全部大于基准,因此在该位置插入基准值
    quicksort(arr,i,low-1);
    quicksort(arr,low+1,j);
}

int main()
{
    vector<int> arr={1,3,2,6,5,4,10,9,8};
    quicksort(arr,0,arr.size()-1);
    for(int i=0;i<arr.size();i++)
    {
        cout<<arr[i]<<" ";
    }
    return 0;
    // for(auto value:arr)
    // {
    //     cout<<value<<" ";
    // }
}

三、冒泡排序

基本思想:

        重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。

实现过程:

①比较相邻的元素。如果第一个比第二个大,就交换他们两个。对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。

②不计最后一个元素,重复步骤①,直到第一个元素。

③重复步骤②,直到第一个元素结束,此时数组升序。

#include<iostream>
#include<vector>
using namespace std;

void bubblesort(vector<int>& arr)
{
    int mark,n=arr.size()-1;
    for(int i=n;i>0;i--)
    {
        mark=0;
        for(int j=0;j<i;j++)
        {
            if(arr[j+1]<arr[j])
            {
                mark=1;
                swap(arr[j+1],arr[j]);
            }
        }
        if(mark==0)return;
    }
}

int main()
{
    vector<int> arr={1,3,6,4,5,2,9,4};
    bubblesort(arr);
    for(int i=0;i<arr.size();i++)
    {
        cout<<arr[i]<<" ";
    }
}

四、选择排序

实现过程:

①从未排序元素中寻找最小元素,放到已排序序列的末尾。

②重复步骤①,直到所有元素均排序完毕。

#include<iostream>
#include<vector>
using namespace std;

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

int main()
{
    vector<int> arr={1,5,6,8,2,3,0,5};
    selectsort(arr);
    for(int i=0;i<arr.size();i++)
    {
        cout<<arr[i]<<" ";
    }
    return 0;
}

五、插入排序

实现过程:

①将待排序序列前一部分元素看做一个有序序列,把之后的元素当成是未排序序列。

②从头到尾依次扫描未排序序列,将每个元素插入有序序列的适当位置。

#include<iostream>
#include<vector>
using namespace std;

void insertsort(vector<int>& arr)
{
    int value,i,j;
    for(i=1;i<arr.size();i++)
    {
        value=arr[i];
        for(j=i-1;j>=0&&value<arr[j];j--)
        {
            arr[j+1]=arr[j];
        }
        arr[j+1]=value;
    }
}

int main()
{
    vector<int> arr={1,0,5,2,4,9,2,7};
    insertsort(arr);
    for(int i=0;i<arr.size();i++)
    {
        cout<<arr[i]<<" ";
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值