冒泡排序
冒泡排序算法的运作如下:
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];} }
}
交换两个数据,可以用用临时变量,也可用以下的两个方法
a = a^b;
b = a^b;
a = a^b;
或者
a = a + b;
b = a - b;
a = a - b;
冒泡排序变异版-鸡尾酒排序法
/*** 鸡尾酒排序法* *正常冒泡排序法,每次遍历都是向一个方向冒出最值,*而鸡尾酒排序法是变异的冒泡排序法,往返方向找出最值*/
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; // 当前最小值的 indexint 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);}
}