8.2 内部排序法---选择类排序(简单选择、堆排序)

选择类排序:分为简单选择排序、堆排序; 其时间复杂度度分别为:O(n^2)、O(nlogn).

简单选择排序:每一趟从待排序元素中选出最小(或最大)的一个元素,依次存放在已经有序的元素的最后,直到全部待排序的元素全部有序为止!

堆排序:利用堆的特性对元素进行排序。主要分为两部分:创建堆大顶堆(或小顶堆)、调整堆。

下面示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/***********************************************************/
// 程序名称:SwapSort.cpp
// 程序目的:内部排序法---插入类排序
// 程序来源:数据结构与算法分析(C语言版) P-247
// 日期:2013-9-3 16:46:25 JohnnyHu修改
/***********************************************************/

#include <stdio.h>
#include <stdlib.h>

#define Error( str )        FatalError( str )
#define FatalError( str )   fprintf( stderr,  "%s\n", str ), exit(  1 )

#define  MAX         8   
typedef  int ElementType;

void SelectSort(ElementType a[],  int n);
void CreateHeap(ElementType a[],  int n);
void AjustHeap(ElementType a[],  int s,  int n);
void HeapSort(ElementType a[],  int n);
void PrintSort(ElementType a[],  int n);

int main( void)
{
    ElementType data[MAX] = { 051441653855};

    printf( "堆排序前元素序列:\n");
    PrintSort(data, MAX);

     //SelectSort(data, MAX);
    HeapSort(data, MAX);

    printf( "堆排序后元素序列:\n");
    PrintSort(data, MAX);

     return  0;
}

// 两元素互换
void Swap(ElementType& lValue, ElementType& rValue)
{
    ElementType tmp = lValue;
    lValue = tmp;
    lValue = rValue;
    rValue = tmp;
}

/************************************************************************/
// 简单选择排序
/************************************************************************/

void SelectSort(ElementType a[],  int n)
{
     for ( int i =  0; i < n; i++)
    {
         int k = i;           // k表示当前最小元素的下标
        ElementType tmp;
         for ( int j = i +  1; j < n; j++)
        {
             if (a[k] > a[j])
                k = j;       // 每趟最小元素下标为k
        }
         if (k != i)
        {  // k与i不等,a[i]与a[k]互换
            tmp = a[i];
            a[i] = a[k];
            a[k] = tmp;
        }
    }
     return;
}

// 创建大顶堆
void CreateHeap(ElementType a[],  int n)
{
     for ( int i = n/ 2 -  1; i >=  0; i--)   // n/2开始建堆
        AjustHeap(a, i, n);

     return;
}

// 调整堆
#define  leftChild(i)    2 * i +  1
void AjustHeap(ElementType a[],  int i,  int n)
{
     int child;
    ElementType tmp = a[i];  // 保存根节点
     for ( ; leftChild(i) < n; i = child)
    {
        child = leftChild(i);
         if (child != n -  1 && a[child +  1] > a[child])
            child++;
         if (tmp < a[child])      // 两if,保证j为关键字较大结点
            a[i] = a[child];
         else
             break;
    }
    a[i] = tmp;  // 根结点插入到正确位置

     return;
}

/************************************************************************/
// 堆排序
/************************************************************************/

void HeapSort(ElementType a[],  int n)
{
    CreateHeap(a, n);        // 创建堆

     for ( int i = n -  1; i >  0; i--)
    {
        Swap(a[ 0], a[i]);    // 删掉最大值
        AjustHeap(a,  0, i);  // 从根节点开始调整堆
    }

     return;
}

// 打印元素序列
void PrintSort(ElementType a[],  int n)
{
     for ( int i =  0; i < n; i++)
        printf( "[%d]\t", a[i]);
    printf( "\n");

     return;
}
输出结果:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值