您的位置:首页 > 运维架构 > Shell

Java实现排序(插入排序+冒泡排序+选择排序+ Shell排序+快速排序)

2009-04-14 20:54 381 查看
以对ArrayList集合中的Integer元素进行升序排序为例:

package org.hyp.test;

import java.util.ArrayList;
import java.util.Random;

public class MySort {
private ArrayList<Integer> list;

public ArrayList<Integer> getList() {
return list;
}

public MySort(int num, int mod) {
list = new ArrayList<Integer>(num);
for(int i=0;i<num;i++) {
list.add(new Integer(Math.abs(new Random().nextInt() % mod + 1)));
}
}

/*
*【冒泡排序】从首元素开始,比较相邻两个元素,如果0号元素比1号大,则交换两者位置,同时右移一个位置,再比较相邻
* 两个元素,假设元素总数为N,则第一轮遍历经过N-1次后,最大的元素已经排在最末标记位,第二轮比较除它之外剩余元
* 素,将次大元素排在倒数第二标记位,遍历N-2次,依次类推
*/
public void bubbleSort() {
for(int i=0;i<list.size()-1;i++) {
for(int j=i+1;j<list.size();j++) {
if(((Integer)list.get(i)).intValue() > ((Integer)list.get(j)).intValue()) {
swap(i, j);
}
}
}
}

/*
*【选择排序】设定一个最小值元素标志位(初始值标记为0号元素),比较0号元素和1号元素,将标记位移动到更小的元素上,然后
* 继续和后面所有元素比较,遍历一次后,标志位将指向最小的元素,此时交换该元素与0号元素位置,开始第二轮遍历,此时最小
* 标志位初始值为待遍历集合的最左边的元素,依次循环。
* 注意它对冒泡排序的改进在于,并不是每次比较后都交换位置,而是设定标记位,比较一轮之后才交换位置,确定最小元素
*/
public void selectSort() {
for(int i=0;i<list.size()-1;i++) {
int minIndex = i;
for(int j=i+1;j<list.size();j++) {
if(((Integer)list.get(j)).intValue() <= ((Integer)list.get(minIndex)).intValue())
minIndex = j;
}
swap(minIndex, i);
}
}

/*
*【插入排序】它采用的是冒泡和选择中都没有出现的局部排序。从排序过程的中间来理解,此时中间某的元素左边的所有元素都
*已经是局部有序的,即每个元素都比它前面的元素小,但是这些元素的最终位置还未确定,因为它们外面还有若干元素未参与排
*序,需要从已局部有序的元素序列最右边的元素的后一个开始,先将其自身位置空出(这里用临时空间存储元素),将其与序列中
*每个元素比较,若碰到最后一个比它大的,则将这些比它大的元素都向右移动一个位置,然后再将该元素插入到空出的位置中。
*/
public void insertSort() {
for(int i=1;i<list.size();i++) {
for(int j=i;j>0 && ((Integer)list.get(j-1) >= (Integer)list.get(j));j--) {
swap(j-1, j);
}
}
}

/*
*【希尔排序】它通过设定增量,将序列分成若干子序列,分别对这些子序列进行插入排序,不断减少增量(即子序列中元素与元素
*之间的间隔)直至为1,最后一次即是对于整个序列进行一次插入排序。这里简单采用序列长度不断减半的值作为增量,也可以采
*用h=3*h+1等其他增量序列
*/
public void shellSort() {
for(int i=list.size()/2;i>0;i/=2) {
for(int j=0;j<i;j++) {
sort(list, j, i);
}
}
}

//工具方法,对增量序列进行插入排序操作
private void sort(ArrayList<Integer> list, int start, int inc) {
for(int i=start+inc;i<list.size();i+=inc) {
for(int j=i;(j>=inc) && (((Integer)list.get(j)).intValue() < ((Integer)list.get(j-inc)).intValue());j -= inc) {
swap(j, j-inc);
}
}
}

/*
*【快速排序】从序列中找出一个元素做枢纽值,将序列分为左右两个子序列,经过排序后,左边一组全部大于枢纽值,
*右边一组全部小于枢纽值。这里简单采用序列中间位置的元素做枢纽值,然后将其与左边序列第一个元素位置互换,
*然后低位指针从第二个元素向上扫描,遇到比枢纽值小的元素则上移一位,高位指针从最后一个元素向下扫描,遇到
*比枢纽值大的元素则下移一位,最后当低位指针位置高于或等于高位指针时,排序完成。由于此时高位指针指向的元素
*仍旧是比枢纽值小的,所以将其与第一个元素(即枢纽值)位置互换,则此时枢纽值左边的序列全部小于它,右边的序列
*全部大于它,然后再分别对两个子序列递归调用快速排序
*/
public void quickSort(ArrayList<Integer> list, int low, int high) {
Integer pivot;
int scanup, scandown, mid;
if(high - low <= 0)
return;
else
if(high - low == 1) {
if(list.get(high) < list.get(low)) {
swap(low, high);
return;
}
}
mid = (low + high) / 2;
pivot = list.get(mid);
swap(low, mid);
scanup = low + 1;
scandown = high;
do {
while(scanup <= scandown && list.get(scanup) <= pivot)
scanup ++;
while(list.get(scandown) > pivot)
scandown --;
if(scanup < scandown)
swap(scanup, scandown);
} while(scanup < scandown);
list.set(low, list.get(scandown));
list.set(scandown, pivot);
if(low < scandown -1)
quickSort(list, low, scandown -1);
if(high > scandown + 1)
quickSort(list, scandown + 1, high);
}

//工具方法,实现集合中两个元素互换位置
private void swap(int i1, int i2) {
Integer temp = list.get(i1);
list.set(i1, list.get(i2));
list.set(i2, temp);
}

//工具方法,依次打印集合中各个元素
public void display() {
for(Integer i : list) {
System.out.print(i + " ");
}
System.out.println();
}

public static void main(String[] args) {
MySort ms = new MySort(10, 100);
ms.display();
ms.bubbleSort();
ms.selectSort();
ms.insertSort();
ms.shellSort();
ms.quickSort(ms.getList(), 0, 9);
ms.display();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: