参考链接:http://blog.csdn.net/morewindows/article/category/859207
快排-冒泡-直接插入-直接选择-归并-堆排序
[swap]两数交换 不使用中间变量 inline void swap( int &a , int & b) { if (a != b) /需判断 可能会置0 { // a^b = c 对c用a可以解出b 对c用b 可以解出a a = a ^ b; //对c 用旧b解锁得到 a; b = b ^ a; //对c 用b(旧 a)解锁得到b; a = a ^ b; } if(a != b) { //总数 a = a + b; //总数- 旧b = 旧 a b = a - b; //总数- 新b(旧 a) = 旧b a = a - b; } } 【快速排序】【挖坑填坑】 算法思想:找到数组一个值(一般是第一个元素) 根据这个值把数组分成3堆,对这个堆进行递归 21 5 19 1 第一个数为准值 右边找小的 左边找大的 1 5 19 1 把准值扔到左右重叠的位置 1 5 19 21 准值 = 位置 = 3 判断(left<准值) 递归(数组,0,准值-1); 判断(准值>right) 递归(数组,准值+1,right); void q_sort (int numbers[], int left, int right ) { int pivot , l_hold, r_hold; l_hold = left ; r_hold = right ; //选取第一个元素作为阀值 pivot = numbers [left]; //以阀值为界限分组 while (left < right) { //右边找到一个比阀值小的循环结束 while ((numbers [right] >= pivot) && (left < right)) right--; //假如找到把右边小的扔到左边去 if (left != right) { numbers[left ] = numbers[ right]; left++; } //左边找到一个比阀值大的循环结束 while ((numbers [left] <= pivot) && (left < right)) left++; //假如找到把左边大的扔到右边去 if (left != right) { numbers[right ] = numbers[ left]; right--; } } //把阀值放到left=right的地方 numbers[left ] = pivot; //阀值记录为位置 pivot = left ; //左右回到开始位置 left = l_hold ; right = r_hold ; //左边到阀值前一个位置排序 if (left < pivot) q_sort(numbers , left, pivot-1); //阀值后一个位置到右边排序 if (right > pivot) q_sort(numbers , pivot+1, right); } 【冒泡排序】 算法思想: N个数字 1.比较前后2个数字,大的往后面走,最大就是最后一个 2.N=N-1,依此循环,N=0顺序就确定好了 void _bsort (int * arr,int size) { //总共循环次数 for(int i = 0; i < size ;i++) //每次循环完确定一个最大然后缩小样本空间 for(int j = 1; j<size - i; j++) { if (arr [j - 1] > arr[j ]) swap(arr [j - 1], arr[j ]); } } void _bsort_fast (int * arr,int size) { int flag = size; int k = 0; while(flag > 0) { //flag为某个位置后全部有序的标志位 k = flag ; //假如有序了退出循环 flag = 0; for(int i= 1; i<k ; i++) { if(arr [i-1]> arr[i ]) { swap(arr [i-1], arr[i ]); flag = i ; } } } } 【插入排序】 算法思想: 1.数组a[0,n-1],令i=0; 2.a[0]有序,插入a[i],a[0..i]有序 3.i++,直到i=n-1排序完成 //小到大 void _insert_sort (int * arr,int size) { int i ,j, k; for( i = 1;i < size;i ++) { //为arr[i] 找位置 for( j = i-1; j >= 0; j --) { if(arr [i] > arr[j ]) break; } //排除上面的循环没执行情况把下面语句加在 break上面也可以 //找到合适位置j插入 j后面的后移 if(j != i-1) { //保存arr[i] int temp = arr[ i]; //从a[i] 后面一位开始将比 a[i]大的数据向后移 for( k = i-1; k > j ;k--) arr[k +1] = arr[ k]; //将a[i] 放到正确位置上 arr[k + 1] = temp; } } } void insertsort2 (int a[], int n) { int i , j; for (i = 1; i < n; i ++) { //a[i]与前一位相比如果遇到比 a[i]小的有序 //假如前面的比a[i]大进行移位插入 if (a [i] < a[i - 1]) { //记录a[i] int temp = a[ i]; //条件语句是关键包括了搜索和移位 for (j = i - 1; j >= 0 && a [j] > temp; j --) a[j + 1] = a[ j]; //a[i]插入 a[j + 1] = temp; } } } //可以遍历第i个数前面的数 //可以比较第i个数和它前面的数 //eg:if(a[i]>a[j]) for(int i=1; i<n ; i++) for(int j= i-1; j >=0; j--) void Insertsort3 (int a[], int n) { int i , j; for (i = 1; i < n; i ++) for (j = i - 1; j >= 0; j --) { //a[j]与前一位比较比它小就交换直到合适位置 if(a [j] > a[j +1]) swap(a [j], a[j + 1]); } } 【直接选择排序】 算法思想:与直接插入排序类似 1.数组a[0,n-1],令i=0; 2.a[0..i-1]有序,从无序区a[i,n-1]选择一个最小的,放到a[i]位置,使a[0,..i]有序 3.i++,直到i=n-1排序完成 void select_sort (int * arr, int size) { int i , j , mid_pos; for(i =0; i< size; i ++) { mid_pos = i ; //搜索i 位置后面的元素 //得到比a[i] 小的数的位置 for(j =i+1; j<size ; j++) { if(arr [mid_pos] > arr[j ]) { //记下最值得交换的位置 mid_pos = j ; } } //和arr[i] 交换位置a[0..i]有序 swap(arr[mid_pos], arr[i ]); } } 【归并排序】 算法思想: 1.先递归分解数列,分到一个小组只有1个数据,有序 2.再合并对称的2个数组完成归并 void merge_array (int a[],int first, int mid , int last, int temp[]) { int first_a = first, end_a = mid ; int first_b = mid + 1, end_b = last ; int k = 0; //比较两个小数组小的到新数组 while(first_a <= end_a && first_b <= end_b ) { if(a [first_a]> a[first_b ]) temp[k ++] = a[ first_b++]; else temp[k ++] = a[ first_a++]; } //可能有剩余的补上 while(first_a <= end_a) temp[k ++] = a[ first_a++]; //可能有剩余的补上 while(first_b <= end_b) temp[k ++] = a[ first_b++]; //拷贝到a for(int i=0; i<k ; i++) a[first + i] = temp[i ]; } void merge_sort (int a[], int first, int last , int temp[]) { if(first < last) { int mid = (first + last) / 2; //右边有序 merge_sort(a ,first, mid,temp ); //左边有序 merge_sort(a ,mid+1, last,temp ); //合并两边 merge_array(a ,first, mid,last ,temp); } } 【堆排序】 算法思想: 1.建立堆 2.排序 //增加操作是儿子节点找父亲节点调整父亲节点往上走 //删除操作时父亲节点(头节点 )找儿子节点调整儿子节点往下走 void heap_min_add_fix (int * arr,int pos) { //i为新节点位置 int i = pos; //j为父节点位置 int j = (i-1)/2; int temp = arr[ i]; while(j >=0) { //假如父节点小不需要调整 if(arr [j] <= temp) break; //重新调整父节点、子节点位置 //父节点位置继续调整 arr[i ] = arr[ j]; i = j ; j = (i -1)/2; } //新节点位置重新设置 arr[i ] = temp; } void heap_min_add (int * arr,int pos, int data ) { arr[pos ] = data; heap_min_add_fix(arr ,pos); } //堆的删除每次只能删除头结点 void heap_min_delete_fix (int * arr,int pos , int nodesize ) { //father int i = pos; int temp = arr[ i]; //son node int j = 2*i+1; while(nodesize >j) { //左右孩子找到最小的 if(j +1<nodesize && arr[j +1]<arr[ j]) j++; if(temp =< arr[ j]) break; //小的节点往上走 arr[i ] = arr[ j]; i = j ; //新父亲节点 j = 2*i +1 //新儿子节点 } //找到这个父亲节点赋值 arr[i ] = temp; } void heap_min_delete (int * arr,int size) { //最后一个节点与第一个节点交换 //执行向下调整 swap(arr [0],arr[ size-1]); heap_min_delete_fix(arr ,0,size-1); } void heap_create (int* arr, int size) { //拿到最后一个父节点父节点往下修复 for(int i=( size-1)/2;i >=0;i--) heap_min_delete_fix(arr ,i, size-1); } void heap_sort_min (int * arr, int size) { //每次拿a[n-1] 与a[0]交换 //然后执行向下调整,调整 [0 - n-2] //再执行a[n-2] 与a[0]交换 //再往下执行调整,调整到 [0 - n-3] //每次将数据并入后面的有序区,完成后整个数组有序 for(int i= size-1;i >=0; i++) { swap(arr [0],arr[ i]); heap_min_delete_fix(arr ,0,i); }