常用排序
堆排序
void heapAdjust(vector<int>&v,int parent,int length){
for (int j = parent*2; j <=length; j*=2) {
if(j+1<=length && v[j+1]>v[j])
j++;
if(v[parent]>v[j])
break;
swap(v[parent],v[j]);
parent=j;
}
}
void heapSort(vector<int>&v){
for(int i=(v.size()-1)/2;i>=1;--i){ //1
heapAdjust(v,i,v.size()-1);
}
for(int i=v.size()-1;i>=2;i--){
swap(v[1],v[i]);
heapAdjust(v,1,i-1);
}
}
注意点:
1. 其实是用数组存储二叉树,所以,为了方便计算下标,0位置弃用,从1位置开始。不然第一个时,0,其儿子不满足0*2,0*2+1规律。
2. //1 处v.size()-1为最后一个数的下标,除2得到最后一个数的父亲
3. //2处,前面只是j<=m,并没有约束j+1,而//2 &&后面的比较用到j+1,所以必须限制j+1<=m
4. stl中有专门函数可以实现,make_heap,push_heap,pop_heap,sort_heap,
归并排序
递归写法
void merge(vector<int>&srVect,int start,int end,int mid){
vector<int>tmpVect;
int i=start,j=mid+1;
while(i<=mid && j<=end){
if(srVect[i]<srVect[j])
tmpVect.push_back(srVect[i++]);
else
tmpVect.push_back(srVect[j++]);
}
while(i<=mid)
tmpVect.push_back(srVect[i++]);
while(j<=end)
tmpVect.push_back(srVect[j++]);
copy(tmpVect.begin(),tmpVect.end(),srVect.begin()+start);
}
void mergeSort(vector<int>&srVect,int start,int end){
if(start<end){
int mid=(start+end)>>1;
mergeSort(srVetc,start,mid);
mergerSort(srVect,mid+1,end);
merge(srVetc,start,end,mid);
}
}
非递归写法
void mergePass(vector<int>&srVect,int length){
int index=0;
while(srVect.size()-index>=length*2){
merge(srVect,index,index+length*2-1,index+length-1);
}
if(srVect.size()-index>length)//剩下个数介于length,2*length
merge(srVect,index,srVect.size()-1,index+length-1);
}
void mergeSort2(vector<int>&srVect){
int length=1;
while(length<srVect.size()){
mergePass()
length*=2;
}
}
快速排序
int partition(vector<int>&srVect,int left,int right){
int pivotKey=srVectp[left];
while(left<right){
while(left<right && srVect[right]>=pivotKey) //因为while里面还会对right--,所以还要保证减减后,left<right
right--;
swap(srVect[left],srVect[right]);
while(left<right && srVect[left]<=pivotKey)
left++;
swap(srVect[left],srVect[right]);
}
return left;
}
void quickSort(vector<int>&srVect,int left,int right){
if(left<right){ //排序至少要两个数
int index=partition(srVect,left,right);
quickSort(srVect,left,index-1); //index已经排好了,所以不用排index
quickSort(srVect,index+1,right);
}
}
算法复杂度,用主定理:
冒泡排序
void bubbleSort(vector<int>&srVect){
for(int i=0;i<srVect.size()-1;++i){
for(int j=0;j<srVect.size()-i-1;++j){
if(srVect[j]>srVect[j+1])
swap(srVect[j],srVect[j+1]);
}
}
}
二分查找
int binarySearch(vector<int>&srVect,int val){
int left=0,right=srVect.size()-1;
while(left<=right){
int mid=(left+right)>>1;
if(srVect[mid]==val)return mid;
else if(srVect[mid]>val)
right=mid-1;
else
left=mid+1;
}
return -1;
}
kmp算法
int* findNext(char*patternStr){
int*next=(int*)malloc(strlen(patternStr);
int k=-1,j=0;
next[0]=-1;
while(j<strlen(patternStr)){
if(k==-1 || patternStr[k]==patternStr[j]){
++k;
++j;
next[j]=k;
}
else
k=next[k];
}
}
void kmpSearch(char *srStr,char*patternStr ){
int slen=strlen(srStr),plen=strlen(patternStr);
int i=0,j=0;
while(i<slen && j<plen){
if(j==-1 || srStr[i]==patternStr[j]){
++i;
++j;
}
else{
j=next[j];
}
}
if(j==plen)
return i-plen;
else
return -1;
}
strcpy,memcpy,memmove
char* strcpy(char*dst,char*src){
if(dst==NULL || src==NULL)return NULL;
char*tmp=dst;
while(*src!=0)
*dst++=*src++;
*dst=0;
return tmp;
}
void* memcpy(void*dst,void*src,size_t count){
if(dst==NULL || src==NULL)return NULL;
char*pdst=(char*)dst;
char*psrc=(char*)scr;
while(count>0){
*pdst++=*src++;
--count;
}
return dst;
}
void* memmove(void*dst,void*src,size_t count){
if(dst==NULL || src==NULL)return NULL;
char*pdst=(char*)dst;
char*psrc=(char*)scr;
if(pdst<=psrc || pdst>psrc+count){ //forward copy
while(count>0){
*pdst++=*psrc++;
--count;//count要记得减少
}
}
else{
while(count>0){
*(pdst+count)=*(psrc+count);
--count;
}
}
return dst;
}
注意点
- strcpy要考虑最后的’\0’,
- memmove要考虑覆盖问题,当pdst不在psrc的范围内,即pdst<=psrc || pdst>psrc+count,用前向拷贝
- memcpy,memmove第三个参数要是size_t
- strcpy,memcpy,memmove要记得先判断指针不为NULL