数据结构内部排序分析+代码实现

1.直接插入排序

算法思想:每趟将一个待排序的元素作为关键字,按照其关键字值的大小插入到已经排好的部分序列的适当位置上,直到插入完成。

最好:O(n-1) 最坏: O(n * n)
平均: O(n * n)

void insertSort(int a[],int n){
	int i,j;
	int temp;
	for(int i=2;i<=n;i++){ //下标从1开始,第一个元素有序,从第二个元素开始处理 
		temp=a[i];
		j=i-1;
		while(j>=1&&temp<a[j]){//从待排序之前的元素开始扫描,如果大于待排元素则后移一位。 
			a[j+1]=a[j];
			j--;
		}
		a[j+1]=temp;
	}
} 

2.折半插入排序

算法思想:在直接插入排序中,查找插入位置时采用折半查找的方法。

分析:时间复杂度 O(n * n),比直接插入排序减少了比较次数,在记录移动次数方面和直接插入排序是一样的,所以他们的时间复杂度是一样的。

折半插入排序的记录比较次数和初始序列无关。因为每趟排序折半寻找插入位置时,折半次数是一定的(都是在low>high时结束),折半一次就要比较一次,所以比较次数一定。

void BinInsertSort(int a[],int n){
	
	for(i=1;i<n;i++){
		low=0;
		high=i-1;
		while(low<=high){
			m=(low+high)/2;
			if(a[i]<a[m]) high=m-1;
			else low=m+1;
		}
				//向后移动元素a[high+1...i-1],在a[high+1]处插入a[i] 
		x=a[i];
		for(j=i-1;j>high;j--)
			a[j+1]=a[j];
			
		a[high+1]=x;
	} 
} 

3.希尔排序

算法思路:先将待排序列分割成几个子序列,分别进行直接插入排序,基本有序后再对整个序列进行直接插入排序。

说明:希尔排序是不稳定的,时间复杂度O(nlogn)
希尔排序的增量取法要注意:首先增量序列的最后一个值一定是1,其次除1以外的增量序列中的值没有除1以外的公因子(如 8,2,1不可以,8和2有除1以外的公因子2)

void ShellSort(int a[],int n){
	
	dk=n/2;
	while(dk>=1){
		//一趟希尔排序,对dk个序列分别进行插入排序
		for(i=dk;i<n;i++){
			x=a[i];
			for(j=i-dk;j>=0&&x<a[j];j-=dk)
				a[j+dk]=a[j];
			a[j+dk]=x;
		} 
		dk/=2;
	}
	
} 

4.冒泡排序

算法思想:依次比较相邻元素,逆序则交换,重复n-1次

分析:比较和交换总是发生在相邻元素之间,是稳定的排序算法。时间复杂度O(n * n),空间O(1).

void BubbleSort(int a[],int n){
	
	int i,j,flag;
	for(i=n;i>=2;i--){
		flag=0;
		for(j=2;j<=i;j++){
			if(a[j-1]>a[j]) swap(a[j-1],a[j]),flag=1;
		}
		if(flag==0) return ;
	}
} 

5.快速排序

算法思想:一趟排序把记录分割成独立的两部分,一部分关键字均比另一部分小,然后再分别对两部分快排。

分析:平均情况下,时间复杂度O(nlogn),记录本来有序时为最坏情况,时间复杂度为O(n*n),当每次的枢纽都把表等分为长度相近的两个子表时,速度是最快的.

int Partition(int a[],int low,int high){
	int pivot=a[low];
	while(low<high){
		while(low<high&&a[high]>=privot) --high;
		a[low]=a[high];
		while(low<high&&a[low]<=privot) ++low;
		a[high]=a[low];
	}
	a[low]=privot;
	return low;
}


void quickSort(int a[],int low,int high){
	if(low<=high){
		int pivotpos=Partition(a,low,high);
		quicksort(a,low,pivotpos-1);
		quiclsort(a,privotpos+1,high);
	}
} 

你可能感兴趣的:(数据结构,算法)