09-散列3. Hashing - Hard Version (30)

题目:http://www.patest.cn/contests/mooc-ds/09-%E6%95%A3%E5%88%973

题目的意思给你一个通过线性探测法生成Hash表,求出它的输入顺序并且要最小序列,散列函数x% N。

先看下图

09-3. <wbr>Hashing <wbr>- <wbr>Hard <wbr>Version <wbr>(30)

   从表中可以得出,冲突=下标 - Key % N, 但32的下标小于Key%N, 为了使计算一致,补上N使它也符合一般情况,所以冲突计算的公式为:
冲突 = (下标 - Key % N + N) % N 

  冲突是因为散列函数求出来的位置被占了,移到下个位置的时候,如果被占,又冲突。换个角度说,冲突是被其他数影响的,被2个数影响冲突就是2,被3个数影响,冲突就是3,依次类推。画成图后(本来线用了不同的颜色,QQ截图被压缩了),冲突可以看成边,那么要还原成最小输入序列就变成了拓扑排序。

解:

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.LinkedList;
import java.util.Map.Entry;
import java.util.PriorityQueue;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;



/**
 * @author chenhong
 * */

class Node implements Comparable<Node>
{
	int value; 
	int index;
	ArrayList<Node> from =null;//入度
	ArrayList<Node> to = null ;//出度
	public Node(int value,int index)
	{
		this.value=value;
		this.index=index;
		from = new ArrayList<Node>();
		to = new ArrayList<Node>();
	}
	
	@Override
	public int compareTo(Node o) {
		// TODO Auto-generated method stub
		return this.value-o.value;
	}
	
		
}

public class Main {

	
	
	public static void main(String[] args) {
		
		Scanner scanner = new Scanner(System.in);
		int N = scanner.nextInt();
		ArrayList<Node> input = new ArrayList<Node>(); //输入序列
		for(int i=0;i<N;i++)
		{
			int value= scanner.nextInt();
			Node node = new Node(value,i);
			input.add(node);
			
		}
		//初始化入度和出度
		for(int i=0;i<N;i++)
		{
			Node node = input.get(i);
			int value = node.value;
			if(value<0) continue;
			int key_N = value%N; // key%N
			int to = (i-key_N+N)%N ;//冲突 = (下标 - Key % N + N) % N 
			for(int j=0; j<to ;j++)
			{
				int index = (key_N+j)%N;
				
				Node n = input.get(index);
				n.to.add(node);
				node.from.add(n);
			}
		}
		
		PriorityQueue<Node> output = new PriorityQueue<Node>();
		//找到入度为0的点
		for(int i=0;i<N;i++)
		{
			Node node = input.get(i);
			if(node.from.size()==0)
				output.add(node);
		}
		StringBuilder sb = new StringBuilder();
		while(!output.isEmpty())
		{
			Node n = output.poll();
			if(n.value<0) continue;
			sb.append(n.value+" ");
			int index = n.index;
			ArrayList<Node> to = n.to;
			ArrayList<Node> from = n.from;
			//修改入度
			for(Node i: to)
			{
				
				i.from.remove(n);
				if(i.from.size()==0)
					output.add(i);
			}
			
		}
		if(sb.length()>0)
			System.out.println(sb.substring(0, sb.length()-1));
		

	}

	
	
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值