Data structure - stack, queue and tree
Developers can use arrays to establish a more complex data structure with variants of the linked list. This section explores three such data structures: stack, queue and trees. When the algorithm is given, use Java code directly for concise.
Stack
The stack is such a data structure, and the insertion and deletion of its data items can only be done at one end called the top of the stack. Because the last inserted data item is the data item that is the first to delete, developers tend to be stacked as a LILO (Last-In, First-Out) data structure.
Data item is pressed (insert) or pops up (deleted or acquired) the top. Figure 13 illustrates a stack with three String data items, each data item is pressed into the top of the stack.
Figure 13 There are three stacks that press String data items
As shown in Figure 13, the stack is built downwards in memory. For the pressing of each data item, the data items of the previous stack and all the data items below are to move down. When one data item is to pop up from the stack, the stack top element is obtained and removed from the stack. .
Stack is very useful in many programming environments. Two very ordinary environments:
· Stack Save Return Address: When the code calls a method, the address of the first instruction after the instruction is called into the top of the current thread. When the return command of the called method is performed, the address is popped up from the stack and then proceeding from the address. If another method is called, the stack's LIFO behavior mode ensures that the return instruction of the second method will perform shift to the first method, and the return instruction of the first method can perform transfers to the first method of calling to call The code of the code. The result is that the stack represents the modified method "Remember" to return the address.
· Stack Save the parameters and local variables of each called method: When a method is called, the JVM allocates memory allocated memory and local variables in the approach return address. If the method is an instance method, one of the parameters stored in the stack is the reference to the current object.
A stack can be generally implemented using a one-dimensional array or single-link table. If you use a one-dimensional array, an integer variable that is often named TOP saves the index of the stack top data item. Similarly, a reference variable that is often named TOP references the stack top node (including the stack top data item) in the single-chain table.
The implementation of the architecture construction stack found in the Java's Collections API. This implementation consists of a STACK interface, the ArrayStack and the LinkedListStack implementation class, and the Fullstackexception support class. In order to facilitate the release, these classes are packaged in the com.javajeff.cds package, where the CDS represents a complex data structure. Listing 8 gives a STACK interface.
Listing 8. Stack.java
// stack.javaPackage com.javajeff.cds; public interface stack {boolean iSempty (); Object peek (); void push (Object O); object pop ();}
The four methods of Stack are determined whether the stack is empty, obtain the stack top data item without deleting, any data item into the stack, obtain and delete the top element. In addition to a specific construction method of implementation, your program is enough to call these methods.
Listing 9 gives the implementation of the Stack based on one-dimensional array:
Listing 9 ArrayStack.java
// arraystack.java
Package com.javajeff.cds;
Public Class ArrayStack IMPLEMENTS Stack
{
Private int top = -1;
Private Object [] stack;
Public ArrayStack (int Maxelements)
{
Stack = new object [maxelements];
}
Public Boolean IMEMPTY ()
{
Return Top == -1;
}
Public Object PEEK ()
{
IF (TOP <0)
Throw new java.util.emptystackedException ();
Return Stack [TOP];
}
Public void Push (Object O)
{
IF (TOP == Stack.Length - 1)
Throw new fulstacked ();
Stack [ TOP] == 0;
}
Public Object Pop ()
{
IF (TOP <0)
Throw new java.util.emptystackedException ();
Return Stack [TOP -];
}
}
ArrayStack indicates that the stack consists of a private integer index TOP and a reference variable stack of a one-dimensional array. TOP identifies the stack top data item in the stack, initialization to -1 to indicate that the stack is empty. Use a maximum number of intended numbers of explanation when you want to create an ArrayStack object to call public ArrayStack. Trying to pop up a data item from a hollow stack top that throws a java.util.emptyStackException exception object in the pop () function. Similarly, if you try to press more than MaxElements in the stack, the PUSH (Object O) function throws the Fullstackexception object, and the code is shown in Listing 10:
Listing 10 Fullstackexception.java
Package com.javajeff.cds;
Public Class Fullstackexception Extends RuntimeException
{
}
In order to be relatively called EmptyStackException, Fullstackexception extends RuntimeException. This way, you don't have to add FullstackedException in the throws in a way.
Listing 11 gives the implementation of STACK-based single-linked list:
Listing 11. LinkedListStack.java
// linkedListStack.java
Package com.javajeff.cds;
Public Class LINKEDLISTSTACK IMPLEMENTS Stack
{
Private static class node
{
Object O;
Node next;
}
Private node top = NULL;
Public Boolean IMEMPTY ()
{
Return Top == NULL;
}
Public Object PEEK ()
{
IF (TOP == NULL)
Throw new java.util.emptystackedException ();
Return Top.o;
}
Public void Push (Object O)
{
Node Temp = new node ();
TEMP.O = O;
TEMP.NEXT = TOP;
TOP = TEMP;
}
Public Object Pop ()
{
IF (TOP == NULL)
Throw new java.util.emptystackedException ();
Object o = top.o;
TOP = Top.Next;
Return O;
}
}
LinkedListStack indicates that the stack consists of a private top-level node node and a private reference variable TOP, and the reference variable TOP is initialized to NULL represents an empty stack. LINKEDLISTSTACK does not require a constructor with respect to a stack that is implemented with a one-dimensional array. In this way, Void Push (Object O) does not need to throw a FullStackexception object. However, Object Pop () still needs to check whether the stack is empty, which may result in a throwing EMPTYSTACKEXCEPTION object. Because we have seen interfaces and three classes that make up this data structure implementation, we will exemplify the use of stacks.
Listing 12. StackDemo.java
// stackdemo.java
Import com.javajeff.cds. *;
Class StackDemo
{
Public static void main (string [] args)
{
System.out.println ("ArrayStack Demo");
System.out.println ("-------------");
StackDemo (New ArrayStack (5));
System.out.println ("LinkedListStack Demo);
System.out.println ("-------------------");
StackDemo (New LinkedListStack ());
}
Statci Void StackDemo (Stack S)
{
System.out.println ("Pushing /" Hello / ");
S.push ("Hello");
System.out.println ("Pushing /" World / ");
S.push ("world");
System.out.println ("Pushing StackDemo Object");
S.Push (new stackdemo ());
System.out.Println ("Pushing Character Object");
S.Push (New Character ("a"));
Try
{
System.out.println ("Pushing /" One Last Item / ");
S.push ("One last item");
} catch (Fullstackexception E)
{
System.out.println ("One Push Too Many");
}
SYSTEM.OUT.PRINTLN ();
While (! s.IMempty ())
System.out.println (S.POP ());
Try
{
S.POP ();
}
Catch (java.util.emptystackexception e)
{
SYSTEM.OUT.PRINTLN ();
}
SYSTEM.OUT.PRINTLN ();
}
}
The following output is generated when running STACKDEMO:
ArrayStack Demo --------------- Pushing "Hello" Pushing "World" Pushing StackDemo objectPushing Character objectPushing Thread objectPushing "One last item" One push too manyThread [A, 5, main] CStackDemo @ 7182c1WorldHelloOne pop too manyLinkedListStack Demo -------------------- Pushing "Hello" Pushing "World" Pushing StackDemo objectPushing Character objectPushing Thread objectPushing "One last item" One last itemThread [A , 5, main] cstackdemo @ cac268worldhelloone pop TOMY queue
The queue is such a data structure, insertion of data items on one end (column end), and the acquisition or deletion of the data item is on the other end (team header). Because the first inserted data item is also the first acquired or deleted data item, developers generally refer to the queue as FIFO data structure.
Developers often use two queues: linear queue and loop queue. In both queues, data items are inserted in the queue, then move to the team header and delete or get it from the queue header. Figure 14 illustrates linearity and cycling queues.
Figure 14 has four linear queues and seven data items of the inserted integer data items.
The linear queue of Figure 14 stores four data items, and the integer 1 is the first. The queue is full, and an additional integer data item cannot be stored because REAR has already referred to the rightmost (last) slot. The slot pointing to the plane is empty because it involves linear queue behavior. At first, Front and Rear point to the leftmost slot, indicating that the team is empty. In order to store integer 1, REAR points to the next slot on the right, and stores 1 to that slot. When the integer 1 is obtained or deleted, the Front enters a slot to the right.
The cyclic queue of Figure 14 stores seven integer data items, starting with integer 1. This queue is full and cannot store other integer data until the Front is in front of the clockwise direction. Similar to the linear queue, the slot of the Front point is empty and the behavior involved in the cycle queue. Initially, Front and Rear points to the same slot, indicating that the team is empty. For each data item, REAR advances a slot, and the Front is advanced in a slot for the deletion of each data item.
Queues are very useful in many programming environments. Two common scenarios are:
• Thread Scheduling: JVM or a basic operating system creates multiple queues to reflect different thread priorities. The thread information will block because all threads of a given priority are stored in the relevant queue.
· Print Task: Because the printer is slower than the computer, the operating system assigns its print task to its print subsystem, and the print subsystem will insert these tasks into a print queue. The first task in the queue first prints first, and the last task is finally printed.
Developers often use one-dimensional array to implement a queue. However, if there are multiple queues, or because the priority cause queue needs to be inserted outside the queue, the developer may choose a double-linked list. Here, we use the array to implement linear and loop queues. Let us start from the Queue interface of the list 13:
// queue.javaPackage com.javajeff.cds; public interface que {void insert (Object O); boolean iSempty (); boolean isfull (); Object remove ();} Queue declares four methods, used for queue In the stored data item, determine if the queue is empty, determine if the queue is full, get or delete the data item by the queue.
Listing 14 gives the implementation of linear queues based on one-dimensional array:
Listing 14. ArrayLinearqueue.java
// arraylinearqueue.java
Package com.javajeff.cds;
Public Class ArrayLinearQueue Implements Queue
{
Private int around = -1, rear = -1;
Private Object [] queue;
Public ArrayLinearqueue (int Maxelements)
{
Queue = New Object [MAXELEments];
}
Public void insert (Object O)
{
IF (REAR == Queue.Length - 1)
Throw new fullqueueexception ();
Queue [ REAR] = O;
}
Public Boolean ISempty ()
{
Return Front == REAR;
}
Public boolean isfull ()
{
ReturnR == queue.length - 1;
}
Public Object Remove ()
{
IF (Front == Rear)
Throw new EmptyQueexception ();
Return Queue [ Front];
}
}
ArrayLinearQueue indicates that the queue consists of a Variety of Front, REAR and Queue. Where Front and REAR are initialized to -1 indicate that the team is empty. Like the constructor of ArrayStack, use a maximum number of indicated elements to create a PUBLIC ArrayLinearqueue (int maxelements) to create an ArrayLinearqueue object.
When REAR illustrates the last element of the array, the ArrayLinearqueue's INSERT (Object O) method throws the fulqueueexception exception object. FullqueueException code is shown in Listing 15:
Listing 15. FullQueueException.java
// fullqueueexception.javaPackage com.javajeff.cds; public class fullueueexception extens runimeexception {}
When Front is equal to REAR, the ArrayLinearqueue's Remove () method throws the EmptyQueueException object. The code of the EMPTYQUEEXCEPTION is as follows:
Listing 16. EmptyQueueException.java
// EmptyQueueException.javaPackage com.javajeff.cds; public class emptyqueueexception extends runtimeException {}
Listing 17 gives the implementation of cyclic queues based on one-dimensional array:
Listing 17. Arraycialcularqueue.java// arraycircularqueue.java
Package com.javajeff.cds;
Public Class ArraycircularQueue Implements Queue
{
Private int around = 0, REAR = 0;
Private Object [] queue;
Public ArrayCircularQueue (int maxelements)
{
Queue = New Object [MAXELEments];
}
Public void insert (Object O)
{
int Temp = REAR;
REAR = (Reart 1)% queue.length;
IF (Front == Rear)
{
REAR = TEMP;
Throw new fullqueueexception ();
}
Queue [REAR] = O;
}
Public Boolean ISempty ()
{
Return Front == REAR;
}
Public boolean isfull ()
{
Return ((Rear 1)% queue.length) == front;
}
Public Object Remove ()
{
IF (Front == Rear)
Throw new EmptyQueexception ();
Front = (Front 1)% queue.length;
Return Queue [Front];
}
}
From a private domain variable and constructor, ArrayCIrcularQueue indicates a similar implementation with ArrayLinearqueue. The INSERT (Object O) method is aware of that it has saved the current value before making REAR points to the next slot. In this way, if the loop queue is full, then REAR is restored to the original value before the FullQueueException exception object is thrown. The restore of the REAR value is necessary, otherwise the Front is equal to the REAR, which will cause the EmptyQueueException (even if the loop queue is not empty).
After studying the interface and various classes of the data structure of the queue, considering the list 18, this is an application for explaining linear and cyclic queues.
Listing 18. Queuedemo.java
// queuedemo.javaimport com.javajeff.cds. *; Class queuedemo {public static void main (string [] args) {system.out.println; system.out.println ("---- ----------------- "); Queuedemo (New ArrayLinearqueue (5)); System.out.Println (" ArrayCircularQueue Demo "; System.out.println (" - ------------------- "); Queuedemo (New Arraycircularqueue (6)); // NEED One More Slot Because // of Empty Slot in circular // Implementation} Static Void Queuedemo (Queue q) {system.out.println ("is Empty =" q.isempty ()); System.out.Println ("is full =" q.isfull ()); system.out.println ("Inserting /" this / ""); Q. Isert ("this"); system.out.println ("INSERTING / IS /"); Q. Insert ("IS"); system.out.println ("INSERTING /" A / ""); q.insert ("a"); system.out.println ("INSERTING /" SENTENCE / "); Q.insert (" Senten CE "); System.out.Println (" Inserting / ""); Q. Insert ("."); try {system.out.println ("INSERTING /" ONE Last Item / "); Q .insert ("One last item");} catch (fullqueueexception e) {system.out.println ("One Insert Too Many"); System.out.Println ("IS Empty =" q.isempty ()); System.out.println ("is full =" q.isffull ());} system.out.println ();
While (! q.isempty ()) System.out.println (q.Remove () "[IS EMPTY =" q.isempty () ", is full =" q.isfull () "]" ); Try {q.remove ();} catch (emptyqueueexception e) {system.out.println ("One Remove Too Many");} system.out.println ();}} Run Queuedemo get the following output:
ArrayLinearqueue Demo ------------------- is Empty = trueis full = falseinserting "this" inserting "IS" inserting "a" inserting "Sentence" Inserting "." Inserting "." Inserting "One last item" One Insert Too Manyis Empty = Falseis Full = TrueThis [Is Empty = False, Is Full = True] IS [IS EMPTY = FALSE, IS FULL = TRUE] a [IS EMPTY = FALSE, IS FULL = True] SENTENCE [IS Empty = false, is full = true]. [is empty = true, is full = true] One Remove Too Manyarraycircularqueue Demo --------------------- Is empty = trueIs full = falseInserting "This" Inserting "is" Inserting "a" Inserting "sentence" Inserting "." Inserting "One last item" One insert too manyIs empty = falseIs full = trueThis [Is empty = false, Is full = false] IS [is Empty = false, is full = false] a [is es Empty = false, is full = false] SENTENCE [IS EMPTY = false, is full = false]. [is empty = true, is full = false ] One Remove Too Many
tree
The tree is a group of poor nodes, with one node as the root, and the remaining nodes below the roots are organized in a hierarchical manner. Quote The node of the next node is a parent node, similar, the node referenced by the upper node is a child node. The node without children is the leaves node. A node might be the parent node and subpost.
A parent node can reference the required multiple child nodes. In many cases, the parent node can only reference two children nodes, and the tree based on this node is a binary tree. Figure 13 shows a binary tree that stores seven String words in alphabetical sequence.
Figure 15 A binary tree with seven nodes is inserted, deleted, and traversed nodes in binary or other types of trees. For short purposes, we don't study the recursive node insertion, node deletion, and the traversal algorithm of the tree. We change to the source code of a word count program in Listing 19 to illustrate the traversal of the recursive nodes insertion and the tree. The code is used in the code to create a binary tree, with each node including a count of words and words, and then display words and their counts in alphabetical sequence algorithms by the trees.
Listing 19. wc.java
// wc.javaimport java.io. *; Class Treenode {string word; // word being stored. Int count = 1; // count of Words seen in text. Treenode Left; // Left subtree Reference. Treenode Right; / / Right Subtree Reference (String Word) {this.word = word; left = right = null;} public void insert (string word) {int stat (word); if (Status> 0 ) // word argument precedes current word {// If left-most leaf node reached, then insert new node as // its left-most leaf node. Otherwise, keep searching left. if (left == null) left = new TreeNode (Word); Else Left.insert (Word);} else if (status <0) // Word Argument Follows Current Word {//iff Node Reached, THEN INSERT NEW NODE AS // ITS Right-Most LEAF Otherwise, Keep Searching Right. IF (Right == Null) Right = new Treenode (Word); else right.insert (word);} else this.count ;}} class wc {public static void main (string [] args) throws oews oException {Int ch; // Read Each Character from Standard Input Until A Letter // Is Read. This Letter Indicates The Start of A Word. While ((ch = system.in.read ())! = -1) {// if character is a letter dam Start of Word Detected. IF (Character.isletter (CHAR) CH) {// Create StringBuffer Object to Hold Word Letters. StringBuffer SB = New StringBuffer ();
// Place first letter character into StringBuffer object sb.append ((char) ch);.. // Place all subsequent letter characters into StringBuffer // object do {ch = System.in.read (); if (Character.isLetter (CHAR) CH)) sb.append ((char) ch); Else Break;} while (TRUE); // Insert Word Into Tree. if (root == null) root = new treenode (sb.toString () Else root.insert (sb.tostring ());}} DITE (ROOT);} static void display (Treenode root) {// if Either the root node or the current node is null, // signifying what a leaf Node Has Been Reached, Return. if (Root == Null) Return; // Display All Left-Most Nodes (IE, Nodes Whose Words // Precede Words In The Current Node). Display (root.left); // Display current node's word and count. System.out.println ("Word =" root.word ", count =" root.count); // Display All Right-Most Nodes (IE, Nodes Whose Words / / FOLLOW WORDS in the current node. Display (root.right);}} Because there is already a lot of comments, we don't discuss the code here. In order to run this application as follows: To count the number of words in the file, open a command line that includes a retransmissioner. For example, issue a Java WC