快排:
基本原理思想:
1:取标准。
2:从尾部看,大于则减减。小于,则把j位置的值给i位置,并把i++;
3:从头部看,小于则加加。大于,则把i位置的值给j位置,并把j--;
4:把base赋值给最后一个i位置。
5:递归调用。
代码:
#include <iostream>
using namespace std;
int findBaseIndex(int a[],int l,int r)
{
if(l<r)
{
int base=a[l];
int i=l,j=r;
while(i<j)
{
while(a[j]>base && i<j)
j--;
if(i<j)
{
a[i]=a[j];
i++;
}
else
break;
while(a[i]<base && i<j)
i++;
if(i<j)
{
a[j]=a[i];
j--;
}
else
break;
}
a[i]=base;
return i;
}
}
void quickSort(int a[],int l,int r)
{
if(l<r)
{
int index=findBaseIndex(a,l,r);
if(index>l)
quickSort(a,l,index-1);
if(index<r)
quickSort(a,index+1,r);
}
}
int main()
{
int a[]={20,59,4,93,47,1,37};
int len=sizeof(a)/sizeof(a[0]);
int l=0,r=len-1;
quickSort(a,l,r);
for(int i=0;i<len;i++)
{
cout<<a[i]<<" ";
}
return 0;
}
过程中犯下的错误:溢出。ij的值一直控制不好。
归并:
基本原理思想:
1、递归调用mergeSort(),进行分区,结束条件是分区内只有一个元素(即ij相等)。
2、创建临时分区,把相邻分区进行合并。
3、合并到一个临时分区时,分三种情况:相邻分区相继到末尾;或者前面的分区先结束;或者后面的分区先结束。
代码:
#include <iostream>
using namespace std;
void merge(int a[],int mid,int l,int r)
{
int tmpsize = r-l+1;
int *tmp = new int[tmpsize]; //new 在堆上动态开辟内存空间。
int i=l;
int j=mid+1;
int k=0;
while(i<=mid && j<=r) // 这里注意:::i<mid而不是i<l
{
if(a[i]<=a[j])
{
tmp[k++]=a[i++];
}
else
{
tmp[k++]=a[j++];
}
}
while(i<=mid)
{
tmp[k++]=a[i++];
}
while(j<=r)
{
tmp[k++]=a[j++];
}
for(int i=0;i<k;i++)
{
a[l++]=tmp[i];
}
delete[] tmp;
return;
}
void mergeSort(int a[],int l,int r)
{
if(a==NULL || l==r) //这是结束条件
return;
int mid=(l+r)/2;
mergeSort(a,l,mid);
mergeSort(a,mid+1,r);
merge(a,mid,l,r);
return;
}
int main()
{
int a[]={10,8,17,4,16,19,30,2};
int len = sizeof(a)/sizeof(a[0]);
int l=0,r=len-1;
mergeSort(a,l,r);
for (int i=0; i<len; i++)
cout << a[i] << " ";
cout << endl;
return 0;
}