首页 > 编程知识 正文

常见的7种排序算法(java的排序算法)

时间:2023-05-06 18:07:26 阅读:73793 作者:158

轮询算法

轮询算法是指用一种算法计算提供的一系列列表,并按照一定的规则检索列表中的元素。 常见的有序列模式、随机模式、加权模式、加权平滑模式。

定义轮询算法的接口:

/** *轮询算法接口*/publicinterfacebalancet { tchooseone (列表); } 1、publicclassrandombalancetimplementsbalancet { privaterandomrandom=new random (; @ overridepublictchooseone (list tlist ) ) {int sum=list.size; returnlist.get(random.nextint ) sum ); }/** *测试* */publicstaticvoidmain (string [ ] args ) listserviceservices=new ArrayList ); for(intI=0; i 5; I ) {服务e=new service (; e.setip (地址: ) I; e .设置权重(1; 服务. add (e; } randombalanceservicebl=newrandombalance (; for(intI=0; I服务. size (; I ) system.out.println (bl.choose one )服务); } 2、顺序轮询模式publicclassqueuebalancetimplementsbalancet { privatevolatileintindex=0; publicsynchronizedtchooseone (列表) if ) list==null||list.size )==0) return null; int sum=list.size (; int temp=索引% sum; t=list.get(temp ); 索引; 返回t; }/** *测试* */publicstaticvoidmain (string [ ] args ) listserviceservices=new ArrayList ); for(intI=0; i 20; I ) {服务e=new service (; e.setip (地址: ) I; e .设置权重(1; 服务. add (e; } queuebalanceservicebl=newqueuebalance (; for(intI=0; I服务. size (; I ) system.out.println (bl.choose one )服务); } 3、加权模式publicclassweightbalanceimplementsbalanceservice { privatevolatilestaticintindex; @ overridepublicsynchronizedservicechooseone (listservicelist ) {int sum=list.stream ).maptoint } service 3360360 ger vicelice int cur=(索引) % sum; for (服务3360列表) {temp=temp service.getWeight; if(curtemp ) {return service; } }返回空值; } publicstaticvoidmain (字符串[ ] args ) listserviceservices=new ArrayList ); 服务服务器1=new service (; server1. setip (地址1 ); 服务器1.set weight (1; 服务服务器2=new service (; server2. setip (地址2 ); 服务器2.set weight (3; 服务服务器3=new service (; server3. setip (地址3 ); 服务器3.set weight (5; 服务. add (server 1; 服务. add (server 2; 服务. add (server 3; weightbalanceloadbalance=newweightbalance

();for (int i = 0; i < 20; i++) {System.out.println("第"+i+"次请求服务ip为:"+loadBalance.chooseOne(services).getIp());}}}

加权模式存在的问题就是,轮询是以权重值累加第一个小于当前index取模值,最后的结果就是Aserivde N次,Bservice N次,Cservice N次,我们要实现的效果的在总次数内,每个service调用的次数是自身权重在总权重的比例*总调用次数,并且这些调用次数是平滑分布的。这个效果就要看下面的SmoothWeightBalance

4、平滑加权模式 /** * 权重模式均匀轮询 * * 通俗语概述---摘抄网络 * 平滑加权轮询那个算法可以这样想:(total是不变的,因为每次有一个节点减掉total后,每个节点都会加一次 * 自身权重,所以总共又增加了一个total)每次选出节点后,都是减掉这个节点权重一个total;自身权重越大的节 * 点增长越快,那么比其他节点大的几率就越高,被选中的机会就越多;而自身权重比较低的,自身current_weight * 增长比较慢,所以比其他大的几率小,被选中的机会就少。(挨的刀子是一样大的,但是哪棵韭菜长得快,哪棵就 * 更容易挨刀子;东北大米年收1次,海南能收3次) */public class SmoothWeightBalance implements Balance<Service> { /** * 存储当前weight */ private Map<String, Integer> map = new HashMap<>();/** * 加权平滑轮询 * 实现原理:将请求为key,权重值初始为value,每一轮取最大的weight,然后将最大的weight-总数,再将每个递增自身weight。 * 解析: 每一轮所有server的当前weight递增总数等于最大weight的server减少的总数,从而保证持续取值时减少不会将权重越减 * 越少。而权重值越大,那么增长时抢占最大权重值的机会越大,这个几率值和初始weight成正比。就好比草长的越快,那么被割的机会越大。 */public Service chooseOne(List<Service> services) {// 给予每个service的在map中的权重值为自身初始weight services.forEach(service -> map.computeIfAbsent(service.toString(), key -> service.getWeight()) );int sum = services.stream().mapToInt(Service::getWeight).sum(); // 权重总数// 找当前weight值最大的serverService maxService = null;for (Service service : services) {Integer currentWeight = map.get(service.toString());if (maxService == null || currentWeight > map.get(maxService.toString())) {maxService = service; // 找当前weight最大的server}}// 将最大的 - total总数 (备注:默认weight获取:server.getWeight , 当前weight获取 : map.get(server.toString))map.put(maxService.toString(), map.get(maxService.toString()) - sum);// 递增所有server的weight值 (总递增数等于total)for (Service service : services) {Integer oldweight = map.get(service.toString());map.put(service.toString(), oldweight + service.getWeight());}return maxService;}/** * 测试 */public static void main(String[] args) {List<Service> services = new ArrayList<>();Service server1 = new Service();server1.setIp("address1");server1.setWeight(1);Service server2 = new Service();server2.setIp("address2");server2.setWeight(3);Service server3 = new Service();server3.setIp("address3");server3.setWeight(5);services.add(server1);services.add(server2);services.add(server3);SmoothWeightBalance loadBalance = new SmoothWeightBalance();for (int i = 0; i < 20; i++) {System.out.println("第" + i + "次请求服务ip为:" + loadBalance.chooseOne(services).getIp());}}}

 

end!

 

 

 

 

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。