zoukankan      html  css  js  c++  java
  • 快速排序和计数排序API

      听说有十大排序算法,先学习一下快速排序和计数排序算法。

    一:快速排序

     快速排序主要就是每一个找到当前取出来的标尺的数的位置,然后把小于它的数放在左边(从小到大排),把大于它的数放在右边。然后利用递归分左右继续找位置放数字,这个过程有点类似之前的根据前序和中序找后序的题目。递归的出口就是当只有一个数的时候就不需要排了。取出来的位置就是他的位置。

    代码:

    找每一次的位置:

    int findpos(int l,int r){
    	int temp = data[l];
    	int i = l, j = r;
    	while (i != j){
    		while (data[j] >= temp&&i < j)j--;//注意别忘记写j--;
    		data[i] = data[j];
    		while (data[i] <= temp&&i < j)i++;//注意别忘记写i++;
    		data[j] = data[i];
    	}
    	data[i] = temp;
    	return i;
    
    }
    

     递归分区域找位置:

    void quicksort(int l,int r){
    	if (l >= r) return;
    	int pos = findpos(l, r);
    	
    	quicksort(l,pos-1);
    	quicksort(pos+1,r);
    
    }
    

     需要注意的有很多:

    1.递归的出口要放在quicksort的最上面,不放在上面的话如果只有一个数还去找他的位置的话可能会陷入死循环。

    2.while(i!=j)中的这个对称的while语句的写法可以注意背一下。

    while (data[j] >= temp&&i < j)j--;
    		data[i] = data[j];
    		while (data[i] <= temp&&i < j)i++;
    		data[j] = data[i];
    

     二:计数排序

      计数排序不用经过比较,在读一遍的过程中用一个数组记录当前数组出现的次数,(其实就是把排序的过程用count数组的下标来实现了)。要注意的是每一次循环变量的取值: 

    第一次循环的时候是对于count清零,这时候循环变量应该等于count的下标个数,也就是要排序的数组的范围;(数组元素的下标要大于需要排序的数的范围)

    第二次循环的时候是统计的时候,循环变量和要排序的数组的元素的个数相同;

    第三次循环的时候是对于count数组的操作,累加得出当前元素应该放在排序好的数组中的位置。也就是有多少个数小于他,循环变量应该和count的长度相符合;

    第四次循环是对于排序结果的赋值,循环变量和要排序的数组的个数相同即可。

      代码:

    int count[1001];
    int Ans[10];
    void countsort(){
    	for (int i = 0; i < 1000; i++){
    		count[i] = 0;
    	}
    	for (int i = 0; i < 10; i++){
    		count[data[i]]++;
    	}
    	for (int i = 1; i < 1000; i++){
    		count[i] = count[i] + count[i - 1];
    	}
    	for (int i = 0; i < 10; i++){
    		Ans[--count[data[i]]] = data[i];//注意这句话的写法,经常写错
    	}
    }
    

     完整测试代码:

    #include <stdio.h>
    int data[10] = { 2, 3, 1, 5, 7, 6, 4, 8, 2, 0 };
    int findpos(int l,int r){
    	int temp = data[l];
    	int i = l, j = r;
    	while (i != j){
    		while (data[j] >= temp&&i < j)j--;
    		data[i] = data[j];
    		while (data[i] <= temp&&i < j)i++;
    		data[j] = data[i];
    	}
    	data[i] = temp;
    	return i;
    
    }
    void quicksort(int l,int r){
    	if (l >= r) return;
    	int pos = findpos(l, r);
    	
    	quicksort(l,pos-1);
    	quicksort(pos+1,r);
    
    }
    
    int count[1001];
    int Ans[10];
    void countsort(){
    	for (int i = 0; i < 1000; i++){
    		count[i] = 0;
    	}
    	for (int i = 0; i < 10; i++){
    		count[data[i]]++;
    	}
    	for (int i = 1; i < 1000; i++){
    		count[i] = count[i] + count[i - 1];
    	}
    	for (int i = 0; i < 10; i++){
    		Ans[--count[data[i]]] = data[i];
    	}
    }
    
    
    int main(){
    	countsort();
    
    	return 0;
    }
    
    大多数想法要么平庸,要么更糟糕,这很大程度上因为绝妙的想法难得一见,而且他们还要在我们身边这个充斥了各种恶俗的所谓常识的环境中孕育生长。
  • 相关阅读:
    剑指OFFER 滑动窗口的最大值
    剑指OFFER 正则表达式匹配
    linux动态链接库的使用
    剑指OFFER 序列化二叉树
    剑指OFFER 数字在排序数组中出现的次数
    剑指OFFER 数组中的逆序对
    剑指OFFER 反转链表
    剑指OFFER 二叉树的深度
    剑指OFFER 矩形覆盖
    网络相关的命令工具-iptables
  • 原文地址:https://www.cnblogs.com/linux0537/p/7615363.html
Copyright © 2011-2022 走看看