排序问题

天大地大妈咪最大 提交于 2020-01-17 17:31:07

排序总共分为8种,

插入排序分为直接插入排序和希尔排序

选择排序分为简单排序和堆排序

交换排序分为冒泡排序和快速排序

还有两种归并排序和基数排序

谭浩强书上给了3种排序,起泡法,比较交换法和选择法

1.直接插入排序

void insert_sort(int a[],int n){
	int i,j,temp;
	for(i=1;i<n;i++)
		if(a[i]<a[i-1]){
			temp=a[i];
			for(j=i-1;temp<a[j]&&j>=0;j--)
				a[j+1]=a[j];
			a[++j]=temp;
		}
}

2.希尔排序

void shell_insert(int a[],int n,int d){
	int i,j,temp;
	for(i=d;i<n;i++)
		if(a[i]<a[i-d]){
			temp=a[i];
			for(j=i-d;j>=0&&temp<a[j];j=j-d)
				a[j+d]=a[j];
			a[j+d]=temp;
		}
}
void shell_sort(int a[],int n){
	int d=n/2;
	while(d>0){
		shell_insert(a,n,d);
		d=d/2;
	}
}

3.简单选择排序

void select_sort(int a[],int n){
	int i,j,k,temp;
	for(int i=0;i<n-1;i++){
		k=i;
		for(j=i+1;j<n;j++)
			if(a[j]<a[k]) k=j;
		if(k!=i){
			temp=a[i];
			a[i]=a[k];
			a[k]=temp;
		}
	}
}

4.堆排序  有3点需要注意

  1.heap_adjust()  for(i=k*2;i<n;i=i*2){//此处如果i=0无法实现,k*2

  2.if(a[0]>=a[i]) break;//注意此处要是a[0],如果是a[k]就错了还是7 a[k]值发生了更新

  3.heap_adjust(a,i-1,1);//这里必须是i-1,已经换出去的数不能在参与调整

  4.void heapsort(int a[],int n)中for(i=n-1;i>1;i--){       i>1

void heap_adjust(int a[],int n,int k){//k是待调整的元素的位置 
	int i;
	a[0]=a[k];
	for(i=k*2;i<n;i=i*2){//此处如果i=0无法实现,k*2 
		if(i<n&&a[i]<a[i+1]) i++;
		if(a[0]>=a[i]) break;//注意此处要是a[0],如果是a[k]就错了还是7 
		else{
			a[k]=a[i];
			k=i;
		}	
	}
	a[k]=a[0];
}
void build_heap(int a[],int n){
	for(int i=n/2;i>0;i--)
		heap_adjust(a,n,i);
}
void heap_sort(int a[],int n){//a[0]空出来 
	int i,temp;
	build_heap(a,n);
	for(i=n-1;i>1;i--){
		temp=a[i];
		a[i]=a[1];
		a[1]=temp;
		heap_adjust(a,i-1,1);//这里必须是i-1,已经换出去的数不能在参与调整 
	}
}
int main(){
	int a[8]={0,4,6,2,5,7,1,3};
	//insert_sort(a,7);
	//shell_sort(a,7);
	//select_sort(a,7);
	heap_sort(a,8);
	for(int i=1;i<=7;i++)
		printf("%d  ",a[i]);
	return 0;
} 

5.冒泡排序

 注意1. i<n-2,这个n-2来自j的取值范围j<n-i-1 n-i-1=1(当j=0时,a[0]和a[1]比较,所以j最小<1,i=n-2,故i<n-1)

         2.j<n-i-1,因为j+1最大取到n-1,则j最大取到n-2

void bubble_sort(int a[],int n){
	int i,j,temp;
	for(i=0;i<n-1;i++)
		for(j=0;j<n-i-1;j++)
			if(a[j]>a[j+1]){
				temp=a[j];
				a[j]=a[j+1];
				a[j+1]=temp;	
			}
}

6.快速排序

int partition(int a[],int low,int high){
	int prio=a[low],temp;
	while(low<high){
		while(low<high&&a[high]>=prio) high--;
		temp=a[low];
		a[low]=a[high];
		a[high]=temp;
		while(low<high&&a[low]<=prio) low++;
		temp=a[high];
		prio=a[low];
		a[high]=temp;
	}
	return low;
}
void quick_sort(int a[],int low,int high){
	int mid;
	if(low<high){
		mid=partition(a,low,high);
		quick_sort(a,low,mid-1);
		quick_sort(a,mid+1,high);
	}
}

7.二路归并  要注意一点,在merge中注意最后把临时数组赋给a时,要从left开始,a数组和b数组可能长度不一样,分治思想

void merge(int a[],int left,int right,int mid){
	int b[right-left+1],i=left,j=mid+1,k=0;
	while((i!=mid+1)&&(j!=right+1)){
		if(a[i]<=a[j])
			b[k++]=a[i++];
		else b[k++]=a[j++];
	}
	while(i!=mid+1) b[k++]=a[i++];
	while(j!=right+1) b[k++]=a[j++];
	for(i=0;i<right-left+1;i++)
		a[left+i]=b[i];
}
void merge_sort(int a[],int left,int right){
	if(left<right){
		int mid=(left+right)/2;
		merge_sort(a,left,mid);
		merge_sort(a,mid+1,right);
		merge(a,left,right,mid);
	}
}

8.基排序  不太好整的样子,还要取每一位,不知道咋个办

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!