算法导论(CLRS 2ed) 个人答案 11.2

flyfy1 2021-08-29 原文


算法导论(CLRS 2ed) 个人答案 11.2


题目总体上还是不太难……只是,一个晚上都卡在第四题,做Java实现去了……

up date: 最后Java实现了一个上午,终于把第四题做好了。基本思想和Solution Manual是一样的,只是我允许相同key的情况——因为我认为,即使是带着相同的key,data也有可能不同。

11.2-1:

11.2-2:

11.2-3:

For every
node, it\’s a linked list; therefore, by keeping the list sorted, the running
time would change like this:

Operation

Original

New:
keep sorted list

Insertion

O(1)

O(n/m)

Deletion

O(1+n/m)

O(n/m)

Successful
Search

O(1+n/m)

O(1+n/m)

Unsuccessful
Search

O(1)

O(1)

The
problem is, when searching in a linked list, the traversing of every elements
in this linked is still needed, no matter sorted or not.

11.2-4:

package hashing;

import java.util.LinkedList;
import java.util.Random;

/* Author Songyy
 * Start Time: 	2011年3月8日22:43:34
 * Second Time: 2011年3月9日9:30:00
 * Third Time: 	2011年3月9日11:40:36
 * End Time: 2011年3月9日13:25:03
 * 
 * 
 * Info:
 * 	This is to implement Question 11.2-4 in CLRS, 2nd ed.
 * 
 * Basic Idea:
 * 	1. Basic data structure: 
 * 		a hash table; each node has:
 * 		-- flag: true means it\'s a start of a hash chain
 * 		-- Double link on every chain
 * 			 (the empty node list can be treated as a stack of free space, but still need double link for update)
 *  	next empty node: a node reference:
 *  	-- pointed to the last occupied element whose\'s next is an empty node;
 *  	-- null if the table is full
 *  2. Basic Operation:
 *  	-- Insertion x:
 *  		node = table[hash[x.key]];
 *  		if flag==true:
 *  			find a new empty node;
 *				update link;
 *				copy the data into that new node;
 *  		else:
 *  			if it\'s empty:
 *  				unlink from the stack
 *  				set up new chain
 *  				copy data
 *  			if it\'s not:
 *  				copy old data to a new empty node
 *  				update chain
 *  				set up new chain
 *  				copy new data into this node
 *  	-- Search key:
 *  		node = table[key]
 *  		if flag==false: return false;
 *  		else: compare this key with others in the chain
 *  	-- Deletion x:
 *  		// assumption: x is a node in the table already. i.e., this node must exist in the table
 *  		free the x from the linked chain
 *  		x.flag = false;
 *  		add x to the list of the free space (to the beginning of the empty node list)
 */

class LinkedListHashTableNode {
	LinkedListHashTableNode former, next;
	HashObject data;
	/**
	 * False means it\'s used as a linked list, while true means it\'s used as a
	 * hash table node
	 */
	boolean flag;

	public LinkedListHashTableNode() {
		flag = false;
		former = null;
		next = null;
		data = null;
	}

	public LinkedListHashTableNode(HashObject x) {
		this();
		data = x;
	}

	public void cloneNode(LinkedListHashTableNode toNode) {
		toNode.former = former;
		toNode.next = next;
		toNode.data = data;
		toNode.flag = flag;
	}
}

class HashObject {
	Object data;
	int key;

	public HashObject(int key) {
		this.key = key;
	}
}

public class LinkedListHashTable {
	public static final int MAXSIZE = 100;
	private LinkedListHashTableNode table[] = new LinkedListHashTableNode[MAXSIZE];
	private LinkedListHashTableNode emptyNode;

	public LinkedListHashTable() {
		// first initialize the table
		for (int i = 0; i < MAXSIZE; i++) {
			table[i] = new LinkedListHashTableNode();
		}
		// set up the link for the empty node list
		// the first\'s former and the last\'s next node are null
		for (int i = 1; i < MAXSIZE; i++) {
			table[i].former = table[i - 1];
			table[i - 1].next = table[i];
		}

		// the start of the empty node
		emptyNode = table[0];
	}

	private int hash(int key) {
		return key % MAXSIZE;
	}

	/**
	 * @param x
	 * @return true if insert succeed, false if the table is full
	 */
	public boolean insert(HashObject x) {
		// check if the table is full
		if (emptyNode == null)
			return false;

		LinkedListHashTableNode node = table[hash(x.key)];

		// if the node is the beginning of a chain
		if (node.flag == true) {
			// find new empty node
			LinkedListHashTableNode tempEmptyNode = emptyNode;
			emptyNode = emptyNode.next;

			// unlink the supposed empty node
			tempEmptyNode.former = null;
			tempEmptyNode.next = null;

			// update chain
			tempEmptyNode.next = node.next;
			node.next = tempEmptyNode;
			tempEmptyNode.former = node;

			if (tempEmptyNode.next != null)
				tempEmptyNode.next.former = tempEmptyNode;

			// copy data
			tempEmptyNode.data = x;
		} else {
			// if the node is empty
			if (node.data == null) {
				// if it\'s the emptyNode, update emptyNode
				if (node == emptyNode) {
					emptyNode = emptyNode.next;
				}

				// unlink this node from the empty node list
				if (node.former != null) {
					node.former.next = node.next;
				}
				if (node.next != null) {
					node.next.former = node.former;
				}
				node.next = null;
				node.former = null;

				// set up a new chain
				node.former = null;
				node.next = null;
				node.flag = true;

				// copy data
				node.data = x;
			}
			// if not empty, it\'s in another chain
			else {
				// copy the old data to a new emptyNode
				// ** find a new empty node
				LinkedListHashTableNode tempEmptyNode = emptyNode;
				emptyNode = emptyNode.next;
				// ** copy from the node to tempEmptyNode
				tempEmptyNode.former = node.former;
				tempEmptyNode.next = node.next;
				tempEmptyNode.data = node.data;

				// update chain
				// -- node is not the beginning of the chain, thus have a former
				node.former.next = tempEmptyNode;
				if (node.next != null)
					node.next.former = tempEmptyNode;

				// set up new chain
				node.former = null;
				node.next = null;
				node.flag = true;

				// copy data
				node.data = x;
			}
		}
		return true;
	}

	/**
	 * @param key
	 * @return - null if unfound
	 */
	public LinkedListHashTableNode search(int key) {
		LinkedListHashTableNode node = table[hash(key)];
		if (node.flag == false) {
			return null;
		} else {
			while (node != null) {
				if (node.data.key == key)
					return node;
				node = node.next;
			}
		}
		return null;
	}

	/**
	 * @param x
	 *            - x is a node from that table, thus has the information about
	 *            former/ next
	 * @return - false if no need to delete
	 */
	public boolean delete(LinkedListHashTableNode x) {
		// x don\'t have data, thus don\'t need to delete
		if (x.data == null)
			return false;

		// else, x must be in the chain
		// ** x is at the beginning of a chain
		if (x.flag == true) {
			// ** if x doesn\'t have a next, then simply delete it
			if(x.next==null){
				x.flag = false;
			}
			// ** if x has a next, then need to copy it\'s next to x\'s position,
			// then delete its next
			else{
				// temp is at the beginning of the chain
				LinkedListHashTableNode temp = x;
				// x becomes the second element in the chain then
				x = x.next;
				temp.data = x.data;
			}
		}
		// ** unlink x from the chain first
		if (x.former != null){
			x.former.next = x.next;
		}
		if (x.next != null){
			x.next.former = x.former;
		}
		// ** make x to be empty
		x.data = null;
		x.former = null;x.next = null;
		
		// ** then add x to be the first element in emptyNode list
		x.next = emptyNode;
		if(emptyNode!=null){
			emptyNode.former = x;
		}
		emptyNode = x;
		
		return true;
	}

	public static void main(String[] args) {
		LinkedListHashTable a = new LinkedListHashTable();
		LinkedList<Integer> l = new LinkedList<Integer>();
		Random rand = new Random();
		for (int i = 0; i < 100; i++) {
			int t = rand.nextInt(10000);
			System.out.println(t % 100);
			l.add(t);
			if (a.insert(new HashObject(t)) == false)
				System.out.println("List Full!");
		}
		while (!l.isEmpty()) {
			int t = l.pop();
			if (a.search(t) == null) {
				System.out.println("Error: element " + t + "unfound.");
			}
		}
		// int test = 12, t = test;
		// for(int i=0;i<100;i++){
		// a.insert(new HashObject(t));
		// }
	}

}

11.2-5:

If
|U| > m*n, then for the mapping from U to hash table of size m, it\’s at
least a m*n to n mapping, and thus it\’s possible for one slot to have n
elements.

发表于
2011-03-09 01:51 
songyy 
阅读(2001
评论(3
编辑 
收藏 
举报

 

版权声明:本文为flyfy1原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/flyfy1/archive/2011/03/09/1977774.html

算法导论(CLRS 2ed) 个人答案 11.2的更多相关文章

  1. 算法导论

       一.算法   非形式地说,算法【algorithm】就是任何定义的计算过程,该过程取某个值或值的集合作为 […]...

  2. 素数测试

    作者:jostree 转载请注明出处 https://www.cnblogs.com/jostree/p/10 […]...

  3. 最大子数组问题

    最大子数组问题 本文只是做一个记录,更细致的思路请查看算法导论 最大子数组结构体 typedef struct […]...

  4. 算法导论(CLRS)答案

    算法导论(CLRS)答案 Chapter Section I 1 2 p II 1 2 3 p III 1 2 […]...

  5. 算法导论(第三版)练习 2.3-1 ~ 2.3-7

    2.3-1 【31,41】,52,26,38,57,9,4931,41,【26,52】,38,57,9,49【 […]...

  6. 算法导论复习-第三章-函数的增长

    渐近符号     渐近符号常常用于一个算法的时间复杂度度空间复杂度。下面主要介绍五个渐近符号。     首先先 […]...

  7. 算法导论(第三版)练习 4.1-1 ~ 4.1-5

    4.1-1 返回数组的首个元素   4.1-2 最大子数组问题(js描述)   4.1-3 应该会吧..   […]...

  8. 算法导论(第三版)练习 2.1-1 ~ 2.1-4

    2.1-1 (a)  31 – 【41】 – 59 – 26 – […]...

随机推荐

  1. 浅析微信支付:商户平台开通现金红包、指定用户发放、红包记录查询

    本文是【浅析微信支付】系列文章的第十三篇,主要讲解在如何开通商户平台的红包功能和为用户发放红包,以及查询发送红 […]...

  2. Asp.Net平台下的图片在线裁剪功能的实现

    最近项目中有个图片在线裁剪功能,本人查找资料,方法如下:前台展现用jquery.Jcrop实现,后台使用 Sy […]...

  3. 结对编程—-分析队友代码

    通过测试运行队友代码,整体功能及需求都达到了个人编程的要求。下面就细节分析队友代码的优缺点。 优点:1、使用了 […]...

  4. 快速软件开发 学习笔记 之四

    第5章 快速开发中的Core Issues 人们感觉许多软件项目进展缓慢,但是,不同项目却以不同的方式“缓慢着 […]...

  5. 免费的多数据库管理工具sqldbx个人版本

    SqlDbx是一个先进的Sql编辑器和数据库对象资源管理器SqlDbx仅一个可执行的文件不需要安装 SqlDb […]...

  6. Netty中FastThreadLocal源码分析

    Netty中使用FastThreadLocal替代JDK中的ThreadLocal【JAVA】ThreadLo […]...

  7. MySQL定时备份数据库(全库备份)

    一、MySQL数据备份 1.1、 mysqldump命令备份数据 在MySQL中提供了命令行导出数据库数据以及 […]...

  8. javascript初识

    1、什么是js 基于对象和事件驱动并且具有相对安全性的客户端脚本语言,由网景公司开发。     2、js数据类 […]...

展开目录

目录导航