c++经典算法汇总
来源:互联网 发布:dnf制裁知乎 编辑:程序博客网 时间:2024/05/17 08:04
冒泡排序
经过n-1趟子排序,第i趟子排序从第1个数至第n-i个数,若第i个数比后一个数大(则升序,小则降序)则交换两数O(n^2)
#includeusing namespace std;inline void swap(int &a,int &b){ int c = a; a = b; b = c;}void bublesort(int a[],int n){ for (int i=0 ; i<n ; i++) for (int j=0 ; j a[j+1]) swap(a[j],a[j+1]); }}int main(){ int a[]={10,5,2,7}; bublesort(a,4); for (int i=0;i<4;i++) cout << a[i]<<" "; return 0;}
不足1:在排序过程中,执行完最后的排序后,虽然数据已全部排序完备,但程序无法判断是否完成排序,为了解决这一不足,可设置一个标志单元flag,将其设置为OFF,表示被排序的表示是一个无序的表。在每一排序开始时,检查此标志,若此标志为0,则结束排序;否则进行排序;
#includeusing namespace std;inline void swap(int &a,int &b){ int c = a; a = b; b = c;}void bublesort(int *a,int n){ int flag; for(int i=0;i<n;i++) { while(flag) { flag=0; for (int j=0 ; j a[j+1]) { swap(a[j],a[j+1]); flag=1; } } for (int i=0;i<n;i++) cout << a[i]<<" "; cout << endl; } }}int main(){ int a[]={10,3,2,5,7}; bublesort(a,5); return 0;}
不足2:当排序的数据比较多时排序的时间会明显延长。改进方法:快速排序
选择排序
每一趟从无序数列元素中选出最小(或最大)的一个元素,顺序放在有序数列的最后,直到全部待排序的数据元素排完。O(n^2)
#includeusing namespace std;inline void swap(int &a,int &b){ int c = a; a = b; b = c;}void selectsort(int a[],int n){ int min,i,j; for (i=0;i<n;i++) { min=i; for(j = i+1;j<n;j++) if(a[j]<a[min]) min=j; swap(a[i],a[min]); }}int main(){ int a[]={10,5,2,7}; selectsort(a,4); for (int i=0;i<4;i++) cout << a[i]<<" "; return 0;}
鸡尾酒排序
即定向冒泡排序,先对数组从左到右进行升序的冒泡排序,再对数组进行从右到左的降序的冒泡排序,如此往复O(n^2)
#includeusing namespace std;inline void swap(int &a,int &b){ int c = a; a = b; b = c;}void shaker(int a[],int n){ int top=n,bottom=0; int i,j; bool flag=true; while (flag) { flag = false; for (i = bottom; i < top; i++) if (a[i] > a[i + 1]) { swap(a[i], a[i+1]); flag = true; } top--; for (j = top; j > bottom; j--) if (a[j] < a[j - 1]) { swap(a[j], a[j - 1]); flag = true; } bottom++; }}int main(){ int a[]={10,5,2,7}; shaker(a,4); for (int i=0;i<4;i++) cout << a[i]<<" "; return 0;}
直接插入排序
每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子序列中的适当位置,直到全部记录插入完成为止。O(n^2)
#includeusing namespace std;inline void swap(int &a,int &b){ int c = a; a = b; b = c;}void insertsort(int *a,int n){ int j,i,k; for (i=1;i=0;j--) if(a[j]=0;k--) a[k+1]=a[k]; a[k+1]=temp; } }}int main(){ int a[]={10,3,2,5,7}; insertsort(a,5); for (int i=0;i<5;i++) cout << a[i]<<" "; return 0;}
由于代码太长,现在进行改写,将搜索和数据后移这二个步骤合并
#includeusing namespace std;inline void swap(int &a,int &b){ int c = a; a = b; b = c;}void insertsort(int *a,int n){ int j,i; for (i=1;i<n;i++) if(a[i]=0&&a[j]>temp;j--) a[j+1]=a[j]; a[j+1]=temp; }}int main(){ int a[]={10,3,2,5,7}; insertsort(a,5); for (int i=0;i<5;i++) cout << a[i]<<" "; return 0;}
另一种更简便的方法,如果a[i]<a[i-1],就一直交换,直到a[i]>a[i-1]
#includeusing namespace std;inline void swap(int &a,int &b){ int c = a; a = b; b = c;}void insertsort(int *a,int n){ int i,j; for (i=1;i=0&&a[j]>a[j+1];j--) swap(a[j],a[j+1]);}int main(){ int a[]={10,3,2,5,7}; insertsort(a,5); for (int i=0;i<5;i++) cout << a[i]<<" "; return 0;}
希尔排序
先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。O(n^1.25))
#includeusing namespace std;inline void swap(int &a,int &b){ int c = a; a = b; b = c;}void shellsort(int a[],int n){ int i,j,k,gap; for(gap=n/2;gap>0;gap/=2) for ( i=0;i<gap;i++) for(j=gap+i;j<n;j++) if(a[j]=0 && a[k]>temp) { swap(a[k+gap],a[k]); k-=gap; } a[k+gap]=temp; }}int main(){ int a[]={10,3,2,5,7}; shellsort(a,5); for (int i=0;i<5;i++) cout << a[i]<<" "; return 0;}
现在对该代码进行改进,从原先的一组比完比第二组,改进到比较第一组的前两个数,再比较第二组的前两个数。。。在比较第一组的2、3两个数,再比较第二组的2、3两个数,一次类推
#includeusing namespace std;inline void swap(int &a,int &b){ int c = a; a = b; b = c;}void shellsort(int a[],int n){ int i,k,gap; for(gap=n/2;gap>0;gap/=2) for(i=gap;i<n;i++) if(a[i]=0 && a[k]>temp) { swap(a[k+gap],a[k]); k-=gap; } a[k+gap] = temp; }} int main(){ int a[]={10,3,2,5,7}; shellsort(a,5); for (int i=0;i<5;i++) cout << a[i]<<" "; return 0;}
现在使用直接插入排序中的改善代码3进行边比较边移位的代码优化
#includeusing namespace std;inline void swap(int &a,int &b){ int c = a; a = b; b = c;}void shellsort(int a[],int n){ int i,j,gap; for(gap=n/2;gap>0;gap/=2) for(i=gap;i=0 && a[j]>a[j+gap];j-=gap) swap(a[j],a[j+gap]);}int main(){ int a[]={10,3,2,5,7}; shellsort(a,5); for (int i=0;i<5;i++) cout << a[i]<<" "; return 0;}
快速排序
首先任意选取一个数据(通常选用第一个数据)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面O(nlgn)
#includeusing namespace std;inline void swap(int &a,int &b){ int c = a; a = b; b = c;}void quicksort(int a[],int l,int r){ int i=l,j=r; int symbol=a[l]; //以第一个数做基准 if(i>j) return; while(i<j) { while(isymbol) j--; if(i<j) a[i++]=a[j]; //a[i]=a[j],i++ while(i<j && a[i]<symbol) i++; if(i<j) a[j--]=a[i]; } a[i]=symbol; quicksort(a,l,i-1); quicksort(a,i+1,r);}//第二种排序算法(些许变化,供参考)void quicksort2(int a[],int l,int r){ int i = l; int j = r; int key = a[(i+j)/2]; while(i < j) { for(;(i < r)&&(a[i] < key);i++); for(;(j > l)&&(a[j] > key);j--); if (i <= j) { swap(a[i],a[j]); i++; j--; } } if (i < r) quicksort(a,i,r); if (j > l) quicksort(a,l,j);}int main(){ int a[]={10,3,2,5,7}; quicksort(a,0,5); for (int i=0;i<5;i++) cout << a[i]<<" "; return 0;}
归并排序
把待排序序列分为若干个子序列,每个子序列是有序的(递归分解)。然后再把有序子序列合并为整体有序序列(合并新序列)。O(nlgn)
#includeusing namespace std;void merge(int a[], int first, int last, int temp[]);void mergearray(int a[], int first, int mid, int last, int temp[]);bool mergesort(int a[], int n){ int *temp = new int[n]; if (temp == NULL) return false; merge(a, 0, n - 1, temp); return true;}void merge(int a[], int f, int l, int temp[]){ if (f < l) { int mid = (f+ l) / 2; merge(a, f, mid, temp); merge(a, mid + 1, l, temp); mergearray(a, f, mid, l, temp); //有序数列合并 }}void mergearray(int a[], int f, int mid, int l, int temp[]){ int i = f , j = mid + 1,k = 0; while (i <= mid && j <= l) { if (a[i] < a[j]) temp[k++] = a[i++]; else temp[k++] = a[j++]; } while (i <= mid) temp[k++] = a[i++]; while (j <= l) temp[k++] = a[j++]; for (i = 0; i < k ; i++) a[f+i] = temp[i];}int main(){ int a[]={10,3,2,5,7}; mergesort(a,5); for (int i=0;i<5;i++) cout << a[i]<<" "; return 0;}
堆排序
建立一个(最小/最大)堆H[0..n-1],把堆首和堆尾互换,把堆的尺寸缩小1,并调用filterdown( ),目的是把新的数组顶端数据调整到相应位置,直到堆的尺寸为1O(nlgn)
#includeusing namespace std;inline void swap(int &a,int &b){ int c = a; a = b; b = c;}void heapfilterdown(int a[],int i,int n){ int j=i*2+1; //节点的左孩子 int temp=a[i]; while(j<n) { if(j+1a[j]) j++; if(a[j]=0;i--) //找到对数组最后一个节点的父节点,对应数组需要-1 heapfilterdown(a,i,n);}void heapsort(int a[],int n){ makeminheap(a,n); //排列成最小堆 for(int i=n-1 ; i>0;i--) { swap(a[0],a[i]); //堆顶元素与堆底元素交换 heapfilterdown(a,0,i); //向下排列,形成最大堆 }}int main(){ int a[]={10,5,2,7}; heapsort(a,4); for (int i=0;i<4;i++) cout << a[i]<<" "; //输出为递增函数,如果需输出递减函数,使用最小堆 return 0;}
计数排序
- 找出待排序的数组中最大和最小的元素 2、统计数组中每个值为i的元素出现的次数,存入数组C的第i项 3、对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加) 4、反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1
O(n)
#includeusing namespace std;inline void swap(int &a,int &b){ int c = a; a = b; b = c;}void countsort(int a[] , int n){ int z=0; int min,max; min=max=a[0]; for(int i=0;imax) max=a[i]; if(a[i]<min) min=a[i]; } int clength=max+min+1; //创建一个max+min+1大小的辅助数组 int *c = new int[clength]; for (int i=0 ; i<clength;i++) c[i]=0; for(int i=0;i<n;i++) //将待排数组每一个元素个数记录在对应的辅助数组中 c[a[i]-min]++; for(int i=min ;i<=max;i++) for(int j=0;j<c[i-min];j++) //从小到大遍历辅助数组放入原数组,排序完成 a[z++]=i; delete[] c;}int main(){ int a[]={10,3,2,5,7}; countsort(a,5); for (int i=0;i<5;i++) cout << a[i]<<" "; return 0;}
- 经典排序算法汇总(C#)
- C语言经典算法汇总
- c++经典算法汇总
- 各类经典算法汇总
- 经典排序算法汇总
- 计算机经典算法汇总
- 计算机经典算法汇总
- 经典算法汇总-第一章
- c语言经典试题汇总
- 经典C/C++算法
- 经典c/c++算法
- c语言经典算法~~
- C语言经典算法
- C语言经典算法
- 经典C/C++算法
- C的经典算法
- c的经典算法
- 经典C算法收藏
- VS中C++代码折叠
- JavaScript数组定义
- TUXEDO启动常见错误和解决方法 动常见错误和解决方法
- 自动化脚本批量运行机制
- [重构到模式-Chain of Responsibility Pattern]把哈利波特购书优惠招式重构到责任链模式
- c++经典算法汇总
- Bayesian Filtering
- 触屏手机网站设计
- HTML中Form表单提交时,采用 GET和POST的区别 .
- 数据库方面的好文章收藏
- centos虚拟机NAT静态IP设置
- Ubuntu server安装经验
- 反射(二)
- 连接数据库