"Turn" data structure and algorithm (above)

Source: Internet
Author: User
Tags comparable

A data structure is a collection of data that is organized in some form, not only to store data, but also to support access to and manipulation of data. An algorithm is a set of simple instructions that need to be followed to solve a problem that is clearly specified. The following is your own collation of common data structures and algorithms related content, if there are errors, welcome to point out.

In order to facilitate the description, the code part of the article is written in the Java language, in fact, Java itself on a number of common data structures, linear tables, stacks, queues, etc. have provided a good implementation of the Java Collection framework that we often use, there is a need to read this article. Java-Collection Framework full parsing

一、线性表  1.数组实现  2.链表二、栈与队列三、树与二叉树  1.树  2.二叉树基本概念  3.二叉查找树  4.平衡二叉树  5.红黑树四、图五、总结
First, linear table

The linear table is the most common and simplest data structure, which is a finite sequence of n elements.

There are generally two ways to implement a linear table, one is to use an array to store the elements of a linear table, that is, to store the data elements of the linear table sequentially with a contiguous set of storage cells. The other is to use a linked list to store the elements of a linear table, that is, a set of arbitrary storage units to store the data elements of the linear table (the storage unit can be continuous or discontinuous).

Array implementations

An array is a fixed-size data structure, and all operations on a linear table can be implemented by an array. Although once the array is created, its size cannot be changed, but when the array can no longer store new elements in the linear table, we can create a new large array to replace the current array. This enables the use of arrays to implement dynamic data structures.

    • Code 1 creating a larger array to replace the current array
int[] oldArray = new int[10];int[] newArray = new int[20];for (int i = 0; i < oldArray.length; i++) {    newArray[i] = oldArray[i];}// 也可以使用System.arraycopy方法来实现数组间的复制        // System.arraycopy(oldArray, 0, newArray, 0, oldArray.length);oldArray = newArray;
    • Code 2 adding element e to the array position index
//oldArray 表示当前存储元素的数组//size 表示当前元素个数public void add(int index, int e) {    if (index > size || index < 0) {        System.out.println("位置不合法...");    }    //如果数组已经满了 就扩容    if (size >= oldArray.length) {        // 扩容函数可参考代码1    }    for (int i = size - 1; i >= index; i--) {        oldArray[i + 1] = oldArray[i];    }    //将数组elementData从位置index的所有元素往后移一位    // System.arraycopy(oldArray, index, oldArray, index + 1,size - index);    oldArray[index] = e;    size++;}

The above simply write out the array to implement linear table two typical functions, we can refer to the Java ArrayList Collection class source code. The advantage of the linear table of array implementations is that it is more efficient to access or modify elements by subscript, and the main disadvantage is that insertions and deletions are expensive, such as inserting an element in front of the first position, and then moving all the elements backward one position. To improve the efficiency of adding or removing elements at any location, a chain structure can be used to implement a linear table.

Linked list

A linked list is a non-sequential, non-sequential storage structure on a physical storage unit, and the logical order of the data elements is achieved through the order of the pointers in the linked list. A linked list consists of a series of nodes that do not have to be connected in memory. Each node consists of data and chain part Next,next refers to the next node, so when added or deleted, only need to change the relevant node of the next point, the efficiency is very high.


The structure of a single linked list

The following main code to show some of the basic operation of the list, it should be noted that this is mainly a single-linked list, for the time being regardless of the double-linked list and circular linked list.

    • Code 3 node of the linked list
class Node<E> {    E item;    Node<E> next;    //构造函数    Node(E element) {       this.item = element;       this.next = null;   }}
    • After code 4 defines a node, it is normally initialized with the head and tail nodes before use.
//头节点和尾节点都为空 链表为空Node<E> head = null;Node<E> tail = null;
    • Code 5 NULL linked list create a new node
//创建一个新的节点 并让head指向此节点head = new Node("nodedata1");//让尾节点也指向此节点tail = head;
    • Code 6 appends a node to a linked list
//创建新节点 同时和最后一个节点连接起来tail.next = new Node("node1data2");//尾节点指向新的节点tail = tail.next;
    • Code 7 sequential traversal of linked list
Node<String> current = head;while (current != null) {    System.out.println(current.item);    current = current.next;}
    • Code 8 reverse-Traverse linked list
static void printListRev(Node<String> head) {//倒序遍历链表主要用了递归的思想    if (head != null) {        printListRev(head.next);        System.out.println(head.item);    }}
    • Code single-Link list inversion
//单链表反转 主要是逐一改变两个节点间的链接关系来完成static Node<String> revList(Node<String> head) {    if (head == null) {        return null;    }    Node<String> nodeResult = null;    Node<String> nodePre = null;    Node<String> current = head;    while (current != null) {        Node<String> nodeNext = current.next;        if (nodeNext == null) {            nodeResult = current;        }        current.next = nodePre;        nodePre = current;        current = nodeNext;    }    return nodeResult;}

The above several pieces of code mainly show the list of several basic operations, there are many like to get the specified elements, remove elements and other operations can be done by themselves, write the code must clarify the relationship between nodes, so that it is not easy to error.

There are other ways to implement the list, such as circular single linked list, doubly linked list, circular doubly linked list. Circular single linked list is mainly the last node of the list points to the first node, the whole form a chain ring. The two-way linked list is composed of two pointers in the node, one pointing to the precursor, one pointing to the successor, and the implementation of the LinkedList collection class in the JDK is the doubly linked list. A circular doubly linked list is the last node that points to the first node.

Second, stack and queue

Stacks and queues are also more common data structures, which are relatively special linear tables because, for stacks, access, insert, and delete elements can only be made at the top of the stack, and for queues, elements can only be inserted from the end of the queue, accessed and deleted from the queue header.

Stack

A stack is a table that restricts insertions and deletions to only one location, which is the end of the table, called the top of the stack, and the basic operation of the stack is push (stack) and pop (out of the stack), which is equivalent to inserting, which is equivalent to deleting the last element. The stack is sometimes called the LIFO (last on first out) table, which is LIFO.


The model of the stack

Let's look at a classic topic and deepen our understanding of the stack.


A classic topic about stacks

The answer is C, the principle of which can be well thought out.

Because the stack is also a table, any method that implements the table can implement the stack. We open the source code of the class stack in the JDK and we can see that it inherits the class vector. Of course, stack is the container class before Java2, and now we can use LinkedList to do all the work on the stack.

Queue

A queue is a special linear table, except that it allows for deletion only at the front end of the table (front), but in the back-end (rear) of the table, and, like the stack, the queue is a linear table with limited operations. The end of the insert operation is called the tail of the queue, and the end of the delete operation is called the team header.


Queue

We can use the list to implement the queue, the following code simply shows the use of LinkedList to implement the queue class.

    • Code 9 simple Implementation Queue class
public class MyQueue<E> {    private LinkedList<E> list = new LinkedList<>();    // 入队    public void enqueue(E e) {        list.addLast(e);    }    // 出队    public E dequeue() {        return list.removeFirst();    }}

A normal queue is a first-in-one data structure, and the elements are given priority in the priority queue. When an element is accessed, the element with the highest priority is deleted first. Priority queues are more widely used in life, for example, hospital emergency rooms give priority to patients, and patients with the highest priority are treated first. In the Java Collection framework, class Priorityqueue is the implementation class of the priority queue, we can read the source code.

Three, tree and two fork tree

Tree structure is a kind of very important nonlinear data structure, in which tree and two-fork trees are most commonly used. Before we introduce the binary tree, let's take a brief look at the tree's related content.

Tree

A tree is a set of hierarchical relationships consisting of a finite number of n (n>=1) nodes. It has the following characteristics: Each node has 0 or more child nodes, the node without the parent node is called the root node, each non-root node has and only one parent node , in addition to the root node, each child node can be divided into multiple disjoint subtree.


Structure of the tree

The basic concept of binary tree

    • Defined

A binary tree is a tree structure with a maximum of two subtrees trees per node. Usually subtrees are referred to as the left subtree and the right sub-tree. Binary trees are often used to implement a two-fork search tree and a two-fork heap.

    • Related properties

Each node of a binary tree has a maximum of 2 subtrees trees (no nodes with a degree greater than 2), and the subtree of the binary tree has left and right points, and the order cannot be reversed.

The first layer of the binary tree has at most 2^ (i-1) nodes, and a two-tree with a depth of K has a maximum of 2^k-1 nodes.

A two-fork tree with a depth of K and a 2^k-1 node is called a full two-tree ;

A depth of K, a two-tree with n nodes, is called a complete binary tree when and only if each of its nodes corresponds to a node of 1 to N in a full two-tree with a depth of K.


    • Three methods of traversal

In some applications of binary tree, it is often required to find a node with some characteristics in the tree, or to do some processing of all the nodes in the tree, which involves the traversal of the two-fork tree. The binary tree is mainly composed of 3 basic units, the root node, the Saozi right sub-tree. If the first left and right, then according to the three parts of the order of traversal, can be divided into the first sequence traversal, the middle sequence traversal and subsequent traversal of three.

(1) The first sequence traversal if the binary tree is empty, then the empty operation, otherwise access the root node first, and then the first sequence to traverse the left subtree, and finally the first sequence to traverse the right sub-tree. (2) the middle sequence traversal If the binary tree is empty, then the empty operation, otherwise, the middle sequence traversal of the left subtree, and then access the root node, and finally the middle sequence to traverse the right sub-tree. (3) post-order traversal If the binary tree is empty, then the empty operation, otherwise the sequential traversal Zuozi access the root node, and then the subsequent traversal of the right subtree, the last access to the root node.


A given binary tree writes three kinds of traversal results
    • The difference between a tree and a two-fork tree

(1) Binary tree Each node has a maximum of 2 child nodes, the tree is unrestricted. (2) The sub-tree of the nodes in the binary tree is divided into Saozi right subtree, even if there is only one subtrees tree in a node, it is also to indicate whether the subtree is Zuozi or right subtree, that is, the binary tree is orderly. (3) The tree must not be empty, it has at least one node, and a binary tree can be empty.

Above, we mainly introduce the related concept of two-fork tree, we will start with a two-fork search tree, introduce several common types of binary tree, and implement the previous theory part with code.

Binary search Tree

    • Defined

Binary search tree is a binary sort tree, also known as a binary tree. A binary search tree is either an empty tree, or a two-prong tree with the following properties: (1) The Joz tree is not empty, then the value of all nodes on the left subtree is less than the value of its root node, (2) If the right subtree is not empty, the value of all nodes on the right subtree is greater than the value of its root node, and (3) the left and right subtrees are two forks respectively; 4) There are no nodes with the same key value.


A typical two-fork lookup tree Build process
    • Performance analysis

For binary lookup trees, when the given values are the same but the order is not the same, the two-fork look-up tree pattern constructed is different, and here is an example.


Different forms of balanced binary tree in different ASL

As you can see, the average lookup length of a two-fork lookup tree with n nodes is related to the morphology of the tree. Worst case, when the keyword inserted in order, the formation of the two-fork search tree into a single tree, the depth of the tree is n, its average search length (n+1)/2 (and the same order lookup), the best case is the two-fork look-up tree morphology and binary find the same decision tree, its average lookup length and log2 (n) is On average, the average lookup length and logn of the binary lookup tree are equal orders of magnitude, so in order to get better performance, it is usually necessary to "balance" the binary search tree during the construction process, then we will introduce balanced binary tree and red black tree, which can make the height of the lookup tree O (log (n)).

    • Code 102 node of the fork Tree
class TreeNode<E> {    E element;    TreeNode<E> left;    TreeNode<E> right;    public TreeNode(E e) {        element = e;    }}

The three traversal of binary search tree can be implemented directly by recursive method:

    • Code 12 first-order traversal
protected void preorder(TreeNode<E> root) {    if (root == null)        return;    System.out.println(root.element + " ");    preorder(root.left);    preorder(root.right);}
    • Code 13, Sequential traversal
protected void inorder(TreeNode<E> root) {    if (root == null)        return;    inorder(root.left);    System.out.println(root.element + " ");    inorder(root.right);}
    • Code 14 post-Iteration traversal
protected void postorder(TreeNode<E> root) {    if (root == null)        return;    postorder(root.left);    postorder(root.right);    System.out.println(root.element + " ");}
    • Code 152 Simple implementation of a binary lookup tree
/** * @author JACKALTSC */public class Mybinsearchtree<e extends Comparable<e>> {//root private treenode& Lt    E> Root; Default constructor public Mybinsearchtree () {}//two fork Find tree Search public boolean searches (E-e) {treenode<e> Curre        NT = root;            while (current! = null) {if (E.compareto (current.element) < 0) {current = Current.left;            } else if (E.compareto (current.element) > 0) {current = Current.right;            } else {return true;    }} return false; }//Two fork Find tree Insert public boolean insert (E e) {//If the element that was previously an empty binary tree was inserted as the root node if (root = null) {Roo        t = Createnewnode (e);            } else {//or else will traverse from the root node until the appropriate parent node is found treenode<e> parent = null;            treenode<e> current = root; while (current = null) {if (E.compareto (current.element) < 0) {Parent = current;                current = Current.left;                    } else if (E.compareto (current.element) > 0) {parent = current;                current = Current.right;                } else {return false; }}//Insert if (E.compareto (parent.element) < 0) {Parent.left = Createne            Wnode (e);            } else {parent.right = Createnewnode (e);    }} return true;    }//Create a new node protected treenode<e> Createnewnode (e e) {return new TreeNode (e);    }}//Two fork tree node class Treenode<e extends Comparable<e>> {E element;    Treenode<e> left;    Treenode<e> right;    Public TreeNode (e e) {element = e; }}

The above code 15 mainly shows a simple two-fork search tree of its own implementation, including a few common operations, of course, more operations need to be done by ourselves. Because the operation to delete a node in a binary lookup tree is complicated, let me explain here in detail.

    • Delete node analysis in binary search tree

To delete an element in a binary lookup tree, you first need to locate the node that contains the element and its parent node. Assume that current points to the node in the binary lookup tree that contains the element, and that the parent points to the parents of the current node, the current node may be the left child of the parent node, or it may be the right child. Here are two things to consider:

    1. The current node has no left child, so you only need to connect the patent node to the right child of the current node.
    2. The current node has a left child, assuming that rightmost points to the node that contains the largest element in the left subtree of the current node, and Parentofrightmost points to the parent node of the rightmost node. Instead, replace the element values in the current node with the element values in the rightmost node, connect the Parentofrightmost node to the left child of the rightmost node, and then delete the rightmost node.
    Binary Search Tree Delete node public boolean delete (E e) {treenode<e> parent = null;        treenode<e> current = root; Locate the node where you want to delete while (current! = null) {if (E.compareto (current.element) < 0) {Paren                t = current;            current = Current.left;                } else if (E.compareto (current.element) > 0) {parent = current;            current = Current.right;            } else {break;        }}//did not find the node to delete if (current = = null) {return false; }//Consider the first case if (current.left = = null) {if (parent = = NULL) {root = Current.righ            T                } else {if (E.compareto (parent.element) < 0) {parent.left = Current.right;                } else {parent.right = Current.right; }}} else {//Consider the second case treenode<e>Parentofrightmost = current;            treenode<e> rightmost = Current.left;                Locate the largest element node in the left Dial hand tree while (rightmost.right! = null) {parentofrightmost = rightmost;            rightmost = Rightmost.right;            }//Replace current.element = rightmost.element; Parentofrightmost and rightmost left child connected if (parentofrightmost.right = = rightmost) {Parentofrightmos            T.right = Rightmost.left;            } else {parentofrightmost.left = Rightmost.left;    }} return true; }

Balanced two-pronged tree

The balanced binary tree, also known as the AVL tree, is either an empty tree or a two-prong tree with the following properties: Its Saozi right subtree is a balanced binary tree, and the absolute value of the depth of the Saozi right subtree does not exceed 1.


Balanced two-pronged tree

AVL tree is the first invented self-balanced binary search tree algorithm. The maximum height difference for the two son subtree of any node in AVL is 1, so it is also called a height-balanced tree, and the maximum depth of the AVL tree for n nodes is about 1.44log2n. Find, insert, and delete are O (log n) in both the average and worst case scenarios. Additions and deletions may require one or more tree rotations to rebalance the tree.

Red and black Trees

A red-black tree is a balanced binary tree that ensures that in the worst case the event complexity of the basic dynamic set operation is O (log n). The difference between the red and black tree and the balanced binary tree is as follows: (1) The red and black trees give up the pursuit of complete balance, the pursuit of general balance, in the balance with the time complexity of the binary tree is not small, to ensure that the maximum of three times each insert can be rotated to achieve a balance, the implementation is more simple. (2) Balanced binary tree pursuit of absolute balance, the conditions are more stringent, to achieve a more troublesome, each time after inserting new nodes need to rotate the number of unpredictable. Click to view more

Iv. Fig.
    • Brief introduction

Graph is a more complex data structure of linear table and tree, in linear table, there is only linear relationship between data elements, in the tree structure, there is a clear hierarchical relationship between the data elements, and in the graph structure, the relationship between nodes can be arbitrary, the graph of any two data elements may be related to each other. The application of graphs is quite extensive, especially in recent years, and has infiltrated into other branches such as linguistics, logic, physics, Chemistry, Telecommunication engineering, Computer science and mathematics.

    • Related reading

Because the content of this part of the figure is still more, here is not detailed introduction, there is a need to search their own relevant information.

(1) "Introduction to the Map" by Baidu Encyclopedia
(2) Graph of data structure (storage structure, traversal)

V. Summary

Here, about the common data structure of the finishing of the end, intermittent probably spent two days to write, in the process of summing up, through access to relevant information, combined with book content, Harvest is very large, in the next blog will introduce common data structure and algorithm collation summary (under) algorithm, welcome attention.



Dust Language Temptations
Links: http://www.jianshu.com/p/230e6fde9c75
Source: Pinterest
Copyright belongs to the author. Commercial reprint please contact the author for authorization, non-commercial reprint please specify the source.

"Turn" data structure and algorithm (above)

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.