快速排序 归并排序

1.使用随机值或者中间的位置会降低运行时间
2.赋值数据最后让i的位置为基准的数值,这种方法适用于把第一个数当作基准的情况,其他的不行
3.注意类似于3 2这种无序两个数字的情况
快速排序代码(中间位置为基准):

#include<iostream>
#include<algorithm>
using namespace std;
const int N = 100010;
int arr[N];
int i,j;
void quick_sort(int arr[],int left,int right){
	if(left>=right) return;
	int key = arr[(left + right) / 2], i = left - 1, j = right + 1;
    while (i < j)
    {
        do i ++ ; while (arr[i] < key);
        do j -- ; while (arr[j] > key);
        if (i < j) swap(arr[i], arr[j]);
    }
	quick_sort(arr, left, j);
    quick_sort(arr, j+1, right);     
	
}
int main(){
	int n;
	cin>>n;
	for(i=0;i<n;i++)
	  cin>>arr[i];
    quick_sort(arr,0,n-1);
    for(i=0;i<n;i++)
	  cout<<arr[i]<<" ";
	return 0;
} 

例子:杭电1040
杭电1040题
这道题就用了把第一个数字当作基准而且赋值的做法
AC代码:

#include<iostream>
#include<algorithm>
using namespace std;
const int N = 100010;
int arr[N];
int i,j;
void quick_sort(int arr[],int left,int right){
	if(left>=right) return;
	 i=left;
	 j=right;
	//int key=arr[(i+j)/2];
	int key=arr[i];
	while(i<j){
		while(i<j&&arr[j]>=key) j--;
		if (i < j) arr[i++]=arr[j];
		while(i<j&&arr[i]<key) i++; 
		if (i < j) arr[j--]=arr[i];
				
	}
	arr[i]=key;
	quick_sort(arr, left, i);
    quick_sort(arr, i+1, right);     
	
}
int main(){
int n,T;
cin>>T;
while(T--){
	cin>>n;
	for(i=0;i<n;i++)
	  cin>>arr[i];
    quick_sort(arr,0,n-1);
    for(i=0;i<n;i++){
    	if(i==n-1)
    	cout<<arr[i]<<endl;
    	else
    	cout<<arr[i]<<" ";

    }
	  
}
  	
	return 0;
} 

归并排序:
用了分治思想
分治时,将数列对半分,再对一半的数列对半分,直到每一份只有一个数字,再进行合并,依次向上合并
合并时,相当于以前学的数据结构中两个有序链表合并为一个(两个指针分别比较插入,小指针一直走直到遇到比大指针j大的数字,则把j的数字插入到这个数字前,j每插入一个就向后走一步,再从i往后的开始比较。如果哪一个先结束了,剩下的直接链接在结束的后面即可)
但是在数组中进行插入数据不像链表那么方便,可以借助一个数组,将比较后的结果存储到新的数组中,然后转存到原来数组中。

#include<iostream>
using namespace std;
const int N = 100010;
int a[N];
int temp[N];
void merge(int a[],int l,int r){
	if(l>=r) return;//当划分到l r都指向一个数字时就结束 
	int mid=(l+r)/2;
	merge(a,l,mid);//左边归并排序,使得左子序列有序
	merge(a,mid+1,r);//右边归并排序,使得右子序列有序
	//下面进行合并,想象i,j分别指向两个数列的头部开始比较 
	int k=0,i=l,j=mid+1;//J必须从mid+1开始,考虑下两个数字的情况 
	while(i<=mid&&j<=r)
		if(a[i]<a[j]) temp[k++]=a[i++];
		 else temp[k++]=a[j++]; 
    while (i <= mid) temp[k ++ ] = a[i ++ ];
    while (j <= r) temp[k ++ ] = a[j ++ ];
    k=0;
    while(l<=r) a[l++] = temp[k++]; //将temp中的元素全部拷贝到原数组中
}
int main(){
	int n;
	cin>>n;
	for(int i=0;i<n;i++)
		cin>>a[i];
	merge(a,0,n-1);	
	for(int i=0;i<n;i++)
		cout<<a[i]<<" ";
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值