合并排序:
1、算法思想:将待排序的元素分成两个规模大小一致的集合,分别对这两个集合进行排序,最后合并两个集合,回到最初的规模大小,以完成排序。
合并排序重点在合并。
复杂度分析:
暂略
main.cpp:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;
void mergesort(int a[],int left,int right);//进行分组的步骤
void Merge(int a[],int left,int mid,int right);//合并步骤
int main()
{
int arr[200];
memset(arr,0,sizeof(arr));
int length;
cin >> length;//输入元素数量
for(int i=0;i<length;i++)
cin >> arr[i];//输入元素
mergesort(arr,0,length-1);
for(int i=0;i<length;i++){
cout << arr[i] << " ";
}
}
void mergesort(int a[],int left,int right){
if(left < right){//Q1
int mid = (left + right) / 2;
mergesort(a,left,mid);
mergesort(a,mid+1,right);
Merge(a,left,mid,right);
}
}
void Merge(int a[],int left,int mid,int right){
int k=0;
int i=left;
int j = mid+1;
int b[right-left+1];//临时数组,暂时存放元素
while((i<=mid) && (j<=right)){
if(a[i]<a[j])//逆序改一下符号
b[k++] = a[i++];
else
b[k++] = a[j++];
}
if(i>mid){//左半部分排序完毕
while(j<=right){//排左面
b[k++] = a[j++];
}
}
else{//右半部分排序完毕
while(i<=mid){//排右边
b[k++] = a[i++];
}
}
k = 0;//将临时数组的元素抄写到a数组上
for(int i=left;i<=right;i++){
a[i] = b[k++];
}
}
快速排序
1、算法思想:
先把即将排序的元素进行分解,找到一个合适的位置(期间高位低位不断交换),使得在这个位置,最低位的元素大小放在该位置时正好位于最终的排序位置,低于该位置的元素不大于该元素,高于该位置的元素不小于该元素,然后将最低为元素与该位置元素交换
再把左半部分的和右半部分的进行上述操作。
复杂度分析:
暂略
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;
void quicksort(int a[],int left,int right);
int divide(int a[],int left,int right);
int main()
{
int arr[200];
memset(arr,0,sizeof(arr));
int length;
cin >> length;
for(int i=0;i<length;i++)
cin >> arr[i];
//mergesort(arr,0,length-1);
quicksort(arr,0,length-1);
for(int i=0;i<length;i++){
cout << arr[i] << " ";
}
}
void quicksort(int a[],int left,int right){
if(left < right){
//Q2
int t;
int divide_num = divide(a,left,right);
t = a[left];
a[left] = a[divide_num];
a[divide_num] = t;
quicksort(a,left,divide_num-1);
quicksort(a,divide_num+1,right);
}
}
int divide(int a[],int left,int right){
int high = right+1;
int low = left;
while(1){
while(a[++low] < a[left] && low <right){//现在是按照升序排列,降序改为<号即可
}
//Q3
while(a[--high] > a[left]){//同上
}
//这两步筛选出了左半部分第一个比left位置上的数大的数,右半部分第一个比left位置小的数
if(low >= high) break;
int t = a[low];
a[low] = a[high];
a[high] = t;
}
//Q4
return high;
}
思考以下问题:
Q1:合并排序中left < right能改写成left == right吗?为什么。
Q2:快速排序中left < right能改写成left == right吗?为什么。
Q3:为什么在从左往右寻找不小于判断条件时需要加low <right而从右往左寻找时不需要high >right
Q4:为什么return high而不return low?