Introduction to algorithms 11.2-4 create a free linked list with unused slots in the hash list

Source: Internet
Author: User
I. Question

This section describes how to allocate and deploy the storage space of elements by linking all unused slots into a free table. Assume that a slot can store a flag and an element with one or two pointers. All dictionary operations and free linked list operations should have the expected o (1) running time. Is the free linked list a double-stranded table? Or is it enough for a single-chain table?

Ii. Thinking

Known (1) all unused slots chain into a free linked list (2) slots that are slot (3) Hash (x) return the slot of X

A slot stores the following content. The occupied content and unused content have different meanings.

struct node{int key;bool flag;//0:free,1:usedint pre;int next;};

When this slot is not occupied, the value is as follows:

Struct node {int key; // meaningless, initialized to-1 bool flag; // 0: freeint pre; // an idle slot in the free linked list, -1int next; // The next idle slot in the free linked list;-1} if no slot exists };

When this slot is occupied, the values are as follows:

Struct node {int key; // keyword bool flag; // 1: usedint pre; // next node with the same hash value int next; // previous node with the same hash value };

 

During the insert operation, an idle slot is retrieved from the free linked list, and the keyword X is entered to modify the pointer. The corresponding queue of the linked list can be divided into the following situations:

(1) If the slot to which X belongs is not occupied

Step 1: Remove this slot from the free linked list

Step 2: Enter the keyword X.

Step 3: Modify the pointer. In this case, both next and pre are set to-1.

(2) The slot to which X belongs has been occupied. The key to occupying this slot is that Y and Y also belong to this slot.

Step 1: Extract an idle slot from the free linked list. This slot is definitely not the slot to which X belongs.

Step 2: Enter the keyword X.

Step 3: Modify the pointer and add the slot linked list to the "queue with the slot X as the header node"

(3) The slot to which X belongs has been occupied. The key to occupying this slot is Y, and y does not belong to this slot. (2) We can see that this situation is possible.

Step 1: Extract an idle slot from the free linked list. This slot is definitely not the slot of X or the slot of Y, just take it and use it

Step 2: Fill in the keyword Y in the new slot, modify the pointer, And let y use this new slot, and return the original slot to X

Step 3: Enter the keyword X in the slot to which X belongs.

Step 4: Modify the "slot" pointer to which X belongs, similar to (1)-Step 3

 

During the delete operation, the keyword to be deleted is X, and the slot occupied by X is released, which can be divided into the following situations:

(1) The slot occupied by X is the slot of X, and slot-> next =-1, that is, only X in all keywords belongs to this slot. After X is deleted, slot is idle.

Step 1: Release slot to the free linked list

(2) The slot occupied by X is the slot to which X belongs. However, only X belongs to this slot in other keywords. The Key Slot should be used first, instead, release the "slat that is not your own keyword and temporarily used ."

Step 1: select another slot2 from the queue with the slot as the header node. The slot2 keyword belongs to the slot rather than the slot2, and only the slot2 is used because it is occupied.

Step 2: Fill in slot2 content

Step 3: Modify the pointer so that slot exists in the queue instead of slot2. The difference is slot or queue header.

Step 4: Release slot2 to the free linked list

(3) The slot occupied by X is not the slot to which X belongs. In this case, this slot must not be the queue header, and other keywords exist in the queue, and occupies the slot to which X belongs.

Step 1: remove the slots occupied by X from the "queue with the slot header of X"

Step 2: Release slot to the free linked list

 

Search operations. If you understand insert and delete operations, the search operations are relatively simple. The keyword to be searched is X, which can be divided into several situations.

(1) The slot to which X belongs is not occupied, that is, there is no keyword with the same slot as X, and of course there is no

(2) The slot to which X belongs is occupied, but its key does not belong to this slot. It is the same as (1) and does not have the keyword of the same slot as X.

(3) The slot to which X belongs is occupied, and the key to its storage belongs to this slot, that is, the keyword with the same slot as x exists. I just don't know if this keyword is X or not, so I need to look for it further.

 

The "retrieve an idle slot from the free linked list" and "Release the slot to the free linked list" operations mentioned repeatedly during the insertion and deletion process are relatively simple. For details, see the explanation in the code.

 

Iii. Code
# Include <iostream> # include <string> using namespace STD; // slot node struct node {int key; // keyword bool flag; // 0: free, 1: usedint pre; int next;}; int free = 0; // head slot of the Free linked list // calculate the slotint Hash (int x) {return X % 20 ;} // retrieve an idle slot from the free linked list and specify the slotint removeslotfromfree (node * a, int h) numbered H {// mark it as useda [H]. flag = 1; // modify the pointer to remove from the free linked list if (a [H]. PRE> = 0) A [A [H]. pre]. next = A [H]. next; else free = A [H]. next; // If the slot of the table header is removed, update the table header. Slot location if (a [H]. next> = 0) A [A [H]. next]. pre = A [H]. pre; // return the return H of the retrieved slot;} // release the slot numbered H to the free linked list void freeslottofree (node * a, int H) {// mark as freea [H]. flag = 0; // modify the pointer and insert it to the linked list header A [H]. next = free; A [H]. pre =-1; A [H]. key =-1; // update the header slotfree = H;} // The Int search (node * a, int X) {int H = hash (X ); // (1) the slot to which X belongs is not occupied, that is, there is no keyword for the same slot as X, and of course there is no slot to which X is occupied. // (2) the slot to which X belongs is occupied, but the key stored in it does not belong to this slot. It is the same as (1) and does not have the keyword if (a [H] with the same slot as X. flag = 0 | Hash (A [H]. Key )! = H) Return-1; // (3) the slot to which X belongs is occupied, and the key to its storage belongs to this slot // that is, the keyword with the same slot as x exists, I just don't know if this keyword is X. I need to find it further // The search method is to traverse the queue int P = h with the slot header; while (P> = 0 & A [p]. key! = X) P = A [p]. next; if (a [p]. key = x) return P; else return-1;} // during the insert operation, an idle slot is retrieved from the free linked list, and the keyword X is entered to modify the pointer, in the queue corresponding to the linked list, void insert (node * a, int X) {// whether the IF (search (A, x)> = 0) already exists) {cout <"error: Exit" <Endl; return ;}// calculate the slotint H = hash (x) of X; // (1) the slot to which X belongs is not occupied if (a [H]. flag = 0) {// Step1: Remove this slot from the free linked list int T = removeslotfromfree (A, H); // step2: Enter the keyword XA [T]. key = x; // Step 3: Modify the pointer. In this case, both next and pre are set to-1A [T]. next =-1; A [T]. pre =-1;} // (2) the slot to which X belongs has been occupied. The key to occupying this slot is Y, Y also belongs to this slotelse if (Hash (A [H]. key) = h) {// Step1: extracts an idle slot from the free linked list. This slot is definitely not the slot to which X belongs. Just take it and use int T = removeslotfromfree (, free); // Step 2: Enter the keyword XA [T]. key = x; // Step 3: Modify the pointer and add the slot linked list to a [T] in "queue with the slot of X as the header node". next =-1; A [H]. next = T; A [T]. pre = H;} // (3) the slot to which X belongs has been occupied. The key to occupying this slot is Y, y does not belong to this slot, // pass (2) we can see that this is possible because else {// Step1: extracts an idle slot from the free linked list. This slot is definitely not the slot of X or the s of Y. Lotint T = removeslotfromfree (A, free); // Step 2: Enter the keyword Y in the new slot, modify the pointer, And let y use this new slot, return the original slot to XA [T] = A [H]; A [A [H]. pre]. next = T; if (a [H]. next> = 0) A [A [H]. next]. pre = T; // Step 3: Enter the keyword XA [H] in the slot to which X belongs. key = x; // step4: Modify the slot pointer to which X belongs, similar to (1)-step3a [H]. next =-1; A [H]. pre =-1 ;}/// delete operation, the keyword to be deleted is X, and the slotvoid Delete (node * a, int X) occupied by X is released) {// whether int ret = search (A, x) exists; If (Ret <0) {cout <"error: not exit" <Endl; retur N ;}// (1) the slot occupied by X is the slot of X, and slot-> next =-1 // that is, only X belongs to this slot in all the keywords, after X is deleted, the slot is idle. If (ret = hash (x) & A [RET]. next =-1) {freeslottofree (A, RET);} // (2) the slot occupied by X is the slot of X, however, there are other keywords except that X belongs to this slot. // The Key Slot should be used first, release slatelse if (ret = hash (x) & A [RET]. next! =-1) {// Step1: select another slot2 keyword from the queue with the slot as the header node and not slot2 because the slot is occupied, so slot2int next = A [RET]. next; // next is the slot2 number // Step 2: Enter slot2 content in Slota [RET] = A [A [RET]. next]; // Step 3: Modify the pointer so that slot exists in the queue instead of slot2. The difference is slot or queue header A [A [RET]. next]. pre = ret; // Step 4: Release slot2 to freeslottofree (A, next) in the free linked list;} // (3) the slot occupied by X is not the slot of X, in this case, this slot must not be the queue header // other keywords exist in the queue, and occupies the slotelse if (Ret! = Hash (x) {// Step1: removes the slot occupied by X from the queue with the header of X [A [RET]. pre]. next = A [RET]. next; if (a [RET]. next> = 0) A [A [RET]. next]. pre = A [RET]. pre; // Step 2: Release slot to freeslottofree (A, RET); }}// output slotvoid print (node * A) {int I; for (I = 0; I <20; I ++) cout <A [I]. flag <''<A [I]. key <''<A [I]. next <''<A [I]. pre <Endl ;}int main () {int I; // construct a hash node A [20] with 20 slots; for (I = 0; I <20; I ++) {// At the beginning, all slots are freea [I]. flag = 0; if (I = 19) A [I]. next =-1; else a [I]. next = I + 1; A [I]. pre = I-1; A [I]. key =-1;} // teststring STR; int X; while (1) {CIN> STR; If (STR = "I") {x = rand () % 100; cout <x <Endl; insert (a, x);} else if (STR = "D") {CIN> X; Delete (, x);} else if (STR = "p") print (a);} return 0 ;}

 

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.