heap | data structure

Tree

concept and structure

A tree is a non-linear data structure, which is a set of hierarchical relationships composed of n (n>=0) finite nodes. It is called a tree because it looks like an upside-down tree, which means it has the roots pointing up and the leaves pointing down.
There is a special node called the root node. The root node has no predecessor nodes
. Except the root node, the other nodes are divided into M (M>0) disjoint sets T1, T2, ..., Tm, where Each set Ti (1<= i <= m) is a subtree similar in structure to a tree. The root node of each subtree has one and only one predecessor, and can have zero or more successors.
Therefore, the tree is defined recursively.

insert image description here
Note: In the tree structure, there can be no intersection between subtrees, otherwise it is not a tree structure

The tree structure must be strictly required for the relationship of each node, which can be understood through the human blood relationship that we are familiar with
insert image description here

Degree of a node: The number of subtrees contained in a node is called the degree of the node; As shown in the figure above: A is a 6-leaf
node or terminal node: a node with a degree of 0 is called a leaf node; As shown in the figure above: B, C, Nodes such as H, I, etc. are leaf nodes
Non-terminal nodes or branch nodes: nodes whose degree is not 0; As shown in the above figure: nodes such as D, E, F, G... are branch
nodes node, then this node is called the parent node of its child node; as shown in the figure above: A is the parent node of B child node
or child node: the root node of the subtree contained in a node is called the child node of the node; as shown in the figure above: B It is a child node of A
Brother node: Nodes with the same parent node are called sibling nodes; As shown in the figure above: B and C are the
degree of the sibling node tree: in a tree, the degree of the largest node is called the degree of the tree; as above Figure: The level of the tree is 6
nodes: starting from the definition of the root, the root is the first level, the child nodes of the root are the second level, and so on; the
height or depth of the tree: the maximum level of nodes in the tree; as above Figure: The height of the tree is 4 Cousin nodes: the nodes whose parents
are on the same layer are cousins;
Figure: A is the ancestor of all nodes. Descendants
: Any node in the subtree rooted at a node is called the descendant of the node. As shown above: all nodes are descendants of A
Forest: A collection of m (m>0) disjoint trees is called a forest;

You can draw a tree analysis, and you have an intuitive understanding of the tree structure. However, in the computer world, tree implementation does not store data in such an intuitive way. Data can be managed with a container. The more common containers in data structures are arrays and linked list structures. Each has its own advantages. Data management can achieve certain spatial advantages.

binary tree

Concept: A binary tree is a finite set of nodes that:
or is empty. It consists of a root node plus two binary trees called left subtree and right subtree.
There is no node with degree greater than 2 in a binary tree. The subtrees of a binary tree are divided into left and right, and the order cannot be reversed, so a binary tree is an ordered tree.

insert image description here
There are special binary trees, full binary trees , and complete binary trees . these two trees

  1. Full binary tree: a binary tree, if the number of nodes in each layer reaches the maximum value, then this binary tree is a full binary tree. That is to say, if a binary tree has K layers and the total number of nodes is 2^k-1, then it is a full binary tree.
  2. Complete binary tree: A complete binary tree is a very efficient data structure, and a complete binary tree is derived from a full binary tree. For a binary tree with a depth of K and n nodes, it is called a complete binary tree if and only if each node has a one-to-one correspondence with the nodes numbered from 1 to n in the full binary tree with a depth of K. It should be noted that a full binary tree is a special kind of complete binary tree.

In the tree structure, the relationship diagram is tree->binary tree->complete binary tree->full binary tree. This is followed by the specialization of the structure. Among them, the number of leaf nodes of any binary number is one more than the number of nodes with degree 2. It is also possible to calculate the depth of a full binary tree based on the number of nodes (the root node is 1). The full binary tree node is n, and the depth is log with base 2 and n+1 as logarithm. If the root node is 1, the number of i-th layer nodes is 2 (i-1) . If the depth is k, the total number of nodes is 2 k -1.

Binary tree storage

Binary trees can generally be stored using two structures, a sequential structure and a chain structure.

  1. Sequential storage Sequential structure storage is to use arrays for storage. Generally, arrays are only suitable for representing complete binary trees, because not complete binary trees will waste space. In reality, only the heap will be stored in an array, and we will specifically explain the heap in the following chapters. Binary tree sequential storage is physically an array and logically a binary tree.

Ordinary binary trees are not suitable for storage in arrays, because there may be a lot of wasted space. The complete binary tree is more suitable for sequential structure storage. In reality, we usually store the heap (a binary tree) in an array of sequential structures. It should be noted that the heap here and the heap in the virtual process address space of the operating system are two different things. One is the data structure, and the other is the management in the operating system. A region of memory is segmented.
insert image description here

  1. Linked storage
    The linked storage structure of a binary tree means that a linked list is used to represent a binary tree, that is, a link is used to indicate the logical relationship of elements. The usual method is that each node in the linked list is composed of three fields, the data field and the left and right pointer fields, and the left and right pointers are used to give the storage addresses of the link points where the left child and right child of the node are located.

insert image description here

heap

All its elements are stored in a one-dimensional array in the order of a complete binary tree. The heap with the largest root node is called the largest heap or large root heap, and the heap with the smallest root node is called the smallest heap or small root heap.

insert image description here

A large heap means that the parent node of the array is larger than the child node, and a small heap means that the parent node is smaller than the child node.
Parent node and child node relationship

  1. If i>0, the parent number of the node at i position: (i-1)/2; i=0, i is the root node number, no parent node
  2. If 2i+1<n, left child number: 2i+1, 2i+1>=n otherwise there is no left child
  3. If 2i+2<n, the right child number: 2i+2, 2i+2>=n otherwise there is no right child

In a complete binary tree, if the right child exists, the left child must exist.

heap creation

Although the bottom layer of the heap is an array, the array is not necessarily a heap. Therefore, when creating a heap, you also need to pay attention to whether it is a large heap or a small heap. So the creation of the heap also needs to implement a heap algorithm. The underlying algorithm of a heap can be implemented by adding and deleting arrays. If you insert data, you need to compare it from the back to the front. Through the graphic is to adjust from bottom to top, that is, to adjust the algorithm upward. After the data is tail-inserted, the original data pile needs to be kept and compared. Therefore, it is necessary to compare sequentially from the back to the front, but when comparing, a large pile needs a root node to compare twice when the left and right children exist. Downward adjustment requires data comparison in sequence. When comparing data, you need to know the largest number of children among the children, and then compare the parent nodes. Make an exchange. You can use two heap building ideas, which can be analyzed from the time complexity.
insert image description here
Through calculation, we can know that the time complexity of adjusting the heap downward is O(n), and the time complexity of adjusting upward is O(n+nlogk). Therefore, when building the heap, we choose to adjust the heap building algorithm downward. However, the upward adjustment algorithm has to be used when inserting heap data.

downward adjustment of thought

Compare the value of the parent node and the value of the child node. The value of the parent node can be judged according to the type of the actual heap. When implementing, you need to compare the left and right child values. Then perform an exchange according to the heap building requirements.

void AdjustDown(HPDataType* a, int n, int parent)
{
    
    
	int child = parent * 2 + 1;//假设左孩子大
	
	while (child <n)
	{
    
    
		//选取大孩子,防止越界
		if (a[child + 1] > a[child] && child + 1 < n)
		{
    
    
			++child;
		}
		//小堆实现
		
		if (a[parent] > a[child] )
		{
    
    
			swap(&a[child], &a[parent]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
    
    
			break;
		}
	}
	
}

upward adjustment of thought

This is the opposite of the downward adjustment algorithm implementation. But the logic is much the same.

void AdjustUp(HPDataType*arr,HPDataType child)
{
    
    
	int parent = (child - 1) / 2;
	while (child > 0)
	{
    
    
		if (arr[parent] < arr[child])
		{
    
    
			swap(&arr[parent],&arr[child]);
			child = parent;
			parent = (child - 1) / 2;
		}
		else
		{
    
    
			break;
		}
	}

}

Guess you like

Origin blog.csdn.net/github_73587650/article/details/129813649