选择排序算法

数据结构课程中的两种简单的选择排序算法(简单选择排序算法,堆排序)。

选择排序算法的基本思想是:每一步从待排序的元素中选出一个关键字最小的元素,顺序放在排序的元素序列的最后,这样全部选完之后,排序结束。选择排序算法的效率与初始数据的顺序无关,且每进行一趟排序归位一个元素

1、简单选择排序

思想:从所给的元素中选择最小值放在第一个位置(将第一个位置的元素与最小值交换位置),然后从之后的序列中选择一个最小值放在第二个位置,以此类推,直到排序完成。

算法:用C\C++实现的对一个数组的简单选择排序算法如下:

<span style="font-size:14px;">//简单选择排序
void SelectSort(int a[],int n)
{
        int i,j,k,temp;
        for(i=0;i<n-1;i++)//比较n-1次
        {
                k=i;
                for(j=i+1;j<n;j++)//找出最小值
                        if(a[j]<a[k])
                                k=j;
                if(k!=i)    //交换位置
                {
                        temp=a[i];
                        a[i]=a[k];
                        a[k]=temp;
                }
        }
}</span>

总结:简单选择排序的效率与初始数据的顺序性无关,每进行一趟排序归位一个元素,相关性能如下:

2、堆排序

思想:堆排序用到了一种特殊的二叉树——堆,有大根堆和小根堆;这里用到的是大根堆(可以选择用小根堆),对于给定的关键字序列[0,1,2...n],可以把它直接看成是一个完全二叉树的顺序表示,然后首先是将这个完全二叉树调整成堆;交换第0个和第n个元素(将最大的元素归位),然后将[0,1,2,...n-1]调整成堆,依次一次归位一个元素,直到排序结束。 在堆排序过程中多次调用到了筛选算法,筛选算法的前提是:将[low...high]序列看成是一课以low位置元素为根节点的完全二叉树,而其左右子树全部为大根堆,只有根节点不满足大根堆的条件。

算法:用C\C++实现的对一个数组的堆排序算法如下:

<span style="font-size:14px;">//堆排序
void Shift(int a[],int low,int high) //筛选算法
{
        int i=low,j=2*i,temp=a[i];//j为a[low]的左孩子
        while(j<=high)
        {
                if(j<high&&a[j]<a[j+1])//比较左右孩子的大小
                        j=j+1;
                if(a[j]>temp)          //建立大顶堆
                {
                        a[i]=a[j];
                        a[j]=temp;
                        i=j;
                        j=2*i;
                }
                else break;
        }
}
void HeapSort(int a[],int n)
{
        int i,j,temp;
        for(i=n/2;i>=0;i--)    //初始建堆
                Shift(a,i,n-1);
        for(j=n-1;j>=0;j--)    //堆排序
        {
                temp=a[0];
                a[0]=a[j];
                a[j]=temp;
                Shift(a,0,j-1);
        }

}
</span>
总结:堆排序的效率同样跟初始序列的顺序无关,每进行一趟排序归位一个元素,相关性能如下:



最后关于算法的测试:

/*选择排序算法*/
#include <iostream>
using namespace std;

//简单选择排序
void SelectSort(int a[],int n)
{
        int i,j,k,temp;
        for(i=0;i<n-1;i++)//比较n-1次
        {
                k=i;
                for(j=i+1;j<n;j++)//找出最小值
                        if(a[j]<a[k])
                                k=j;
                if(k!=i)    //交换位置
                {
                        temp=a[i];
                        a[i]=a[k];
                        a[k]=temp;
                }
        }
}

//堆排序
void Shift(int a[],int low,int high) //筛选算法
{
        int i=low,j=2*i,temp=a[i];//j为a[low]的左孩子
        while(j<=high)
        {
                if(j<high&&a[j]<a[j+1])//比较左右孩子的大小
                        j=j+1;
                if(a[j]>temp)          //建立大顶堆
                {
                        a[i]=a[j];
                        a[j]=temp;
                        i=j;
                        j=2*i;
                }
                else break;
        }
}
void HeapSort(int a[],int n)
{
        int i,j,temp;
        for(i=n/2;i>=0;i--)    //初始建堆
                Shift(a,i,n-1);
        for(j=n-1;j>=0;j--)    //堆排序
        {
                temp=a[0];
                a[0]=a[j];
                a[j]=temp;
                Shift(a,0,j-1);
        }

}

//测试函数
int main()
{
        int a[10]={144,232,111,678,329,834,123,230,567,431};
        cout<<"排序之前的数组元素为:";
        for(int i=0;i<10;i++)
                cout<<a[i]<<"  ";
        cout<<endl;

        SelectSort(a,10);
        //HeapSort(a,10);

        cout<<"排序之后的数组元素为:";
        for(int i=0;i<10;i++)
                cout<<a[i]<<"  ";
        cout<<endl;

}
测试结果如下:


你可能感兴趣的:(堆排序,简单选择排序)