山东大学项目实训树莓派提升计划二期(十三)排序

该实验旨在研究和分析快速排序和堆排序算法的时间复杂度,要求实现快速排序的quickSort方法及其辅助方法,以及堆排序的Heap类和heapSort方法。实验内容包括使用Java实现快速排序的递归过程,以及大根堆的添加和删除操作。通过测试类验证排序算法的正确性。实验设计考虑了算法效率和堆的特性,如二叉堆的完全性和堆属性。
摘要由CSDN通过智能技术生成

目录

实验六 排序

实验目的

实验内容

实验代码框架

实验设计的思路与考量

快速排序

堆的性质

堆的存储

堆的实现

使用Heap类进行排序


实验六 排序

实验目的

研究和分析各种排序算法的时间复杂度。

掌握各种算法的设计、实现和分析。

实验内容

1.补充QuickSort类的quickSort(int [] list)、quickSort(int[] list,int first,int last)、partition(int []list ,int first,int last)三个方法,实现从小到大的快速排序。其中:

  • quickSort(int [] list)为快速排序的调用入口。
  • quickSort(int[] list,int first,int last)将会递归调用,把原数组list分成左右两段进行快速排序。
  • partition(int []list ,int first,int last)对分段实现快速排序,形成从小到大的有序数列。
  • 运行测试类QuickSortTest,并通过测试。

2.首先实现类Heap中的add(E newObject)、remove()方法,完成堆的设计与实现;其次实现HeapSort类的heapSort(E[] list)方法,进行堆的排序。其中:

  • 类Heap实现的是大根堆。
  • add(E newObject)为往其中添加数据,并对堆进行调整。
  • remove()为移出堆中第一个元素,并构成新的堆。
  • heapSort(E[] list)调用以上两个方法,实现列表从小到大的排序。
  • 运行测试类HeapSortTest,并通过测试。

实验代码框架

QuickSort类

public class QuickSort {
    public void quickSort(int [] list){
    }

    public static void quickSort(int[] list,int first,int last){
    }

    public static int partition(int []list ,int first,int last){
    }
}

 QuickSortTest类

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.util.Arrays;
import static org.junit.Assert.*;

public class QuickSortTest {

    QuickSort q=new QuickSort();

    @Before
    public void setUp() throws Exception {
        System.out.println("begin");
    }

    @After
    public void tearDown() throws Exception {
        System.out.println("End and success");
    }

    @Test
public void quickSort() {
        for(int k=0;k<10;k++){
            int []result=new int[100];
            int []list=new int[100];
            for(int i=0;i<result.length;i++){
                int x=(int)(Math.random()*100);
                result[i]=x;
                list[i]=x;
            }
            q.quickSort(list);
            Arrays.sort(result);
            assertArrayEquals(result,list);
        }
    }
}

Heap类

public class Heap<E extends Comparable<E>> {
    private java.util.ArrayList<E> list=new java.util.ArrayList<>();

    public Heap(){}

    public Heap(E[] objects){
    }

    public void add(E newObject){
    }

    public E remove(){
        return null;
    }

    public int getSize(){    }
}

 HeapSort类

public class HeapSort {

    public <E extends Comparable<E>> void heapSort(E[] list){
    }

    public static void main(String[] args) {
    }

}

HeapSortTest类

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.util.Arrays;
import static org.junit.Assert.*;
public class HeapSortTest {

    HeapSort h=new HeapSort();

    @Before
    public void setUp() throws Exception {
        System.out.println("begin");
    }

    @After
    public void tearDown() throws Exception {
        System.out.println("End and success");
    }

    @Test
    public void heapSort() {
        for(int k=0;k<10;k++){
            Integer []result=new Integer[100];
            Integer []list=new Integer[100];
            for(int i=0;i<result.length;i++){
                int x=(int)(Math.random()*100);
                result[i]=x;
                list[i]=x;
            }

            h.heapSort(list);
            Arrays.sort(result);
            assertArrayEquals(result,list);
        }
    }
}

实验设计的思路与考量

平常我们常接触的算法是插入排序、冒泡排序等等,对于快速排序、堆排序、基数排序等算法并不熟悉,并且不熟悉他们的实现过程,因此实验选择考察快速排序、堆的实现、堆排序这三个方面。

快速排序

1.快速排序的工作机制为,该算法在数组中选择一个称为基准(pivot)的元素,将数组分为两部分,使得第一部分中的所有元素都小于或等于基准元素,而第二部分中的所有元素都大于基准元素。对第一部分递归地应用快速排序算法,然后对第二部分递归地应用快速排序算法。

2.快速排序的图解

图来源于参考书《Java语言程序设计与数据结构(进阶篇)》

3.在实现时,为方便假定将数组的第一个元素选为基准元素。因此,在最佳情况下,基准元素每次将数组划分为规模大致相等的两个部分;在最差情况下,基准元素每次会将数组划分为一个大的子数组和另外一个空数组。

4.快速排序的T(n)=O(nlogn)。

5.优化:该算法的每次划分都将基准元素放在了恰当的位置。基准元素的选择会影响算法的性能。在理想情况下,应该选择能平均划分两部分的基准元素,可以从这个方面考虑优化。

堆的性质

堆排序使用的是二叉堆,它首先将所有的元素添加到一个堆上,然后不断一处最大的元素以获得一个排好序的线性表。

  1. 形状属性:它是一棵完全二叉树。
  2. 堆属性:每个结点大于或等于他的任意一个孩子。
  3. 在同一个存储空间操作,大根堆得到升序排列的元素,小根堆得到降序排列的元素。

堆的存储

如果堆的大小是已知的,可以将堆存储在一个数组中。但是未知堆的大小时,最好使用ArrayList来存储,因此本实验在堆的实现上使用了ArrayList。

 如果数组/ArrayList的存储起始下标为0,对于位置i处的节点,它的左子节点在位置2i+1处,它的右子节点在位置2i+2处,而它的父节点在位置(i-1)/2处。

堆的实现

  1. 方法add(E newObject)将一个对象追加到树中,如果该对象大于他的父节点,就互换他们。此过程持续到该新对象成为根节点,或者新对象不大于它的父节点。
  2. 方法remove()删除并返回根节点,并且放在数组的最后。为保持堆的特征,该方法将最后的对象移到根节点处,如果该对象小于它的较大的子节点,就互换它们。此过程持续到最后一个对象成为叶子节点,或者该对象不小于它的子节点。

使用Heap类进行排序

首先使用Heap类创建一个对象,使用add方法将所有元素添加到队中,然后使用remove方法从堆中删除所有元素。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值