Heap, heap sort, priority queue (C + + implementation)

Source: Internet
Author: User

So far, I know that there are two kinds of heap, one is memory, a common use is dynamic memory allocation (this is the case in C + +), the other is here to discuss a data structure.

A, heap

In the data structure of the heap is called binary heap, as the name suggests, we can think of it as a complete binary tree, each element has a maximum of 2 children, respectively, as the left child and the right child. Depending on the relationship between the element and its child, the heap can be divided into the largest heap and the smallest heap. The nature of the largest heap is the value of a parent whose value is not less than (if any), and correspondingly, the smallest heap is the value of a parent whose value is not greater than that of a child.

Similar to the representation of a two-fork tree, the heap can be stored sequentially or chained. I use sequential storage here. Chained storage involves pointer manipulation, which can be a bit of a hassle. Now that we are storing the array, we need to understand the subscript relationship between the parent node of the two-fork tree and the child node in order.

Parent (i) = I/2 Left (i) = 2i+1, right (i) = 2i+2

Note I is starting from 0, when I was counted from 1, the relationship was slightly different.

The two most common applications of the heap are heap sorting and priority queues, which are used in some algorithms, such as the minimum spanning tree algorithm. When working on a heap, such as inserting an element or deleting an element, we adjust the heap to ensure that the nature of the heap is not corrupted after the change, that the data structure is still a heap. How to keep the nature of the heap.

Take the maximum heap as an example, assuming that the heap is stored in array arrays, the subscript of the element to be adjusted is I and its left and right subtree are the largest heap. Then we do the following:

1. Find the maximum value in Array[i] and Array[left (i)], array[right (i)] (if all exists), mark it as largest, if Array[i is the maximum, then the subtree with its root is already the largest heap, and the program ends. Otherwise, a child of array[i] is the maximum, then swap array[i with the child and go to step 2

2. The child node labeled largest is Array[i], and the subtree with its root may violate the nature of the heap, so perform step 1 on the subtree.

In the following function, I use Heap_type to indicate whether the heap is the largest heap or the smallest heap, and perform different operations accordingly.

Template<typename t> void Heapify (T *array, const int length, int i, Heap_type Type)
{
	if (I < length)
	{
		int extre_ele_index;
		Extre_ele_index = i;
		if (i*2+1 < length)//left child
		{
			if (type = = Max_heap)
			{
				if (Array[extre_ele_index) < array[i*2+1]) 
  extre_ele_index = i*2+1;
			} else{
				if (Array[extre_ele_index] > array[i*2+1])
					extre_ele_index = i*2+1;
			}
		}
		if (i*2+2 < length)/right child
		{
			if (type = = Max_heap)
			{
				if (Array[extre_ele_index] < array[i*2+2] )
					extre_ele_index = i*2+2;
			} else{
				if (Array[extre_ele_index] > array[i*2+2])
					extre_ele_index = i*2+2;
			}
		}
		if (Extre_ele_index!= i)
		{
				T extre_ele; 
				Extre_ele = Array[i];
				Array[i] = Array[extre_ele_index];
				Array[extre_ele_index] = Extre_ele;
				Heapify (array, length, extre_ele_index, type);}}

With the above subroutine, we can build a heap.

To treat the heap array as a complete binary tree, we need to start with the first non-leaf node of the complete binary tree, and then adjust the elements in the array to the first element of the array, which is the root of the complete binary tree. The reason for the adjustment from the first non-leaf node is that there is no child in the leaf node, so obviously it satisfies the nature of the heap and there is no need for adjustment.

Template<typename t> void Build_heap (T *array, const int length, Heap_type Type)
{
	int i;
	for (i = LENGTH/2 i >= 0; i.)
	{
		heapify (array, length, I, type);
	Note the ordinal number of the first non-leaf node
//Note the ordinal number of the left and right child of the element in the array (starting from 0).

So we can build a heap.

Second, heap sorting

Heap sort, as the name suggests, is based on the sort of heap. Because the nature of the heap (parents are not greater than or not less than the child's value), the first element of the heap (or the root of the complete binary tree) is always the most (large, small) value in the heap. Heap sorting is the use of this feature of the heap, the process can be described as follows:

1. Exchange the first element with the last element of the heap.

2. Reduce the size of the heap by one

3. The new value exchanged to the first position may violate the nature of the heap, so call heapify to keep the heap.

4. Repeat 1, 2, 3 until only 1 elements are left in the heap.

Since step one puts the first element in the position it should be placed in after it is sorted, one of the elements in the array is ordered every time it is executed, and the heap is naturally reduced by one size.

The sort_by indicates ascending or descending order.

Template<typename t> void Heap_sort (T *array, const int length, sort_by type)
{
	int i;
	T Extre_ele;
	if (type = = ASCEND)
		build_heap (array, length, max_heap);
	else
		build_heap (array, length, min_heap);//First build a heap to ensure that the first element is extreme. For

	(i = length-1 i >= 1;-i)//i subscript that represents the last element of a child array that has not been sorted out.
	{
		extre_ele= array[0];
		Array[0] = Array[i];
		Array[i] = Extre_ele;
		if (type = = ASCEND)
			heapify (array, I, 0, max_heap  );
		else
			heapify (array, I, 0, min_heap  );
	}

Third, priority queues

Priority queues are divided into the maximum priority queue and the minimum priority queue, respectively, based on the maximum heap and the minimum heap. As a queue, the priority queue must first have the team, the team, take the first, and the basic operation, the difference is to change the operation of the queue (out of the team), we have to carry out the above mentioned adjustments to ensure that the queue is still a heap.

The team operation and heapify Operation just the opposite, Heapify is adjusted from top to bottom, the team operation is to adjust from the bottom up, the new team elements placed in the appropriate position.

1. Because before the team, the queue is already a heap, so when the team, only to compare it with the parents, if the nature of the heap, then swap it with the parents, and then in the new position compared with the parents, until its relationship with parents to meet the nature of the heap.

template <typename t> void Priority_queue<t>::enqueue (T *ele) {if (Heap_size+1 > max_s	
		ize)//heap full, need to reassign {T *old_heap = heap;
		heap = new t[max_size*2];
		for (int i = 0; i < heap_size ++i) heap[i] = Old_heap[i];
		Delete old_heap;
	Old_heap = NULL;
	} Heap[heap_size] = *ele;
	int cur_index = heap_size; 
	int par_index = parent (heap_size);
	++heap_size;
			if (type = = Minimum_priority_queue) while (par_index >= 0 && Heap[cur_index] < Heap[par_index]) {
			T tmp = Heap[cur_index];
			Heap[cur_index] = Heap[par_index];
			Heap[par_index] = tmp;
			Cur_index = Par_index;
		Par_index = parent (Cur_index);
	else//the maximum priority queue.
			{while (par_index >= 0 && Heap[cur_index] > Heap[par_index]) {T tmp = Heap[cur_index];
			Heap[cur_index] = Heap[par_index];
			Heap[par_index] = tmp;
			Cur_index = Par_index;
		Par_index = parent (Cur_index); }
	}
}

The operations of the team and the heap sort are almost identical. Heap sort each iteration is to swap the first element with the last, and then to reduce the heap size by one, and finally invoke the heapify to preserve the nature of the heap. The team operation is to assign the last element to the first element, the heap size minus one, and call the heapify to preserve the nature of the heap. Haha, see no, the only difference is one is the swap, one is the assignment.

Template <typename t>
void priority_queue<t>::d equeue (T *ele)
{
	heap[0] = heap[heap_size-1];
	--heap_size;
	if (type = = Minimum_priority_queue)
		heapify (heap, heap_size, 0, min_heap);
	else
		heapify (heap, heap_size, 0, max_heap);
}

Priority queues The main operation is the above two, the other is simpler.

Program files in my resources, address links: Click on the Open link

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.