赞
踩
最好是n,最坏是 n的平方,在内存里排。是稳定的。
- void Bubble_Sort(int[] arr) //参数为数组和长度
- {
- int n=arr.length;
- for (int i = 0; i < n ; i++) {
- for (int j = 0; j < n - i - 1; j++) { //n-i-1是比较次数,每比较一趟就少一次
- if (arr[j] > arr[j + 1]) { //交换arr[j]与arr[j+1]的值
- int temp = arr[j];
- arr[j] = arr[j + 1];
- arr[j + 1] = temp;
- }
- }
- }
- }
- public void insertSort(int [] nums)
- {
- if(nums.length==0 && nums.length==1)
- {
- return ;
- }
-
- //注意,遍历的最大位置是 长度减2
- for(int i=0;i<nums.length-1;i++)
- {
- //这个border,表示已排数组的右界。
- int border=i;
- int current =nums[i+1];
-
- //从右往左遍历已排数组,如果比current大,就让当前遍历的这个元素后移一位。
- while(border>=0 && current<nums[border])
- {
- //右移一位
- nums[border+1]=nums[border];
- border--;
- }
- //停的时候,说明已经找到 那个小于等于 current的元素的位置了。
- nums[border+1]=current;
-
- }
-
- }
最佳情况:T(n) = O(n)
最坏情况:T(n) = O(n2)
平均情况:T(n) = O(n2)
不稳定: 需要多次插入排序,值相同的元素可能在各自的插入排序中移动,最后其 稳定 性就会被打乱
算法停止的标识是 gap=0。其实就是每次移动gap个单位的,直接插入排序。
- public void HillSort(int [] nums)
- {
- int gap =(nums.length)/2;
- //希尔排序的循环条件是gap>0
- while(gap>0)
- {
- //不同于直接插入排序,这里最大索引到nums.length-1
- for(int i=gap;i<nums.length;i++)
- {
- //i-gap,就是直接插入排序的右界。
- int border=i-gap;
-
- //
- int current=nums[i];
- //这个while,就是一个一次移动gap位置的直接插入排序。
- while(border>=0 && nums[border] >current )
- {
- //往后移动gap个位置
- nums[border+gap]=nums[border];
-
- border-=gap;
- }
- //出来了,说明碰到小于等于current的了。
- nums[border+gap]=current;
-
- }
- gap=gap/2;
- }
- }
最佳情况:T(n) = O(nlog2 n)
最坏情况:T(n) = O(nlog2 n)
平均情况:T(n) =O(nlog2n) 稳定
递归的把一个数组拆分为两个数组,直接数组长度只剩1(也就是分成两个元素)。
就是不断地递归 有序地合并 拆分的两个子数组。
合并的方法就是,有序合并 两个数组,且让新数组有序。
那为什么要递归到最深,也就是两个数组只有一个元素的时候呢?
因为这样复杂度低。如果只整一层归并呢?那样复杂度就是n的平方 即(n/2)(n/2)。
- public int[] mergeSort(int[] arr)
- {
- //当数组大小为1的时候,直接return,让递归的上一层排序即可。
- if (arr.length == 1) return arr;
- //copyOfRange,左闭右开
- int mid= (arr.length)/2;
- int [] leftArr=Arrays.copyOfRange(arr,0,mid);
- int [] rightArr=Arrays.copyOfRange(arr,mid,arr.length);
-
- //mergeSort 必须要有返回值,因为上一层要用
- return merge(mergeSort(leftArr),mergeSort(rightArr));
-
- }
-
- // 就是把两个有序数组, 合并成一个有序数组。
- public int[] merge(int[] left, int[] right) {
- int[] result = new int[left.length + right.length];
- for (int index = 0, i = 0, j = 0; index < result.length; index++) {
-
- //i 是用来遍历left 数组的,i都大于等于left.length了,则说明 left数组的元素都加完了
- if (i >= left.length)
- result[index] = right[j++];
- else if (j >= right.length)
- result[index] = left[i++];
- else if (left[i] > right[j])
- result[index] = right[j++];
- else
- result[index] = left[i++];
- }
-
- return result;
- }
最佳情况:T(n) = O(n) 最差情况:T(n) = O(n2) 平均情况:T(n) = O(n2)
不稳定
就是每一轮都把最小的值放在最前面。
比如第一轮 确定 1为最小的,放在最前面。 下一轮就不用 考虑第一个位置。
第一次排序结果:{1,3,7,2,6,9,5,8}
第二轮就 ,确认2是 第二轮最小的。下一轮就不用 考虑前两个位置。
第二轮排序结果为:{1,2,7,3,6,9,5,8}。
- public static int[] selectionSort(int[] array) {
- if (array.length == 0)
- return array;
- for (int i = 0; i < array.length; i++) {
-
-
- //每个i就是一轮。
- int minIndex = i;//最小索引初始化为。
- for (int j = i; j < array.length; j++) {
- if (array[j] < array[minIndex]) //找到最小的数
- minIndex = j; //将最小数的索引保存
- }
- //然后 位置i 和最小的索引 minIndex 的值交换。
- //i 位置就成了这一轮最小的。
- int temp = array[minIndex];
- array[minIndex] = array[i];
- array[i] = temp;
- }
- return array;
- }
时间复杂度:
空间复杂度(因为每次都要记录基准值):O(logn)
但是排序不稳定。
给定一个序列 6 1 2 7 9 3 4 5 10 8
在初始状态下,数字6在序列的第1位。我们的目标是将6挪到序列中间的某个位置,假设这个位置是k。现在就需要寻找这个k,并且以第k位为分界点,左边的数都小于等于6,右边的数都大于等于6。想一想,你有办法可以做到这点吗?
变成如下这样 6 1 2 7 9 3 4 5 10 8。
做法:
- void quickSort(int[] arr,int left,int right)
- {
- if (right >= left) {
- //保存基数
- int basic = arr[left];
- //定义左右指针
- int i = left;
- int j = right;
- while (i < j) { //左指针小于右指针
- while (i < j && arr[j] > basic) {//操作右指针找到小于基数的下标
- j--;
- }
- //出了这个while,立马就得判断
- if (i < j) {
- arr[i] = arr[j];
- i++;
- }
- while (i < j && arr[i] < basic) {//相反,找到大于基数的下标
- i++;
- }
- if (i < j) {
- arr[j] = arr[i]; //大于基数的值赋给右指针所指的位置
- j--; //右指针左移
- }
- }
- arr[i] = basic; //将基数放入到指针重合处
- quickSort(arr, left, i - 1); //递归调用,对左半部分数组进行排序
- quickSort(arr, i + 1, right); //对右半部分数组进行排序
- }
-
- }
堆 是一个完全二叉树。
大根堆:每个节点的值都大于或者等于他的左右孩子节点的值。
跟二叉排序树不同之处是, 孩子节点只需要 小于父亲节点即可。
它满足完全二叉树的一些规则,最后一个非叶子节点是 arrLengrh/2-1
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。