数据结构课程设计-排序
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一、问题描述
1、排序问题描述
排序是计算机程序设计的一种重要操作,他的功能是将一组任意顺序数据元素(记录),根据某一个(或几个)关键字按一定的顺序重新排列成为有序的序列。
简单地说,就是将一组“无序”的记录序列调整为“有序”的记录序列的一种操作。
本次课程设计主要涉及几种常用的排序方法,分析了排序的实质,排序的应用,排序的分类,同时进行各排序方法的效率比较,包括比较次数和交换次数。
我们利用java语言来实现本排序综合系统,该系统包含了:插入排序、交换排序、选择排序、归并排序。
其中包括:
(1)插入排序的有关算法:不带监视哨的直接插入排序的实现;
(2)交换排序有关算法:冒泡排序、快速排序的实现;
(3)选择排序的有关算法:直接选择排序、堆排序的实现;
(4)归并排序的有关算法:2-路归并排序的实现。
2、界面设计模块问题描述
设计一个菜单式界面,让用户可以选择要解决的问题,同时可以退出程序。
界面要求简洁明了,大方得体,便于用户的使用,同时,对于用户的错误选择可以进行有效的处理。
二、问题分析
本人设计的是交换排序,它的基本思想是两两比较带排序记录的关键字,若两个记录的次序相反则交换这两个记录,直到没有反序的记录为止。
应用交换排序基本思想的主要排序方法有冒泡排序和快速排序。
冒泡排序的基本思想是:将待排序的数组看作从上到下排列,把关键字值较小的记录看作“较轻的”,关键字值较大的纪录看作“较重的”,较小关键字值的记录好像水中的气泡一样,向上浮;较大关键字值的纪录如水中的石块向下沉,当所有的气泡都浮到了相应的位置,并且所有的石块都沉到了水中,排序就结束了。
冒泡排序的步骤:
1)置初值i=1;
2)在无序序列{r[0],r[1],…,r[n-i]}中,从头至尾依次比较相邻的两个记录r[j]
与r[j+1](0<=j<=n-i-1),若r[j].key>r[j+1].key,则交换位置;
3)i=i+1;
4)重复步骤2)和3),直到步骤2)中未发生记录交换或i=n-1为止;
要实现上述步骤,需要引入一个布尔变量flag,用来标记相邻记录是否发生交换。
快速排序的基本思想是:通过一趟排序将要排序的记录分割成独立的两个部分,其中一部分的所有记录的关键字值都比另外一部分的所有记录关键字值小,然后再按此方法对这两部分记录分别进行快速排序,整个排序过程可以递归进行,以此达到整个记录序列变成有序。
快速排序步骤:
1)设置两个变量i、j,初值分别为low和high,分别表示待排序序列的起始下
标和终止下标。
2)将第i个记录暂存在变量pivot中,即pivot=r[i];
3)从下标为j的位置开始由后向前依次搜索,当找到第一个比pivot的关键字值
小的纪录时,则将该记录向前移动到下标为i的位置上,然后i=i+1;
4)从下表为i的位置开始由前向后依次搜索,当找到第一个比pivot的关键字值
大的记录时,则将该记录向后移动到下标为j的位置上;然后j=j-1;
5)重复步骤3)和4),直到i= =j为止;
6)r[i]=pivot.
三、数据结构描述
快速排序和冒泡排序都属于内部排序,快速排序是不稳定的排序,而冒泡排序是稳定的排序。
内部排序是指带排序序列完全存放在内存中进行的排序过程,这种方法适合数量不太大的数据元素的排序。
四、算法设计
1.冒泡排序的程序流程图
2.冒泡排序算法设计
public void bubbleSort() {
RecordNode temp; //辅助结点
boolean flag = true; //是否交换的标记
for (int i = 1; i < this.curlen && flag; i++) { //有交换时再进行下一趟,最多n-1趟flag = false; //假定元素未交换
for (int j = 0; j < this.curlen - i; j++) { //一次比较、交换
cm[1].setCpn(cm[1].getCpn()+1); //比较次数加1
if (r[j].getKey().compareTo(r[j + 1].getKey()) > 0) { //逆序时,交换
temp = r[j];
r[j] = r[j + 1];
r[j + 1] = temp;
cm[1].setMvn(cm[1].getMvn()+3); //移动次数加3;
flag = true;
}
}
}
}
3.快速排序的程序流程图(1)
4.快速排序的程序流程图(2)
5.快速排序算法设计
public int partition(int i,int j) {
RecordNode pivot=r[i]; //第一个记录作为支点记录
while(i<j){ //从表的两端交替地向中间扫描
while(i<j&&pivot.getKey().compareTo(r[j].getKey())<=0){
j--;
}
if(i<j){
r[i]=r[j]; //将比支点记录关键字值小的记录向前移动
i++;
}
while(i<j&&pivot.getKey().compareTo(r[i].getKey())>0){
i++;
}
if(i<j){
r[j]=r[i]; //将比支点记录关键字值大的记录向后移动
j--;
}
}
r[i]=pivot; //支点记录到位
return i; //返回支点位置
}
public void qSort(int low,int high){
if(low<high){
int pivotloc=partition(low,high);
qSort(low,pivotloc-1);
qSort(pivotloc+1,high);
}
}
public void quickSort(){
qSort(0,this.curlen-1);
}
五、详细程序清单
package KCSJ_Sort;
import java.util.Scanner;
//记录结点类
class RecordNode {
private Comparable key;
private Object element;
public Object getElement() {
return element;
}
public void setElement(Object element) {
this.element = element;
}
public Comparable getKey() {
return key;
}
public void setKey(Comparable key) {
this.key = key;
}
public RecordNode(Comparable key) {
this.key = key;
}
public RecordNode(Comparable key, Object element) {
this.key = key;
this.element = element;
}
}
//关键字类型类
class KeyType implements Comparable<KeyType> {
private int key;
public KeyType() {
}
public KeyType(int key) {
this.key = key;
}
public int getKey() {
return key;
}
public void setKey(int key) {
this.key = key;
}
public String toString() {
return key +"";
}
public int compareTo(KeyType another) {
int thisVal = this.key;
int anotherVal = another.key;
return (thisVal < anotherVal ? -1 : (thisV al == anotherVal ? 0 : 1));
}
}
//比较与移动次数类
class CopareMoveNum{
private int cpn;
private int mvn;
public int getCpn() {
return cpn;
}
public void setCpn(int cpn) {
this.cpn = cpn;
}
public int getMvn() {
return mvn;
}
public void setMvn(int mvn) {
this.mvn = mvn;
}
}
//顺序排序表类
class SeqList {
CopareMoveNum[] cm;
private RecordNode[] r;
private int curlen;
public RecordNode[] getRecord() {
return r;
}
public void setRecord(RecordNode[] r) {
this.r = r;
}
public SeqList(int maxSize) {
this.r = new RecordNode[maxSize];
this.curlen = 0;
this.cm=new CopareMoveNum[3];
for(int i=0;i<3;i++){
this.cm[i] = new CopareMoveNum();
this.cm[i].setCpn(0);
this.cm[i].setMvn(0);
}
}
// 求顺序表中的数据元素个数并由函数返回其值
public int length() {
return curlen; //
}
public void insert(int i, RecordNode x) throws Exception { if (curlen == r.length) {
throw new Exception("顺序表已满");
}
if (i < 0 || i > curlen) {
throw new Exception("插入位置不合理");
}
for (int j = curlen; j > i; j--) {
r[j] = r[j - 1];
}
r[i] = x;
this.curlen++;
}
//输出数组元素
public void display() {
for (int i = 0; i < this.curlen; i++) {
System.out.print(" " + r[i].getKey().toString());
}
System.out.println();
}
// 不带监视哨的直接插入排序算法
public void insertSort() {
RecordNode temp;
int i, j;
for (i = 1; i < this.curlen; i++) {
temp = r[i];
cm[0].setMvn(cm[0].getMvn()+1);
for (j = i - 1; j >= 0 && temp.getKey().compareTo(r[j].getKey()) < 0; j--) {
cm[0].setCpn(cm[0].getCpn()+1);
r[j + 1] = r[j];
cm[0].setMvn(cm[0].getMvn()+1);
}
r[j + 1] = temp;
cm[0].setMvn(cm[0].getMvn()+1);
}
}
// 冒泡排序算法
public void bubbleSort() {
RecordNode temp;
boolean flag = true;
for (int i = 1; i < this.curlen && flag; i++) {
flag = false;
for (int j = 0; j < this.curlen - i; j++) {
cm[1].setCpn(cm[1].getCpn()+1);
if (r[j].getKey().compareTo(r[j + 1].getKey()) > 0) {
temp = r[j];
r[j] = r[j + 1];
r[j + 1] = temp;
cm[1].setMvn(cm[1].getMvn()+3);
flag = true;
}
}
}
}
// 快速排序算法
public int partition(int i,int j) {
RecordNode pivot=r[i];
while(i<j){
while(i<j&&pivot.getKey().compareTo(r[j].getKey())<=0){
j--;
}
if(i<j){
r[i]=r[j];
i++;
}
while(i<j&&pivot.getKey().compareTo(r[i].getKey())>0){ i++;
}
if(i<j){
r[j]=r[i];
j--;
}
}
r[i]=pivot;
return i;
}
public void qSort(int low,int high){
if(low<high){
int pivotloc=partition(low,high);
qSort(low,pivotloc-1);
qSort(pivotloc+1,high);
}
}
public void quickSort(){
qSort(0,this.curlen-1);
}
//简单选择排序算法
public void selectSort() {
RecordNode temp;
for (int i = 0; i < this.curlen - 1; i++) {
int min = i;
for (int j = i + 1; j < this.curlen; j++) {
cm[2].setCpn(cm[2].getCpn()+1);
if (r[j].getKey().compareTo(r[min].getKey()) < 0) {
min = j;
}
}
if (min != i) {
temp = r[i];
r[i] = r[min];
r[min] = temp;
cm[2].setMvn(cm[2].getMvn()+3);
}
}
}
//堆排序算法
public void sift(int low, int high){
int i=low;
int j=2*i+1;
RecordNode temp=r[i];
while(j<high){
if(j<high-1&&r[j].getKey().compareTo(r[j+1].getKey())>0){ j++;
}
if(temp.getKey().compareTo(r[j].getKey())>0){
r[i]=r[j];
i=j;
j=2*i+1;
}
else{
j=high+1;
}
}
r[i]=temp;
}
public void heapSort(){
int n=this.curlen;
RecordNode temp;
for(int i=n/2-1;i>=0;i--){
sift(i,n);
}
for(int i= n-1;i>0;i--){
temp=r[0];
r[0]=r[i];
r[i]=temp;
sift(0,i);
}
}
//归并排序算法
public void merge(RecordNode[] r,RecordNode[] order,int h,int m,int t){ int i=h,j=m+1,k=h;
while(i<=m&&j<=t){
if(r[i].getKey().compareTo(r[j].getKey())<=0){
order[k++]=r[i++];
}
else{
order[k++]=r[j++];
}
}
while(i<=m){
order[k++]=r[i++];
}
while(j<=t){
order[k++]=r[j++];
}
}
public void mergepass(RecordNode[] r,RecordNode[] order,int s,int n){ int p=0;
while(p+2*s-1<=n-1){
merge(r, order, p, p+s-1, p+2*s-1);
p+=2*s;
}
if(p+s-1<n-1){
merge(r, order, p, p+s-1, n-1);
}
else{
for(int i=p;i<=n-1;i++){
order[i]=r[i];
}
}
}
public void mergeSort(){
int s=1;
int n=this.curlen;
RecordNode[] temp= new RecordNode[n];
while(s<n){
mergepass(r,temp,s,n);
display();
s*=2;
mergepass(temp,r,s,n);
display();
s*=2;
}
}
}
//测试类
public class KCSJ_Sort_1 {
static SeqList ST = null;
public static void createSearchList() throws Exception {
ST=new SeqList(20);
Scanner sc=new Scanner(System.in);
System.out.print("请输入排序表的表长:");
int n=sc.nextInt();
KeyType[] k= new KeyType[n];
System.out.print("请输入排序表中的关键字序列:");
for (int i = 0; i < n; i++) { //输入关键字序列
k[i] = new KeyType(sc.nextInt());
}
for(int i=0;i<n;i++){ //创建顺序排序表
RecordNode r = new RecordNode(k[i]);
ST.insert(i, r);
}
}
public static void main(String[] args) throws Exception{
Scanner sc=new Scanner(System.in);
//System.out.println("创建顺序查找表");
//createSearchList();
while(true){
System.out.println(" *************** 欢迎进入排序系统***************\n ");
System.out.println(" ★ 1 直接插入排序 2.冒泡排序 3.快速排序★\n ");
System.out.println(" ★ 4.直接选择排序 5 堆排序 6.归并排序★\n ");
System.out.println (" ★0.退出★\n ");
System.out.println("
*********************************************** \n ");
System.out.print("请输入选择(0-6):");
int i=sc.nextInt();
switch(i){
case 1: System.out.println("---不带监视哨直接插入排序---");
System.out.println("创建顺序排序表");
createSearchList();
ST.insertSort();
System.out.print("排序结果:");
ST.display();
System.out.println("比较次数为:"+ST.cm[0].getCpn());
System.out.println("移动次数为:"+ST.cm[0].getMvn());
break;
case 2: System.out.println("---冒泡排序---");
System.out.println("创建顺序排序表");
createSearchList();
ST.bubbleSort();
System.out.print("排序结果:");
ST.display();
System.out.println("比较次数为:"+ST.cm[1].getCpn());
System.out.println("移动次数为:"+ST.cm[1].getMvn());
break;
case 3: System.out.println("---快速排序---");
System.out.println("创建顺序排序表");
createSearchList();
ST. quickSort();
System.out.print("排序结果:");
ST.display();
break;
case 4: System.out.print("---简单选择排序---");
System.out.println("创建顺序排序表");
createSearchList();
ST.selectSort();
System.out.print("排序结果:");
ST.display();
System.out.println("比较次数为:"+ST.cm[2].getCpn());
System.out.println("移动次数为:"+ST.cm[2].getMvn());
break;
case 5: System.out.print("---堆排序---");
System.out.println("创建顺序排序表");
createSearchList();
ST. heapSort ();
System.out.print("排序结果:");
ST.display();
break;
case 6: System.out.print("---归并排序---");
System.out.println("创建顺序排序表");
createSearchList();
ST. mergeSort ();
System.out.print("排序结果:");
ST.display();
break;
case 0:return;
}
}
}
}
六、程序运行结果
快速排序的运行结果:
七、心得体会
通过这次课程设计,使我彻底明白了理论不等于实践,在课本上本理解的很好的冒泡排序在总体运行的过程中也出现了诸多漏洞,同时暴露出我在数据结构的知识方面的欠缺,而在调试快速排序的时候也不是那么容易上手,因为在以前的实验中未涉及到快速排序的编程问题,我也只是在学习过程中粗略地知道快速排序的排序方法,并未深究。
而在这几天的课程设计过程中,通过老师的帮助和努力钻研,对排序的知识有了更深的认识。
在设计的过程中,团队的合作也是非常重要的,在合作的过程中,要有对集体负责的意识,正是有了这种意识,我们更加愿意通过自己的努力去完善团队的设计,大大地培养了我们团结协作的意识。
总而言之,在这次的课程设计中,受益良多。
审核人:(签名)执笔人:(签名)刘小晶
参与讨论人员:朱蓉、杜伟峰、张丽华。