你好,游客 登录
背景:
阅读新闻

数据结构与算法之排序(归纳总结三)

[日期:2014-12-24] 来源:博客园  作者:叼烟斗的纤夫 [字体: ]

  选择排序的基本思想是:每一趟从n-i+1 (i=1,2,…,n)个元素中选取一个关键字最小的元素作为有序序列中第i个元素。本节在介绍简单选择排序的基础上,给出了对其进行改进的算法堆排序。

1.简单选择排序

  a:算法描述

  简单选择排序的基本思想非常简单,即:第一趟,从n个元素中找出关键字最小的元素与第一个元素交换;第二趟,在从第二个元素开始的n-1个元素 中再选出关键字最小的元素与第二个元素交换;如此,第k趟,则从第k个元素开始的n-k+1个元素中选出关键字最小的元素与第k个元素交换,直到整个序列 按关键字有序。

  b:算法实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public void selectSort(int[] r, int low, int high) {
    for (int k = low; k < high - 1; k++) { // 作n-1趟选取
        int min = k;
        for (int i = min + 1; i <= high; i++)
            // 选择关键字最小的元素
            if (compare(r[i], r[min]))
                min = i;
        if (k != min) {
            int temp = r[k]; // 关键字最小的元素与元素r[k]交换
            r[k] = r[min];
            r[min] = temp;
        }// end of if
    }// end of for(int k=0…
 
}// end of selectSort

  

【效率分析】
空间效率:显然简单选择排序只需要一个辅助空间。

时间效率:在简单选择排序中,所需移动元素的次数较少,在待排序序列已经有序的情况下,简单选择排序不需要移动元素,在最坏的情况下,即待排序序列 本身是逆序时,则移动元素的次数为3(n-1)。然而无论简单选择排序过程中移动元素的次数是多少,在任何情况下,简单选择排序都需要进行n(n- 1)/2次比较操作,因此简单选择排序的时间复杂度为Ο(n²)

  c:算法示例

  SelectSort.java

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
package com.test.sort.selection;
 
 
public class SelectSort {
 
    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        System.out.println("简单选择排序排序功能实现》》》》");
        int[] arr = { 23, 54, 6, 2, 65, 34, 2, 67, 7, 9, 43 };
 
        SelectSort sort = new SelectSort();
        System.out.println("排序之前序列:");
        sort.printArr(arr);
        sort.selectSort(arr, 0, arr.length - 1);
        System.out.println("排序之后序列:");
        ;
        sort.printArr(arr);
    }
 
    public void selectSort(int[] r, int low, int high) {
        for (int k = low; k < high - 1; k++) { // 作n-1趟选取
            int min = k;
            for (int i = min + 1; i <= high; i++)
                // 选择关键字最小的元素
                if (compare(r[i], r[min]))
                    min = i;
            if (k != min) {
                int temp = r[k]; // 关键字最小的元素与元素r[k]交换
                r[k] = r[min];
                r[min] = temp;
            }// end of if
        }// end of for(int k=0…
 
    }// end of selectSort
 
    public boolean compare(int paramA, int paramB) {
        if (paramA < paramB) {
            return true;
        } else {
            return false;
        }
    }
 
    /**
     * 依次打印出数组元素
     */
    public void printArr(int[] arr) {
        if (arr != null) {
            for (int temp : arr) {
                System.out.print(temp + "  ");
            }
            System.out.println();
        }
    }
}

  

  d:结果输出

2.堆排序

  a:算法描述

    设有n个元素,欲将其按关键字排序。可以首先将这n个元素按关键字建成堆,将堆顶元素输出,得到n个元素中关键字最大(或最小)的元素。然 后,再将剩下的n-1个元素重新建成堆,再输出堆顶元素,得到n个元素中关键字次大(或次小)的元素。如此反复执行,直到最后只剩一个元素,则可以得到一 个有序序列,这个排序过程称之为堆排序。堆排序需要解决两个问题,一个是如何将n个元素的序列按关键字建成堆;一个是输出堆顶元素后,怎样调整剩余n-1 个元素,使其按关键字成为一个新堆。

                        调整堆结构

                      初始堆建立过程

  b:算法实现

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
public void heapSort(int[] r) {
    int n = r.length - 1;
    for (int i = n / 2; i >= 1; i--)
        // 初始化建堆
        heapAdjust(r, i, n);
    for (int i = n; i > 1; i--) { // 不断输出堆顶元素并调整r[1..i-1]为新堆
        int temp = r[1]; // 交换堆顶与堆底元素
        r[1] = r[i];
        r[i] = temp;
        heapAdjust(r, 1, i - 1); // 调整
    }
}
 
// 已知r[low..high]中除r[low]之外,其余元素均满足堆的定义
private void heapAdjust(int[] r, int low, int high) {
    int temp = r[low];
    for (int j = 2 * low; j <= high; j = j * 2) { // 沿关键之较大的元素向下进行筛选
 
        // j指向关键之较大的元素
        if (j < high && compare(r[j], r[j + 1]))
            j++;
        // 若temp比其孩子都大,则插入到low所指位置
        if (!compare(temp, r[j]))
            break;
        r[low] = r[j];
        low = j; // 向下筛选
    }
    r[low] = temp;
}

  c:算法示例

HeapSort.java

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
package com.test.sort.selection;
 
 
public class HeapSort {
 
    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
 
        System.out.println("堆排序排序功能实现》》》》");
        int[] arr = {1, 54, 6, 1, 65, 34, 2, 67, 7, 9, 43 };
 
        HeapSort sort = new HeapSort();
        System.out.println("排序之前序列:");
        sort.printArr(arr);
        sort.heapSort(arr);
        System.out.println("排序之后序列:");
        sort.printArr(arr);
    }
 
    public void heapSort(int[] r) {
        int n = r.length - 1;
        for (int i = n / 2; i >= 1; i--)
            // 初始化建堆
            heapAdjust(r, i, n);
        for (int i = n; i > 1; i--) { // 不断输出堆顶元素并调整r[1..i-1]为新堆
            int temp = r[1]; // 交换堆顶与堆底元素
            r[1] = r[i];
            r[i] = temp;
            heapAdjust(r, 1, i - 1); // 调整
        }
    }
 
    // 已知r[low..high]中除r[low]之外,其余元素均满足堆的定义
    private void heapAdjust(int[] r, int low, int high) {
        int temp = r[low];
        for (int j = 2 * low; j <= high; j = j * 2) { // 沿关键之较大的元素向下进行筛选
 
            // j指向关键之较大的元素
            if (j < high && compare(r[j], r[j + 1]))
                j++;
            // 若temp比其孩子都大,则插入到low所指位置
            if (!compare(temp, r[j]))
                break;
            r[low] = r[j];
            low = j; // 向下筛选
        }
        r[low] = temp;
    }
 
    public boolean compare(int paramA, int paramB) {
        if (paramA < paramB) {
            return true;
        } else {
            return false;
        }
    }
 
    /**
     * 依次打印出数组元素
     */
    public void printArr(int[] arr) {
        if (arr != null) {
            for (int temp : arr) {
                System.out.print(temp + "  ");
            }
            System.out.println();
        }
    }
 
}

  d:结果输出

原文链接:http://www.cnblogs.com/zhangminghui/p/4181121.html

推荐阅读:





收藏 推荐 打印 | 录入: | 阅读:
本文评论   查看全部评论 (0)
表情: 表情 姓名: 字数
点评:
       
评论声明
  • 尊重网上道德,遵守中华人民共和国的各项有关法律法规
  • 承担一切因您的行为而直接或间接导致的民事或刑事法律责任
  • 本站管理人员有权保留或删除其管辖留言中的任意内容
  • 本站有权在网站内转载或引用您的评论
  • 参与本评论即表明您已经阅读并接受上述条款