快排:
基本原理思想:
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; }