一、建立顺序表节点的类
package sorts;
public class RecordNode {
private Comparable key; //关键字
private Object element; //数据元素
public Comparable getKey() {
return key;
}
public void setKey(Comparable key) {
this.key = key;
}
public Object getElement() {
return element;
}
public void setElement(Object element) {
this.element = element;
}
public RecordNode(Comparable key){
this.key=key;
}
public RecordNode(Comparable key,Object element){
this.key=key;
this.element=element;
}
}
二、构建顺序表
public class SeqList {
private RecordNode[] r; //顺序表记录结点数组
private int curlen; //顺序表长度,即记录个数
//顺序表的构造方法,构造一个存储空间容量为maxSize的顺序表
public SeqList(int maxSize){
this.r=new RecordNode[maxSize]; //为顺序表分配maxSize个存储单元
this.curlen=0; //置顺序表的当前长度为0
}
public RecordNode[] getRecord(){
return r;
}
public void setRecord(RecordNode[] r){
this.r=r;
}
public int getCurlen(){
return curlen;
}
}
三、冒泡排序
基本思想:每两个相邻的数相互比较,如果前一个数比后一个数大就交换位置,第一轮可以得出最大数,第二轮可以得出第二大的数,以此类推。
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++){
if(r[j].getKey().compareTo(r[j+1].getKey())>0){
temp=r[j];
r[j]=r[j+1];
r[j+1]=temp;
flag=true;
}
}
}
}
四、快速排序
基本思想:一般选用第一个数作为支点。先从最后一个开始和支点比较,如果比支点大,则继续j--和支点比较,如果比支点小就和r[i]交换。交换后,就从左边第一个起,与支点比较,如果比支点小,则i++继续和支点比较,如果比支点大,就和r[j]相交换。一轮结束后,递归继续。
//1.一趟快速排序
public int Partition(int i,int j){
RecordNode pivot=r[i]; //第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;
}
//2.采用递归形式进行快速排序
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++){ //n-1趟排序
int min=i;
for(int j=i+1;j<this.curlen;j++){
if(r[j].getKey().compareTo(r[min].getKey())<0){
min=j;
}
}
if(min!=i){
temp=r[i];
r[i]=r[min];
r[min]=temp;
}
}
}
六、堆排序
//1.创建初始堆
public void sift(int low,int high){
int i=low; //子树的根节点
int j=2*i+1; //j为i结点的左孩子
RecordNode temp=r[i];
while(j<high){ //沿较小值孩子结点向下筛选
if(j<high-1&&r[j].getKey().compareTo(r[j+1].getKey())>0){
j++; //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;
}
//2.堆排序
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);
}
}
七、归并排序
//1.两个相邻有序序列的归并
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){ //将r中两个相邻子序列归并到order中
if(r[i].getKey().compareTo(r[j].getKey())<=0){ //较小值复制到order中
order[k++]=r[i++];
}
else{
order[k++]=r[j++];
}
}
while(i<=m){ //将前一个子序列剩余元素复制到order中
order[k++]=r[i++];
}
while(j<=t){ //将后一个子序列剩余元素复制到order中
order[k++]=r[j++];
}
}
//2.一趟归并排序算法
public void mergepass(RecordNode[] r,RecordNode[] order,int s,int n){
int p=0; //p为每一对待组合并表的第一个元素的下标,初始值为0
while(p+2*s-1<=n-1){ //两两归并长度均为s的有序表
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中
order[i]=r[i];
}
}
}
//3.2-路归并排序
public void mergeSort(){
int s=1; //s为已排序的子序列长度,初始值为1
int n=this.curlen;
RecordNode[] temp=new RecordNode[n]; //定义长度为n的辅助数组temp
while(s<n){
mergepass(r,temp,s,n); //一趟归并,将r数组中各子序列归并到temp中
s*=2; //子序列长度加倍
mergepass(temp,r,s,n); //将temp数组中各子序列再归并到r中
s*=2;
}
}
八、插入排序
public void insertSort(){
RecordNode temp;
int i,j;
for(i=1;i<this.curlen;i++){ //n-1趟扫描
temp=r[i]; //将待插入的第i条记录暂存在temp中
for(j=i-1;j>=0&&temp.getKey().compareTo(r[j].getKey())<0;j--){
r[j+1]=r[j];
}
r[j+1]=temp;
}
}
九、实例
package sorts;
public class test {
public static void main(String[] args) throws Exception{
SeqList SL=new SeqList(20);
RecordNode[] rd=new RecordNode[20];
for(int i=0;i<rd.length;i++){
rd[i]=new RecordNode((int)(Math.random() * 100));
}
SL.setRecord(rd);
for(int j=0;j<rd.length;j++){
SL.insert(j,rd[j]);
}
//System.out.println("curlen="+SL.getCurlen());
System.out.println("排序前:");
for(int i=0;i<rd.length;i++){
System.out.print(rd[i].getKey()+" ");
}
SL.bubbleSort();
System.out.println(" ");
System.out.println("冒泡排序后:");
for(int i=0;i<rd.length;i++){
System.out.print(rd[i].getKey()+" ");
}
SL.quickSort();
System.out.println(" ");
System.out.println("快速排序后:");
for(int i=0;i<rd.length;i++){
System.out.print(rd[i].getKey()+" ");
}
SL.selectSort();
System.out.println(" ");
System.out.println("选择排序后:");
for(int i=0;i<rd.length;i++){
System.out.print(rd[i].getKey()+" ");
}
SL.heapSort();
System.out.println(" ");
System.out.println("堆排序后:");
for(int i=0;i<rd.length;i++){
System.out.print(rd[i].getKey()+" ");
}
SL.mergeSort();
System.out.println(" ");
System.out.println("归并排序后:");
for(int i=0;i<rd.length;i++){
System.out.print(rd[i].getKey()+" ");
}
SL.insertSort();
System.out.println(" ");
System.out.println("插入排序后:");
for(int i=0;i<rd.length;i++){
System.out.print(rd[i].getKey()+" ");
}
}
}
十、运行结果