选择排序和堆排序

一  选择排序

(1)思想

假设有十张扑克牌放在桌上,我们需要按从小到大的顺序拿到手上,每次只能选择一张牌拿到手上,那么每一次我们都必须从桌上的扑克牌中选择最小的牌拿起来,一次循环十次,这样就将扑克牌按从小到的顺序拿到手上了。这就是选择排序。

(2)实现

  1. //选择排序  
  2. //输入:待排序数组(A)和数组个数(n)  
  3. //输出:按从小到大排序的数组(A)  
  4. void Select_sort(SortArray *A,int n)  
  5. {  
  6.     int i,j,min;  
  7.     int temp;  
  8.     for (i = 0 ; i < n -1 ; i++)  
  9.     {  
  10.         min = i;  
  11.         for (j = i+1 ; j < n ; j++)  
  12.         {  
  13.             if ((*A)[min] > (*A)[j])  
  14.             {  
  15.                 min = j;  
  16.             }  
  17.         }  
  18.         if (i != min)  
  19.         {  
  20.             temp = (*A)[i];  
  21.             (*A)[i] = (*A)[min];  
  22.             (*A)[min] = temp;  
  23.         }  
  24.     }  
  25. }  
//选择排序
//输入:待排序数组(A)和数组个数(n)
//输出:按从小到大排序的数组(A)
void Select_sort(SortArray *A,int n)
{
    int i,j,min;
    int temp;
    for (i = 0 ; i < n -1 ; i++)
    {
        min = i;
        for (j = i+1 ; j < n ; j++)
        {
            if ((*A)[min] > (*A)[j])
            {
                min = j;
            }
        }
        if (i != min)
        {
            temp = (*A)[i];
            (*A)[i] = (*A)[min];
            (*A)[min] = temp;
        }
    }
}
选择排序是一种简单直观的排序算法,但它并不稳定。其不稳定性体现在:如果一个元素比当前元素小,而该小的元素又出现在一个和当前元素相等的元素后面,那么交换后的稳定性就被破坏了(百度百科解释),照我的理解应该是,如果按序列(3,5,3,2,1)来说,在当前序列中前一个3的优先级大于后面的3,但是第一次排序就将第一个3换到了后面,因此该算法不稳定。

选择排序优于冒泡排序,其比较次数减少了,但是其算法复杂度依然是O(N2).

二  堆排序算法

(1)  思想

在选择排序中,我们每次从待排序数组中选择最小的数是根据遍历数组比较得来的,这种方法的效率低。

在堆排序中,利用最小/最大堆来获取待排序数组的最小/最大值。

(2)  实现

在堆排序中,最重要的是构建最大堆。

  1. //构建 最大堆  
  2. void Heap_adjust(SortArray *A , int s , int n)  
  3. {  
  4.     int temp , i ;  
  5.     temp = (*A)[s];  
  6.     for (i = 2*s+1 ; i <= n ; i = 2*i +1)  
  7.     {  
  8.         if (i < n-1 && (*A)[i] < (*A)[i+1])  
  9.         {  
  10.             ++i;  
  11.         }  
  12.         if (temp > (*A)[i])  
  13.         {  
  14.             break;  
  15.         }  
  16.         (*A)[s] = (*A)[i];  
  17.         s=i;  
  18.     }  
  19.     (*A)[s] = temp;  
  20. }  
//构建 最大堆
void Heap_adjust(SortArray *A , int s , int n)
{
    int temp , i ;
    temp = (*A)[s];
    for (i = 2*s+1 ; i <= n ; i = 2*i +1)
    {
        if (i < n-1 && (*A)[i] < (*A)[i+1])
        {
            ++i;
        }
        if (temp > (*A)[i])
        {
            break;
        }
        (*A)[s] = (*A)[i];
        s=i;
    }
    (*A)[s] = temp;
}
构建最大堆的时间复杂度0(n)

堆排序算法

  1. void Heap_sort(SortArray *A,int n)  
  2. {  
  3.     int i;  
  4.     for (i = n/2-1 ; i >=0; i–)  
  5.     {  
  6.         Heap_adjust(A,i,n-1);  
  7.     }  
  8.   
  9.     for (i = 0 ; i <n ; i ++)  
  10.     {  
  11.         cout<<(*A)[i]<<endl;  
  12.     }  
  13.     for ( i = n -1 ; i >=0 ; i–)  
  14.     {  
  15.         int temp = (*A)[0];  
  16.         (*A)[0] = (*A)[i];  
  17.         (*A)[i] = temp;  
  18.         Heap_adjust(A , 0 , i-1);  
  19.     }  
  20. }  
void Heap_sort(SortArray *A,int n)
{
    int i;
    for (i = n/2-1 ; i >=0; i--)
    {
        Heap_adjust(A,i,n-1);
    }

    for (i = 0 ; i <n ; i ++)
    {
        cout<<(*A)[i]<<endl;
    }
    for ( i = n -1 ; i >=0 ; i--)
    {
        int temp = (*A)[0];
        (*A)[0] = (*A)[i];
        (*A)[i] = temp;
        Heap_adjust(A , 0 , i-1);
    }
}
在堆排序中,需要反复重建最大堆,其时间复杂度为O(nlogn)

所以,总时间复杂度为O(nlogn),其优于冒泡排序和选择排序等。

附:主程序代码

  1. #include <stdio.h>  
  2. #include “stdafx.h”  
  3. #include <iostream>   
  4. using namespace std;  
  5.   
  6. #define MAX 100  
  7. typedef int SortArray[MAX];  
  8.   
  9. int _tmain(int argc, _TCHAR* argv[])  
  10. {  
  11.     int n ;  
  12.     SortArray A;  
  13.     cout<<”/**选择排序和堆排序**/\n”  
  14.         <<”请输入数组个数”<<endl;  
  15.     cin>>n;  
  16.     cout<<”请输入待排序数组”<<endl;  
  17.     for (int i = 0 ; i < n ; i++)  
  18.     {  
  19.         cin>>A[i];  
  20.     }  
  21.     cout<<”正在排序请稍后…..”<<endl;  
  22.     //Bubble_sort(&A,n);  
  23.     //Select_sort(&A,n);  
  24.     //Insert_sort(&A,n);  
  25.     //Shell_sort(&A,n);  
  26.     Heap_sort(&A,n);  
  27.     cout<<”排序结果如下…..”<<endl;  
  28.     for (int i = 0 ; i < n ; i++)  
  29.     {  
  30.         cout<<A[i]<<endl;  
  31.     }  
  32.     system(”pause”);  
  33.     return 0;  
  34. }  
#include <stdio.h>




include "stdafx.h"

include <iostream>

using namespace std;

define MAX 100

typedef int SortArray[MAX];

int _tmain(int argc, _TCHAR* argv[])
{
int n ;
SortArray A;
cout<<"/选择排序和堆排序/\n"
<<"请输入数组个数"<<endl;
cin>>n;
cout<<"请输入待排序数组"<<endl;
for (int i = 0 ; i < n ; i++)
{
cin>>A[i];
}
cout<<"正在排序请稍后....."<<endl;
//Bubble_sort(&A,n);
//Select_sort(&A,n);
//Insert_sort(&A,n);
//Shell_sort(&A,n);
Heap_sort(&A,n);
cout<<"排序结果如下....."<<endl;
for (int i = 0 ; i < n ; i++)
{
cout<<A[i]<<endl;
}
system("pause");
return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值