算法学习之排序

排序算法综述与比较
本文详细归纳了插入排序、堆排序、归并排序、快速排序等常见排序算法的实现、时间复杂度、数据结构及应用,并进行了核心内容的对比分析。

由于学习缘故,将今日所学排序算法做以归纳总结,以备来日便宜:

插入排序:

public static void insertSort(int a[])
	{
		int key;
		for(int j = 2;j < a.length;j++)
		{
			key = a[j];
			//insert a[j] into the sorted sequencea[1..j-1]
			int i = j - 1;
			while(i > 0 && key < a[i])
			{
				a[i + 1] = a[i];//后面大的元素往前挪
				i = i-1;
			}
			a[i+1] = key;//将键值插入
		}
	}

时间复杂度:T(n) = O(n(n - 1)/2) = O(n^2)

思想:边比较变排序,将数组分成排好序的和未排好序两段。

HeapSort

public void maxHeapyfy(int i)//维护一个大顶堆
	{
		if(2*i < a.length && 2*i+1 < a.length)
		{ 
			//System.out.print("@@@@@");
			int leftchild = 2*i;
			int rightchild = 2*i+1;
			int largest;	
			if(leftchild <= heapsize && a[leftchild] > a[i])
				largest = leftchild;
			else largest = i;	
			//System.out.print(a[rightchild]);
			if (rightchild <= heapsize && a[rightchild] > a[largest])
				largest = rightchild;	//找出比较大的元素		
			
			if(largest != i){//如果孩子比父亲大,就交换
				int temp;
				temp = a[i];
				a[i] = a[largest];
				a[largest] = temp;
				maxHeapyfy(largest);//交换完后开始协调孩子节点作为父节点的堆
			}
		}
	}

T(n) = O(h) = O(lgn)

public void buildHeap(){
		System.out.print("建堆过程:"+"\n");
		for(int i = (a.length - 2)/2;i >= 1;i--)//从下往上建堆
		{
			//System.out.print(a[i]);
			maxHeapyfy(i);			
			for(int j = 1;j < a.length - 1;j++)
				System.out.print(a[j]+" ");
			System.out.print("***"+"\n");
		}
	}
T(n) = O(lgn)
public void heapSort()//堆排序
	{
		buildHeap();
		System.out.print("\n"+"建完堆后:"+"\n");
		for(int j = 1;j < a.length - 1;j++)
			System.out.print(a[j]+" ");
		System.out.print("*_*"+"\n"+"排序过程:"+"\n");
		for(int i = a.length - 2;i >= 2;i--)
		{
			int t;
			t = a[i];//每次把第一个换到数组最后一个
			a[i] = a[1];
			a[1] = t;
			heapsize = heapsize - 1;
			for(int j = 1;j < a.length - 1;j++)
				System.out.print(a[j]+" ");
			System.out.print("\n");
			maxHeapyfy(1);
		}
	}

T(n) = O(lgn) + O(nlgn) = O(lgn)
数据结构:数组,用下标来维护父子关系

HeapSort的一个应用:优先队列

<span style="font-size:12px;">public int heapMaxinum()//优先队列最大值
	{
		return a[1];
	}
	
	public int heapExtract()//去掉并返回堆中最大
	{
		if(heapsize < 1)
			System.out.print("heap overflow\n");
		int max = a[1];
		a[1] = a[heapsize];
		heapsize--;
		maxHeapyfy(1);
		return max;
	}
	
	public void heapIncrease(int i,int key)
	{
		if(a[i] > key)
			System.out.print("new key is smaller than current key\n");
		a[i] = key;
		while(i > 1 && a[i/2] < a[i])//满足比父节点要小的性质
		{
			int t = a[i];
			a[i] = a[i/2];
			a[i/2] = t;
			i = i/2;
		}
	}
	
	public void maxInsert(int key)
	{
		heapsize = heapsize + 1;
		a[heapsize] = -9999;
		heapIncrease(heapsize,key);
	}</span>

MergeSort:


MergeSort(a,p,r)
	if p < r
		q = (p+r)/2;
		MergeSort(a,p,q);
		MergeSort(a,q+1,r);
		Merge(a,p,r);	//O(n)

T(n) = 2T(n/2) + O(n)

利用主定理:a = 2;b = 2;n^(log22) = n  == O(n)

                     case2:f(n) = O(n)*1,故k = 0;所以:T(n) = O(nlgn)

QuickSort

public static int partition(int[] a,int p,int r){//对数组a原址重排
		int x = a[r];//令最后一个元素为pivot
		int i = p - 1;
		for(int j = p;j <= r - 1;j++)
		{
			if(a[j] <= x){
				i++;
				int t = a[i];
				a[i] = a[j];
				a[j] = t;
			}
		}
		int t = a[i+1];
		a[i+1] = a[r];//自此,pivot左边的元素均小于它,右边的均大于它
		a[r] = t;
		return i+1;
	}
	
	public static void quickSort(int[] a,int p,int r)
	{
		if(p < r)
		{
			int q = partition(a,p,r);//O(n)
			quickSort(a,p,q-1);
			quickSort(a,q+1,r);
		}
		
	}

pivot刚好在中间时:T(n) = 2(n/2) + O(n)  ==>  T(n) = O(nlgn)

pivot造成0:n-1时(也就是所有元素都相等或者已然排好序(自小到大)):T(n) = T(n-1) + T(0) + O(n) ==> T(n) = O(n^2)




几个排序算法比较

algorithmworst caseaverage casebest casespace coststable ?implements
InsertSortO(n^2) reverse sortedO(n^2)O(n) sortedO(1)yesinsert a[j] to sorted a[1..j-1]
MergeSortO(nlgn)O(nlgn)O(nlgn)O(n)yesDC MergeSort() Merge()
HeapSortO(nlgn)O(nlgn)O(nlgn)O(1)noBuliHeap()  MaxHeapify()
QuickSortO(n^2) (0:n-1)O(nlgn)O(nlgn) 对半O(1)noPartition()
BubbleSortO(n^2)O(n^2)O(n)O(1)yes 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值