快速排序和归并排序

快速排序

1.知识点

1.快速排序主要思想基于分治
2.快速排序不稳定
例如 3 1 2 3 5,分界点 x=3
当i指向第一个数3,j指向倒数第二个数3,会停下来交换两个数

2.步骤

1.确定分界点x
q[l]q[(l+r)/2]q[r]、随机
2.调整区间
区间划分成两部分,使得满足条件:
1、左区间里的所有的数都 <=x
2、右区间里的所有的数都 >=x
比如这个数 ==x,它在左边和右边都是可以的
实现操作:
两个指针i、j分别指向头和尾
从i开始交替移动i、j
移动i直到指向的数满足>=x,说明这个数属于右半边,则停下来
去移动j,直到j指向的数满足 <=x,说明这个数属于左半边,则停下来
交换这两个数(前提条件是i<j 即未相遇且ij的左边)
i,j继续往中间走直至相遇
3.递归
递归处理左右两段

3.代码(带注释)

void quick_sort(int q[],int l,int r){
	if(l>=r){ // 区间没有数或者只有一个数则无需排序  
		return;
	}
	int x=q[(l+r)/2]; //确定分界点 
	/**
	每一次交换完之后要向中间移动一格
	所以每一次先把两个指针往中间移动一次,再判断 
	所以一开始需要放到两个边界点的外面一格,这样经过移动一格后会指导真正的边界 
	**/
	int i=l-1;
	int j=r+1;
	while(i<j){ // 还未相遇 
		while(q[++i]<x); // 说明不满足右区间的条件即不满足 >=x 
		while(q[--j]>x); // 说明不满足左区间的条件即不满足 <=x
		if(i<j){ // 可能i已经在j的右边了才停下来,此时无需交换位置 
			swap(q[i],q[j]);
		}
	}
	quick_sort(q,l,j); // 递归左区间 
	quick_sort(q,j+1,r); // 递归右区间
}

4.代码(不带注释)

void quick_sort(int q[],int l,int r){
	if(l>=r){
		return;
	}
	int x=q[(l+r)/2];
	int i=l-1;
	int j=r+1;
	while(i<j){ 
		while(q[++i]<x);
		while(q[--j]>x);
		if(i<j){ 
			swap(q[i],q[j]);
		}
	}
	quick_sort(q,l,j);
	quick_sort(q,j+1,r);
}

归并排序

1.知识点

1.主要思想是分治
2.归并排序是稳定的
3.与快速排序不同的是:
快速排序以数组中任意一个数为分界点,归并排序以整个数的中间为分界点
快速排序先排序再递归两边,而归并排序是先递归排序

2.步骤

1.确定分界点
mid=(l+r)/2
2.递归排序左边和右边
3.归并
合二为一,把两个有序的数组合并成一个有序的数组
实现操作:
1.有两个有序序列后,一个指针指向第一个序列的第一个数即最小值,另一个指针指向第二个序列的第一个数即最小值
2.每次判断两个指针指向的数字哪个更小,将其存入答案数组,并将这个指针向后移动一位,直到其中有一个指针到序列的最后
3.将剩下的序列的那一段直接补到答案序列中

3.代码(带注释)

int temp[N]; // 用来存答案的临时数组
void merege_sort(int q[],int l,int r){
	if(l>=r){ // 区间没有数或者只有一个数则无需排序
		return;
	}
	int mid=l+r >> 1; // 数组的中间点为分界点 
	merege_sort(q,l,mid); // 递归左半边  
   	merege_sort(q,mid+1,r); // 递归右半边 
	int k=0; //k用来记录temp数组存储到第几个了 
	int i=l; //i用来表示指向第一个有序序列的第一个数即最小值 
	int j=mid+1; //j用来表示指向第二个有序序列的第一个数即最小值 
	while(i<=mid && j<=r){ // 当两个指针都指向所在序列的范围时 
		if(q[i]<=q[j]){ // 比较两个指针所指向的数,选择小的那个数存入temp[],并向右移动一格指针 
			temp[k++]=q[i++];
		} 
		else{
			temp[k++]=q[j++];
		}
	}
	while(i<=mid){ // i指针还没有到终点,将剩余的数直接存入temp[] 
		temp[k++]=q[i++];
	}
	while(j<=r){ // j指针还没有到终点,将剩余的数直接存入temp[] 
		temp[k++]=q[j++];
	}
	for(int i=l,j=0;i<=r;i++,j++){ //将temp数组的数据存回到q[]	 
		q[i]=temp[j];
	}
} 

4.代码(不带注释)

int temp[N];
void merege_sort(int q[],int l,int r){
	if(l>=r){ 
		return;
	}
	int mid=l+r >> 1;
	merege_sort(q,l,mid); 
   	merege_sort(q,mid+1,r); 
	int k=0; 
	int i=l; 
	int j=mid+1; 
	while(i<=mid && j<=r){  
		if(q[i]<=q[j]){
			temp[k++]=q[i++];
		} 
		else{
			temp[k++]=q[j++];
		}
	}
	while(i<=mid){ 
		temp[k++]=q[i++];
	}
	while(j<=r){ 
		temp[k++]=q[j++];
	}
	for(int i=l,j=0;i<=r;i++,j++){	 
		q[i]=temp[j];
	}
} 
posted @ 2021-02-20 16:03  二氧化矽  阅读(85)  评论(0)    收藏  举报