1. 冒泡排序
两两比较相邻元素,逆序则交换,外层循环意思是总共要经过n-1轮冒泡,第i轮过后,第n-i个元素总是前n-i个数中的最大,所以按如下代码进行内外循环。
1 int* bubbleSort(int* A, int n) { 2 // write code here 3 for(int i=n-1;i>=0;i--) 4 for(int j=0;j<i;j++) 5 { 6 if(A[j+1]<A[j]) 7 { 8 int temp=A[j]; 9 A[j]=A[j+1]; 10 A[j+1]=temp; 11 } 12 } 13 return A; 14 }
1. 选择排序
从i=0开始,内循环先找出第i+1到n-1中最小的数的下标,然后跟a[i]交换,保证每一次大循环后,a[i]都是[i,n-1]中的最小,因此最后一次循环为[i,n-1]只有两个元素的时候。代码如下:
1 int* selectionSort(int* A, int n) { 2 // write code here 3 for(int i=0;i<n-1;i++) 4 { 5 int mini=i; 6 for(int j=i+1;j<n;j++) 7 { 8 mini=A[mini]>A[j]?j:mini; 9 } 10 if(mini!=i) 11 { 12 int temp=A[mini]; 13 A[mini]=A[i]; 14 A[i]=temp; 15 } 16 } 17 return A; 18 }
3. 插入排序
插入排序思想是,记[0,i]是有序的,则在[0,i]中倒着查找插入第i+1个元素。
1 int* insertionSort(int* A, int n) { 2 // write code here 3 for(int i=1;i<n;i++) 4 { 5 int temp=A[i]; 6 int j=i-1; 7 while(j>=0&&temp<A[j]) 8 { 9 A[j+1]=A[j]; 10 j--; 11 } 12 A[j+1]=temp; 13 } 14 return A; 15 }
4.归并排序
归并排序关键点在于把两个有序数组融合起来的merge函数,通过不断划分子问题,用分治的思想,把一个大的数组分成两部分,每一部分再分成两部分,递归直到分到两个子数组都只有一个元素,自然这个子数组就是有序的,再把这样的两个子数组归并起来,自然得到规模为2的有序子数组,以此类推,最后归并成一个大的数组。
1 class MergeSort { 2 public: 3 int* mergeSort(int* A, int n) { 4 // write code here 5 mergeSort(A,0,n-1); 6 return A; 7 } 8 9 void mergeSort(int* A, int left, int right) 10 { 11 if(left==right) 12 return; 13 int mid=(left+right)/2; 14 mergeSort(A,left,mid); 15 mergeSort(A,mid+1,right); 16 merge(A,left,mid,right); 17 return; 18 } 19 20 void merge(int* A,int left,int mid,int right) 21 { 22 int* temp=new int[right-left+1]; 23 int l=left; 24 int r=mid+1; 25 int k=0; 26 while(l<=mid&&r<=right) 27 { 28 if(A[l]<=A[r]) 29 { 30 temp[k++]=A[l++]; 31 } 32 else 33 temp[k++]=A[r++]; 34 } 35 while(l<=mid) 36 temp[k++]=A[l++]; 37 while(r<=right) 38 temp[k++]=A[r++]; 39 for(int i=0;i<k;i++) 40 A[left+i]=temp[i]; 41 } 42 };
5. 快排
其基本思想是:
1. 分治法: 在 quickSort(A, 0,n-1) 中调用 quickSort(A, left,mid-1) 和 quickSort(A, mid+1,right) ,其中mid为枢纽所在的位置。
2. 在数组中随机选择一个枢纽作为基准,将其放到数组的最右边后,遍历数组,将比其小的数放在其左边,大于其的数放在其右边。
3. mid = partition(A,left,right) 该函数的思想是,用 int pivot = left-1; 指向小于枢纽的数的最后一个元素的位置,然后遍历该数组,最后返回 pivot 表示枢纽所在的位置。
class QuickSort { public: int* quickSort(int* A, int n) { // write code here if(A==nullptr&&n<2) return A; srand((unsigned(time(NULL)))); return quickSort(A, 0,n-1); } int* quickSort(int* A, int left, int right){ if(left<right) { int random = left+rand()%(right-left+1); int temp=A[random]; A[random]=A[right]; A[right]=temp; int mid = partition(A,left,right); quickSort(A, left,mid-1); quickSort(A, mid+1,right); } return A; } int partition(int* A, int left, int right) { int pivot = left-1; int index = left; while(index <= right) { if(A[index] <= A[right]) { ++pivot; int temp = A[index]; A[index] = A[pivot]; A[pivot]= temp; } index++; } return pivot; } };
6. 堆排序
堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序。其思路如下:
a.将无需序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆;
b.将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端;
c.重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序。
参考链接:https://www.cnblogs.com/chengxiao/p/6129630.html
class HeapSort { public: void swap(int* A,int i,int j) { int temp = A[i]; A[i] = A[j]; A[j] = temp; } void adjustHeap(int* A, int n, int left, int right) { int parent = left; int maxChild = 2 * parent + 1; int value = A[parent]; while(maxChild <= right) { maxChild = A[maxChild + 1] > A[maxChild] && maxChild < right ? maxChild + 1: maxChild; if( value < A[maxChild]) { A[parent] = A[maxChild]; parent = maxChild; maxChild = 2 * parent + 1; } else break; } A[parent] = value; } int* heapSort(int* A, int n) { // write code here for(int i = n/2-1; i>=0; i--) adjustHeap(A,n,i,n-1); for(int i = n-1; i >0; i--) { swap(A,i,0); adjustHeap(A,n,0,i-1); } return A; } };
7. 希尔排序
希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。
class ShellSort { public: int* shellSort(int* A, int n) { // write code here if(A==nullptr||n<2) return A; int inc = n/2; int index = 0; while(inc > 0) { for(int i = inc; i < n; i++) { index = i; while(index >= inc) { if(A[index - inc] > A[index]) { int temp = A[index - inc]; A[index - inc] = A[index]; A[index] = temp; index -= inc; } else break; } } inc /= 2; } return A; } };
8. 桶排序
class CountingSort { public: void max_min(int* A, int n, int& max, int& min) { max = min = A[0]; for(int i = 1; i < n; i++) { if(A[i]<min) min = A[i]; else if(A[i]>max) max = A[i]; } } int* countingSort(int* A, int n) { // write code here if(A == nullptr||n < 2) return A; int max, min; max_min(A,n,max,min); int* tong = new int[max - min + 1]; for (int i = 0;i < max - min + 1;i++) //清零 tong[i] = 0; for(int i = 0; i < n; i++) //计数 tong[A[i]-min]++; int index = 0; for(int i = 0; i< max-min+1; i++) while(tong[i] > 0) { A[index++] = i+min; tong[i]--; } return A; } };