排序模板

https://www.zhihu.com/question/51337272/answer/572455307

https://mp.weixin.qq.com/s/b1ICJaB5RjUjH_h_cB1qig

https://zhuanlan.zhihu.com/p/68672733

https://zhuanlan.zhihu.com/p/57088609

借用知乎大佬的图片:https://www.zhihu.com/question/51337272/answer/572455307

1.冒泡排序:注意最好情况

注意写法i从size-1开始写比较容易点:

void BubbleSort(vector<int>& arr) {
	int size = arr.size();
	for (int i = size-1; i >=0; i--) {
		for (int j = 0; j < i; j++) {
			if (arr[j] > arr[j+1]) {
				int tmp = arr[j];
				arr[j] = arr[j+1];
				arr[j + 1] = tmp;
			}
		}
	}
}

不过上面那种写法的话,即使遇到最好的情况仍然是O(n2);需要有一个标志位,标志有没有做过交换

https://blog.csdn.net/cloudeagle_bupt/article/details/85215357

public 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;
    }    
}

 

2.选择排序:注意不是稳定得

不是稳定的,例如1 5 6 5 4 ,有一次选择的时候把4和第一个5进行交换了 

void SelectSort(vector<int>& arr) {
	//每次选出一个最小的,然后放在最前面
	int size = arr.size();
	for (int i = 0; i < size ; i++) {
		int index = i;
		for (int j = i+1; j < size ; j++) {
			if (arr[index] > arr[j]) {
				index = j;
			}
		}
		swap(arr[i], arr[index]);
	}
}

3.插入排序:注意代码得实现

void InsertSort(vector<int>& arr) {
	int size = arr.size();
	for (int i = 1; i < size; i++) {
		for (int j = i - 1; j >= 0&& arr[j] > arr[j+1]; j--) {
			swap(arr[j], arr[j + 1]);
		}
	}
}

 

public class InsertSort {
    public static int[] insertSort(int[] arr) {
        if(arr == null || arr.length < 2)
            return arr;

        int n = arr.length;
        for (int i = 1; i < n; i++) {
            int temp = arr[i];
            int k = i - 1;
            while(k >= 0 && arr[k] > temp)
                k--;
            //腾出位置插进去,要插的位置是 k + 1;
            for(int j = i ; j > k + 1; j--)
                arr[j] = arr[j-1];
            //插进去
            arr[k+1] = temp;
        }
        return arr;
    }
}

 

4.希尔排序:缩小增量排序

希尔排序的插入过程几乎于插入排序的过程,只是在外层多加了一个控制增量(gap)的循环罢了。

https://mp.weixin.qq.com/s/4kJdzLB7qO1sES2FEW0Low

public class ShellSort {
    public static int[] shellSort(int arr[]) {
        if (arr == null || arr.length < 2) return arr;
        int n = arr.length;
        // 对每组间隔为 h的分组进行排序,刚开始 h = n / 2;
        for (int h = n / 2; h > 0; h /= 2) {
            //对各个局部分组进行插入排序
            for (int i = h; i < n; i++) {
                // 将arr[i] 插入到所在分组的正确位置上
                insertI(arr, h, i);
            }
     }
     return arr;
    }

    /**
     * 将arr[i]插入到所在分组的正确位置上
     * arr[i]] 所在的分组为 ... arr[i-2*h],arr[i-h], arr[i+h] ...
     */
    private static void insertI(int[] arr, int h, int i) {
        int temp = arr[i];
        int k;
        for (k = i - h; k > 0 && temp < arr[k]; k -= h) {
            arr[k + h] = arr[k];
        }
        arr[k + h] = temp;
    }
}

关于InsertI有更好的写法

void insertI(int[] arr, int h, int i) {
		int temp = arr[i];
		int k;
		for(k = i - h; k >= 0 && arr[k] > arr[k+h] ; k -= h) {
			swap(arr[k], arr[k + h]);
		}
	}

5.桶排序:基数排序和计数排序(桶计基)

5.1桶排序(vector<Node*>)

可以发现有点像哈希表的那个结构

vector<Node*> bucket(n,new Node());

5.2计数排序(能够手写,并且有一个优化的版本的)

public class Counting {
    public static int[] countSort(int[] arr) {
        if(arr == null || arr.length < 2) return arr;

        int n = arr.length;
        int max = arr[0];
        // 寻找数组的最大值
        for (int i = 1; i < n; i++) {
            if(max < arr[i])
                max = arr[i];
        }
        //创建大小为max的临时数组
        int[] temp = new int[max + 1];
        //统计元素i出现的次数
        for (int i = 0; i < n; i++) {
            temp[arr[i]]++;
        }
        int k = 0;
        //把临时数组统计好的数据汇总到原数组
        for (int i = 0; i <= max; i++) {
            for (int j = temp[i]; j > 0; j--) {
                arr[k++] = i;
            }
        }
        return arr;
    }
}

5.3基数排序(vector<list<int>>)也可以申请九个队列

public class RadioSort {

    public static int[] radioSort(int[] arr) {
        if(arr == null || arr.length < 2) return arr;

        int n = arr.length;
        int max = arr[0];
        // 找出最大值
        for (int i = 1; i < n; i++) {
            if(max < arr[i]) max = arr[i];
        }
        // 计算最大值是几位数
        int num = 1;
        while (max / 10 > 0) {
            num++;
            max = max / 10;
        }
        // 创建10个桶
        ArrayList<LinkedList<Integer>> bucketList = new ArrayList<>(10);
        //初始化桶
        for (int i = 0; i < 10; i++) {
            bucketList.add(new LinkedList<Integer>());
        }
        // 进行每一趟的排序,从个位数开始排
        for (int i = 1; i <= num; i++) {
            for (int j = 0; j < n; j++) {
                // 获取每个数最后第 i 位是数组
                int radio = (arr[j] / (int)Math.pow(10,i-1)) % 10;
                //放进对应的桶里
                bucketList.get(radio).add(arr[j]);
            }
            //合并放回原数组
            int k = 0;
            for (int j = 0; j < 10; j++) {
                for (Integer t : bucketList.get(j)) {
                    arr[k++] = t;
                }
                //取出来合并了之后把桶清光数据
                bucketList.get(j).clear();
            }
        }
        return arr;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值