一、问题描述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); //比较次数加1if (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;}}}}六、程序运行结果快速排序的运行结果:七、心得体会通过这次课程设计,使我彻底明白了理论不等于实践,在课本上本理解的很好的冒泡排序在总体运行的过程中也出现了诸多漏洞,同时暴露出我在数据结构的知识方面的欠缺,而在调试快速排序的时候也不是那么容易上手,因为在以前的实验中未涉及到快速排序的编程问题,我也只是在学习过程中粗略地知道快速排序的排序方法,并未深究。