冒泡排序算法的运作如下:
1、比较相邻的元素。如果第一个比第二个大,就交换他们两个。
2、对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
3、针对所有的元素重复以上的步骤,除了最后一个。
4、持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
void BubbleSort(int arr[], int n) { int i = 0, j =0; for(i = 0; i < n; i++) for(j = 0; j < n - 1 - i; j++) { if(arr[j] > arr[j + 1]) { arr[j] = arr[j] ^ arr[j+1]; arr[j+1] = arr[j] ^ arr[j+1]; arr[j] = arr[j] ^ arr[j+1]; } } }
/** * 鸡尾酒排序法 * *正常冒泡排序法,每次遍历都是向一个方向冒出最值, *而鸡尾酒排序法是变异的冒泡排序法,往返方向找出最值 */ public void sort(int[] a) { //需要来回a,length/2趟 for (int i = 0; i < a.length / 2; i++) { //类冒泡,交换最大值至右端 for (int j = i; 1 + j < a.length - i; j++) if (a[j] > a[1 + j]) Arr.swap(a, j, 1 + j); //类冒泡,交换最小值至左端 for (int j = a.length - i - 1; j > i; j--) if (a[j - 1] > a[j]) Arr.swap(a, j - 1, j); } }
/** *改进的冒泡算法,在第i次遍历时,若没有交换数据,说明剩余的数据已经是有序的 */ void BubbleSort(int arr[]) { boolean didSwap; for(int i = 0, len = arr.length; i < len - 1; i++) { didSwap = false; for(int j = 0; j < len - i - 1; j++) { if(arr[j + 1] < arr[j]) { swap(arr, j, j + 1); didSwap = true; } } if(didSwap == false) return; } }
选择排序的工作原理:
首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
/** * @brief 选择排序 * * @param list[] 要排序的数组 * @param n 数组中的元素数量 */ void SelectSort(int *list, int list_size) { int i, j; // 用于循环 int min_index; // 当前最小值的 index int temp; // 用于交换 // 最后一个元素不用排了, 所以可以 len - 1; 少一次循环 for (i = 0; i < list_size - 1; ++i) { // 假定当前的元素就是最小的 min_index = i; // 查找剩下的元素当中最小的 for (j = i; j < list_size; ++j) { if (list[j] < list[min_index]) { min_index = j; } } // 如果找到了比当前小的, 就把当前元素与之交换 if (min_index != i) { temp = list[i]; list[i] = list[min_index]; list[min_index] = temp; } } }
归并操作的过程如下:
1、申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
2、设定两个指针,最初位置分别为两个已经排序序列的起始位置
3、比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
4、重复步骤3直到某一指针到达序列尾
5、将另一序列剩下的所有元素直接复制到合并序列尾
/** * @brief 归并排序 * * @param *list 要排序的数组 * @param n 数组中的元素数量 */ void MergeSort(int *list, int list_size) { if (list_size > 1) { // 把数组平均分成两个部分 int *list1 = list; int list1_size = list_size / 2; int *list2 = list + list_size / 2; int list2_size = list_size - list1_size; // 分别归并排序 merge_sort(list1, list1_size); merge_sort(list2, list2_size); // 归并 merge_array(list1, list1_size, list2, list2_size); } } /** * @brief 归并两个有序数组 * * @param list1 * @param list1_size * @param list2 * @param list2_size */ void merge_array(int *list1, int list1_size, int *list2, int list2_size) { int i, j, k; i = j = k = 0; // 声明临时数组用于存储归并结果 int *list = malloc((list1_size + list2_size)*sizeof(int)); // note: 只要有一个数组到达了尾部就要跳出 // 也就是说只有两个都没有到达尾部的时候才执行这个循环 while (i < list1_size && j < list2_size) { // 把较小的那个数据放到结果数组里, 同时移动指针 list[k++] = list1[i] < list2[j] ? list1[i++] : list2[j++]; } // 如果 list1 还有元素,把剩下的数据直接放到结果数组 while (i < list1_size) { list[k++] = list1[i++]; } // 如果 list2 还有元素,把剩下的数据直接放到结果数组 while (j < list2_size) { list[k++] = list2[j++]; } // 把结果数组 copy 到 list1 里 for (int ii = 0; ii < (list1_size + list2_size); ++ii) { list1[ii] = list[ii]; } free(list); }
快速排序的步骤
1.先从数列中取出一个数作为基准数。
2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
3.再对左右区间重复第二步,直到各区间只有一个数。
/** * @brief 快速排序 * * @param list 要排序的数组 * @param lIndex 左下标 * @param rIndex 右下标 */ void QuickSort(int list[], int lIndex, int rIndex) { if (lIndex < rIndex) { int i = lIndex, j = rIndex, x = list[lIndex];//第一个元素作为基准数 while (i < j) { while(i < j && list[j] >= x) // 从右向左找第一个小于x的数 j--; if(i < j) list[i++] = list[j]; while(i < j && list[i] < x) // 从左向右找第一个大于等于x的数 i++; if(i < j) list[j--] = list[i]; } list[i] = x; QuickSort(list, lIndex, i - 1); // 递归调用 QuickSort(list, i + 1, rIndex); } }