加油啊,都记住

来源:互联网 发布:炽阳魔盒软件下载 编辑:程序博客网 时间:2024/05/18 10:09

。。。。。。。

#include<iostream>#include <vector>#include <algorithm>using namespace std;void swap(vector<int>&a, int i, int j){int temp = a[i];a[i] = a[j];a[j] = temp;}/*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*///冒泡排序法                      (复杂度高,但好处是也可以适用于链表)//稳定排序//循环交换相邻元素,将最大(小)从最后冒出来;循环两层循环//复杂度://       最好情况:顺序:扫描一遍, n-1次比较 O(n)//       最坏情况:逆序:n-1+n-2 +n-3+...+ 3+2+1 = n*(n-1)/2 次比较,并做等数量级的记录移动,  O(n*n)//       辅助空间O(1)vector<int> &bubleSort(vector<int>& A){int len = A.size();for (int i = len - 1; i > 0; i--){bool flag = false;for (int j = 0; j<i; j++)if (A[j]>A[j + 1])  //严格大于才交换,保证了稳定性{int temp = A[j];A[j] = A[j + 1];A[j + 1] = temp;flag = true;}if (flag) break;//加入标志,优化}return A;}/*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*///简单选择排序 //稳定排序//0位置元素与后面每一个元素比较,遍历一遍,找出最小的,进行交换。以此类推。两层循环//时间复杂度  O(n*n)vector<int> &selectSort(vector<int>& A){int len = A.size();for (int i = 0; i < len; i++){int min = i;for (int j = i+1; j < len; j++)  //找到最小元{if (A[j] < A[min])  //严格大于才交换,此时是稳定排序min = j;}if (min != i){int temp = A[i];A[i] = A[min];A[min] = temp;}}return A;}/*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*///直接插入排序 //稳定排序//复杂度://       最好情况:顺序:  n-1次比较 O(n)//       最坏情况:逆序:n-1+n-2 +n-3+...+ 3+2+1 = n*(n-1)/2 次比较,并做    记录移动,  O(n*n)//       辅助空间O(1)vector<int> &insertSort(vector<int>& A){int len = A.size();for (int i = 1; i < len; i++)     //左手中拿着0号位置的牌,然后右手抓扑克牌{int temp = A[i];               //右手抓住一张扑克牌/*for (int j = i-1; j >= 0; j--) {if (A[j] <= temp){A[j + 1] = temp;break;}if (A[j]>temp){A[j + 1] = A[j];}}*/int j;for (j= i; j > 0 && A[j - 1] > temp; j--)A[j] = A[j - 1];A[j] = temp;}return A;}/*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*///希尔排序                       对直接插入排序的的改进//不稳定排序//比O(n*n) 好一点,O(n 的 3/2  次方),vector<int> &shellSort(vector<int> &A){int len = A.size();int increment = len;while (true){increment = 1+ increment / 3 ;            //增量序列for (int x = 0; x < increment;x++)for (int i = x+increment; i < len; i=i+increment)//for (int i =increment; i < len; i++) 可以这一句代替上面两句for{int temp = A[i];int j;for (j = i; j>=increment && A[j - increment]>temp; j = j - increment)A[j] = A[j - increment];A[j] = temp;}if (increment == 1)break;}return A;}/*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*///堆排序                  对简单选择排序的改进,如何快速找到最大元,构建大堆结构//不稳定排序//时间复杂度 :  //           比 O(NlogN)好点,但实际用起来没有希尔排序里面的。。好用void headAjust(vector<int>& A, int start, int end) //   start 大堆起始元素标号,大堆结束元素标号{int temp = A[start];for (int j = 2 * (start + 1) - 1; j <= end; j = (1 + j) * 2 - 1)//沿关键字较大的孩子节点向下筛选,完全二叉树性质,父节点标号和左右子节点标号2倍数的关系{if (j < end&&A[j] < A[j + 1])++j;if (temp>=A[j])break;A[start] = A[j];start = j;}A[start] = temp;   //插入}void heapSort(vector<int>& A){int N = A.size();for (int i = N/2 -1; i >= 0; i--)//建立大顶堆  从下往上,从右往左 ,将每个非叶子节点当做根节点,将其与其子树调整成大顶堆    headAjust(A, i, N-1);    for (int i = N - 1; i > 0; i--)  {swap(A, 0, i);           //每次删掉一个最大值headAjust(A,0,i-1);}}/*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*///归并排序              有序子列的合并//稳定排序//时间复杂度://             O(NlogN)void merge(vector<int>&A,vector<int>&tempA,int L,int R,int rightEnd){int leftEnd = R - 1;int numElements = rightEnd - L + 1;int temp = L;//临时数组存放的初始位置while (L<=leftEnd&&R<=rightEnd){if (A[L] <= A[R])tempA[temp++] = A[L++];elsetempA[temp++] = A[R++];}while (R <= rightEnd)//直接复制右边剩下的tempA[temp++] = A[R++];while (L <= leftEnd)tempA[temp++] = A[L++];//直接复制左边剩下的for (int i = 0; i < numElements; i++, rightEnd--)//元素个数次循环{A[rightEnd] = tempA[rightEnd];}}//分而治之//强时间复杂度:T(N)=O(NlogN)////空间复杂度: O(N+logN)void mSort(vector<int>&A,vector<int>&tempA,int L,int rightEnd){int center;if (L < rightEnd){center = (L + rightEnd) / 2;mSort(A, tempA, L, center);//T(N/2)mSort(A, tempA, center + 1, rightEnd);//T(N/2)merge(A, tempA, L, center + 1, rightEnd);// O(n)}}void mergeSort(vector<int>& A){int N = A.size();vector<int> tempA;tempA.resize(N);if (tempA.size() != 0){mSort(A, tempA, 0, N - 1);}else{return;}}void merge2(vector<int>&A, vector<int>&tempA, int L, int R, int rightEnd){int leftEnd = R - 1;int numElements = rightEnd - L + 1;int temp = L;//临时数组存放的初始位置while (L <= leftEnd&&R <= rightEnd){if (A[L] <= A[R])tempA[temp++] = A[L++];elsetempA[temp++] = A[R++];}while (R <= rightEnd)//直接复制右边剩下的tempA[temp++] = A[R++];while (L <= leftEnd)tempA[temp++] = A[L++];//直接复制左边剩下的}void merge_pass(vector<int>&A, vector<int>&tempA, int N, int Length){int i;for (i = 0; i <= N - 2 * Length; i += 2 * Length)// 两两归并merge2(A, tempA, i, i + Length, i + 2 * Length - 1);if (i + Length < N)              //归并最后两个子序列merge2(A, tempA, i, i + Length, N - 1);elsefor (int j = i; j < N; j++)  //归并剩下的单个子序列tempA[j] = A[j];}//空间复杂度: O(N)void mergeSort2(vector<int>& A){int N = A.size();vector<int> tempA;tempA.resize(N);int Length = 1;if (tempA.size() != 0){while (Length<N){merge_pass(A, tempA, N, Length);Length *= 2;merge_pass(tempA, A, N, Length);Length *= 2;}}else{return;}}/*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*///快速排序              对冒泡算法的改进,找一个关键数据,将其划分为两部分,一边总比关键数据大,一边总比关键数据小,递归循环,直到等于一个数据//不稳定排序//时间复杂度:int partition(vector<int>& a,int left,int right){int i = left;int j = right;int key = a[left];//如何选取主元/*控制在当组内寻找一遍*/while (i < j){/*而寻找结束的条件就是,1,找到一个小于或者大于key的数(大于或小于取决于你想升序还是降序)2,没有符合条件1的,并且i与j的大小没有反转*/while (i < j && key <= a[j]){j--;/*向前寻找*/}/*找到一个这样的数后就把它赋给前面的被拿走的i的值(如果第一次循环且key是a[left],那么就是给key)*/a[i] = a[j];/*这是i在当组内向前寻找,同上,不过注意与key的大小关系停止循环和上面相反,因为排序思想是把数往两边扔,所以左右两边的数大小与key的关系相反*/while (i < j && key >= a[i]){i++;}a[j] = a[i];}a[i] = key;/*当在当组内找完一遍以后就把中间数key回归*/return i;}void median3(vector<int>& A, int left, int right){int m = (left + right) / 2;if (A[left]>A[right])swap(A, left, right);if (A[m] > A[right])swap(A, m, right);if (A[m] > A[left])swap(A, m, left);}int partition2(vector<int>& a, int left, int right){median3(a,left,right);int key = a[left];/*控制在当组内寻找一遍*/int i = left, j = right;while (i < j){/*而寻找结束的条件就是,1,找到一个小于或者大于key的数(大于或小于取决于你想升序还是降序)2,没有符合条件1的,并且i与j的大小没有反转*/while (i < j && key <= a[j]){j--;/*向前寻找*/}/*找到一个这样的数后就把它赋给前面的被拿走的i的值(如果第一次循环且key是a[left],那么就是给key)*/a[i] = a[j];/*这是i在当组内向前寻找,同上,不过注意与key的大小关系停止循环和上面相反,因为排序思想是把数往两边扔,所以左右两边的数大小与key的关系相反*/while (i < j && key >= a[i]){i++;}a[j] = a[i];}a[i] = key;/*当在当组内找完一遍以后就把中间数key回归*/return i;}void qSort(vector<int>& a, int left, int right){/*如果左边索引大于或者等于右边的索引就代表已经整理完成一个组了*/int pivot;int cutoff=100;if ( 1<=right-left){pivot = partition2(a,left,right);qSort(a, left, pivot - 1);  /*最后用同样的方式对分出来的左边的小组进行同上的做法*/qSort(a, pivot + 1, right); /*用同样的方式对分出来的右边的小组进行同上的做法*/                            /*当然最后可能会出现很多分左右,直到每一组的i = j 为止*/}else{insertSort(a);}}void quickSort(vector<int>& A){qSort(A, 0, A.size() - 1);}int main(){vector<int> A = {4,6,3,2,1,0,9};cout << endl;//bubleSort(A);//selectSort(A);//insertSort(A);//shellSort(A);//heapSort(A);//mergeSort(A);//mergeSort2(A);quickSort(A);for (int a : A)cout << a<<" ";return 0;}

必须做到手写!

原创粉丝点击