`
luoweifu
  • 浏览: 60975 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

排序

 
阅读更多

直接插入排序

排序过程

整个排序过程为n-1趟插入,即先将序列中第1个记录看成是一个有序子序列,然后从第2个记录开始,逐个进行插入,直至整个序列有序

算法描述

折半插入排序

排序过程

用折半查找方法确定插入位置的排序叫折半插入排序.

算法描述

算法评价

时间复杂度:T(n)=O(n²)

空间复杂度:S(n)=O(1)

希尔排序(缩小增量法)

排序过程

先取一个正整数d1<n,把所有相隔d1的记录放一组,组内进行直接插入排序;然后取d2<d1,重复上述分组和排序操作;直至di=1,即所有记录放进一个组中排序为止

算法描述

希尔排序特点

l子序列的构成不是简单的“逐段分割”,而是将相隔某个增量的记录组成一个子序列

l希尔排序可提高排序速度,因为

u分组后n值减小,n²更小,而T(n)=O(n²),所以T(n)从总体上看是减小了

u关键字较小的记录跳跃式前移,在进行最后一趟增量为1的插入排序时,序列已基本有序

l增量序列取法

u无除1以外的公因子

u最后一个增量值必须为1

冒泡排序

排序过程

将第一个记录的关键字与第二个记录的关键字进行比较,若为逆序r[1].key>r[2].key,则交换;然后比较第二个记录与第三个记录;依次类推,直至第n-1个记录和第n个记录比较为止——第一趟冒泡排序,结果关键字最大的记录被安置在最后一个记录上

对前n-1个记录进行第二趟冒泡排序,结果使关键字次大的记录被安置在第n-1个记录位置

重复上述过程,直到“在一趟排序过程中没有进行过交换记录的操作”为止

算法描述

快速排序

基本思想

通过一趟排序,将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录进行排序,以达到整个序列有序

排序过程

r[s……t]中记录进行一趟快速排序,附设两个指针ij,设枢轴记录rp=r[s]x=rp.key

l初始时令i=s,j=t

l首先从j所指位置向前搜索第一个关键字小于x的记录,并和rp交换

l再从i所指位置起向后搜索,找到第一个关键字大于x的记录,和rp交换

l重复上述两步,直至i==j为止

l再分别对两个子序列进行快速排序,直到每个子序列只含有一个记录为止

算法描述

简单选择排序

排序过程

l首先通过n-1次关键字比较,从n个记录中找出关键字最小的记录,将它与第一个记录交换

l再通过n-2次比较,从剩余的n-1个记录中找出关键字次小的记录,将它与第二个记录交换

l重复上述操作,共进行n-1趟排序后,排序结束

算法描述

堆排序

堆的定义

n个元素的序列(k1,k2,……kn),当且仅当满足下列关系时,称之为堆

排序过程

将无序序列建成一个堆,得到关键字最小(或最大)的记录;输出堆顶的最小(大)值后,使剩余的n-1个元素重又建成一个堆,则可得到n个元素的次小值;重复执行,得到一个有序序列.

算法描述

排序方法的性能的比较

方法

平均时间

时间

附加空间

稳定性

直接插入

O(n2)

O(n2)

O(1)

稳定的

Shell排序

O(n1.3)

O(1)

不稳定的

直接选择

O(n2)

O(n2)

O(1)

不稳定的

堆排序

O(nlog2n)

O(nlog2n)

O(1)

不稳定的

冒泡排序

O(n2)

O(n2)

O(1)

稳定的

快速排序

O(nlog2n)

O(n2)

O(log2n)

不稳定的

归并排序

O(nlog2n)

O(nlog2n)

O(n)

稳定的

基数排序

O(d(n+r))

O(d(n+r))

O(n+r)

稳定的


排序类的实现

package datastructure.sorter;

import datastructure.common.Strategy;

/**
 * 排序
 * @author luoweifu
 *
 */
public class Sorter implements Strategy {
	/**
	 * 直接插入排序
	 * @param r 要排序的数组
	 * @param low 左端点
	 * @param high 右端点
	 */
	public void insertSort(Object[] r, int low, int high) {
		for(int i=low +1; i<=high; i++) {
			//Object strategy;
			if(compare(r[i],r[i-1]) < 0) {
				Object temp = r[i];
				r[i] = r[i-1];
				int j = i-2;
				for(; j>=low && compare(temp, r[j])<0; j--)
					r[j+1] = r[j];
				r[j+1] = temp;
			}
		}
	}
	
	/**
	 * 折半排序
	 * @param r 要排序的数组
	 * @param low 左端点
	 * @param high 右端点
	 */
	public void  binInsetSort(Object[] r, int low, int high) {
		for(int i=low+1; i<=high; i++) {
			Object temp = r[i];				//保持待插入元素
			int hi = i-1; int lo = low;		//设置初始区间
			while(lo <= hi) {				//折半确定插入位置
				int mid = (lo + hi)/2;
				if(compare(temp, r[mid])<0) 
					hi = mid -1;
				else lo = mid +1;
			}
			for(int j=i-1; j>hi; j--) r[j+1] = r[j];//移动元素
			r[hi+1] = temp;							//插入
		}
	}
	
	/**
	 * 尔排序
	 * @param r 要排序的数组
	 * @param low 左端点
	 * @param high 右端点
	 * @param delta 增量
	 */
	public void shellSort(Object[] r, int low, int high, int[] delta) {
		for(int k=0; k<delta.length; k++) {
			shellInsert(r, low, high, delta[k]);
		}
	}
	private void shellInsert(Object[] r, int low, int high, int deltaK) {
		for(int i=low+deltaK; i<=high; i++) {
			if(compare(r[i], r[i-deltaK])<0) {
				Object temp = r[i];
				int j=i-deltaK;
				for(; j>=low && compare(temp, r[j])<0; j=j-deltaK) 
					r[j+deltaK] = r[j];
				r[j+deltaK] = temp;
			}
		}
	}
	
	/**
	 * 冒泡排序
	 * @param r 要排序的数组
	 * @param low 左端点
	 * @param high 右端点
	 */
	public void bubbleSort(Object[] r, int low, int high) {
		int n = high - low +1;
		for(int i=1; i<n; i++) {
			for(int j=low; j<=high -i; j++) {
				if(compare(r[j],r[j+1])>0) {
					Object temp = r[j];
					r[j] = r[j+1];
					r[j+1] = temp;
				}
			}
		}
	}
	
	/**
	 * 快速排序
	* @param r 要排序的数组
	 * @param low 左端点
	 * @param high 右端点
	 */
	public void quickSort(Object[] r, int low, int high) {
		if(low < high) {
			int pa = partition(r, low, high);
			quickSort(r, low, pa-1);
			quickSort(r, pa+1, high);
		}
	}
	private int partition(Object[] r, int low, int high) {
		Object pivot = r[low];
		while(low < high) {
			while(low<high && compare(r[high], pivot)>=0) high--;
			r[low] = r[high];
			while(low<high && compare(r[low],pivot)<=0) low++;
			r[high] = r[low];
		}
		r[low] = pivot;
		return low;
	}
	
	/**
	 * 简单选择排序
	 * @param r 要排序的数组
	 * @param low 左端点
	 * @param high 右端点
	 */
	public void selectSort(Object[] r, int low, int high) {
		for(int k=low; k<high; k++) {
			int min = k;
			for(int i=min+1; i<=high; i++)
				if(compare(r[i], r[min])<0) min = i;
			if(k != min) {
				Object temp = r[k];
				r[k] = r[min];
				r[min] = temp;
			}
		}
	}
	
	/**
	 * 堆排序
	 * 该方法有点错误,有时间再解决,也希望读者能帮忙解决
	 * @param r 要排序的数组
	 */
	public void heapSort(Object[] r) {
		int n = r.length - 1;
		for(int i=n/2; i>=1; i--)	//初始化键堆
			heapAdjust(r, i, n);
		for(int i=n; i>1; i--) {	//不断输出堆顶元素并调整人r[1....i-1]为新堆
			Object temp = r[1];		//交换堆顶与堆底元素
			r[1] = r[i];
			r[i] = temp;
			heapAdjust(r,1,i-1);//调整
		}
	}
	private void heapAdjust(Object[] r, int low, int high) {
		Object temp = r[low];
		for(int j=2*low; j<=high; j=2*j) {	//沿关键字较大的元素向下进行筛选
			//指向关键字较大的元素
			if(j<high && compare(r[j],r[j+1])<0) j++;
			//若temp比其孩子都大,则插入到low所指位置
			if(compare(temp, r[j])>=0) break;
			r[low] = r[j];
			low = j;	//向下删选
		}
		r[low] = temp;
	}
	
	/**
	 * 归并排序
	* @param r 要排序的数组
	 * @param low 左端点
	 * @param high 右端点
	 */
	public void mergeSort(Object[] r, int low, int high) {
		if(low<high) {
			mergeSort(r, low, (high+low)/2);
			mergeSort(r, (high+low)/2+1, high);
			merge(r, low, (high+low)/2, high);
		}
	}
	private void merge(Object[] a, int p, int q, int r) {
		Object[] b = new Object[r-p+1];
		int s = p;
		int t = q+1;
		int k=0;
		while(s<=q && t<=r) {
			if(compare(a[s],a[t])<0)
				b[k++] = a[s++];
			else 
				b[k++] = a[t++];
		}
		while(s<=q)
			b[k++] = a[s++];
		while(t<=r) 
			b[k++] = a[t++];
		for(int i=0; i<b.length; i++)
			a[p+i] = b[i];
	}
	/**
	 * 把int型的数组转换成包装类Integer的数组
	 * @param a
	 * @return
	 */
	public Integer[] intToInteger(int[] a) {
		Integer b[] = new Integer[a.length];
		for(int i=0; i<a.length; i++) {
			b[i] = Integer.valueOf(a[i]);
		}
		return b;
	}
	

	public boolean equal(Object obj1, Object obj2) {
		// TODO Auto-generated method stub
		return false;
	}

	public int compare(Object obj1, Object obj2) {
		Integer a = (Integer)obj1;
		Integer b = (Integer)obj2;
		if(a.compareTo(b)<0) return -1;
		else if(a.compareTo(b) == 0) return 0;
		else return 1;
	}

	
	
}


/*
class Student implements Strategy {
	public  Integer id ;
	public Student(){
		this.id = 0;
	}
	public Student(int id) {
		this.id = id;
	}
	@Override
	public boolean equal(Object obj1, Object obj2) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public int compare(Object obj1, Object obj2) {
		Student st1 = (Student)obj1;
		Student st2 = (Student) obj2;
		return st1.id.compareTo(st2.id);
	}
	
}
*/

测试

package datastructure.sorter;
/**
 * 测试
 * @author luoweifu
 *
 */
public class Test {

	public static void main(String[] args) {
		//Object[] a = 
		int a[] = {5,6,8,1,8,88,56,78};
		Sorter sort = new Sorter();
		Integer b[] = sort.intToInteger(a);
		//sort.insertSort(a, 0, a.length-1);
		//sort.binInsetSort(a, 0, a.length-1);
		//int b[] = {3,1};
		//sort.shellSort(a, 0, a.length-1, b );
		//sort.bubbleSort(a, 0, a.length-1);
		//sort.quickSort(a, 0, a.length-1);
		//sort.selectSort(a, 0, a.length-1);
		//sort.heapSort(a);				//堆排序,有点错误,有时间再解决
		sort.mergeSort(b, 0, b.length-1);
		for(int i=0; i<b.length; i++) {
			System.out.print(b[i] + "  ");
		}
	}
	
}

结果:

1 5 6 8 8 56 78 88

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics