Sorting algorithm: selection sort (direct selection sort, heap sort)

Friends and guys, we meet again. In this issue, I will explain to you some relevant knowledge points about sorting algorithms . If you have some inspiration after reading it, please leave your three links. I wish you all the best thoughts It’s done!

C language column: C language: from entry to proficiency

Data Structure Column: Data Structure

Personal homepage: stackY、

 

Table of contents

Foreword:

1.Select sort 

1.1 Basic idea

1.2 Direct selection sorting

:: Algorithm ideas 

:: Complete code of direct sorting algorithm

1.3 Characteristics of direct selection sorting algorithm 

 2. Heap sort

:: Complete code of heap sort algorithm

 2.1 Characteristics of heap sort algorithm

 3. Algorithm efficiency comparison


Foreword:

To undertake this article: Sorting Algorithms: Insertion Sorting (Direct Insertion Sorting, Hill Sorting) In this article we have learned about the types of sorting algorithms and how to implement insertion sorting, so in this issue of the article, we will come again Learn a new sorting algorithm: selection sort.

1.Select sort 

1.1 Basic idea

Select the smallest (or largest) element from the data elements to be sorted each time , and store it at the beginning of the sequence until all the data elements to be sorted are exhausted.

1.2 Direct selection sorting

① Select the data element with the largest (smallest) key code in the element set array[i]--array[n-1]

②If it is not the last (first) element in this group of elements, exchange it with the last (first) element in this group of elements

③In the remaining array[i]--array[n-2] (array[i+1]--array[n-1]) set, repeat the above steps until there is 1 element left in the set

 In short (ascending order) is to select the smallest one from all the data and put it in the front position to complete the sorting.

 This sorting method can only select one data at a time, and we can improve on the basis again. We can select and sort two data at a time: set two subscripts, the front subscript finds the smallest number from front to back, and the latter subscript Find the largest number from back to front and sort them in order. This method is obviously better than the previous method, so let's start with this algorithm:

:: Algorithm ideas 

First of all, we need two starting subscripts, one at the beginning of the data and one at the end of the data, and then two more subscripts are needed to record the maximum and minimum values, and the maximum and minimum values ​​will be recorded The initial setting of the subscript is the first to lose a game, and then start a comparison. The subscript at the beginning of the data traverses from the beginning to compare with the minimum value and then finds the minimum value. The subscript at the end of the data starts from Start traversing backwards and forwards to compare the maximum value to find the maximum value, then exchange the minimum value with the first value at the beginning, and exchange the maximum value with the value at the end, so that the minimum value is ranked at the front, and the The maximum value is sorted to the end, and then the interval is narrowed, the subscript ++ at the beginning becomes a new beginning, the subscript at the end -- becomes a new end, and then a new round of comparison is performed, when the beginning and subscript and The sorting ends when the last subscripts overlap.

Code demo:

 

void Swap1(int* p1, int* p2)
{
	int tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}

//选择排序
//排升序
void SelectSort1(int* a, int n)
{
	int begin = 0, end = n - 1;

	while (begin < end)
	{
		//一趟选择排序
	//先将第一个值设置为最大值和最小值
		int mini = begin, maxi = begin;
		//遍历整个数据
		for (int i = begin; i <= end; i++)
		{
			//找到最小值的下标
			if (a[i] < a[mini])
			{
				mini = i;
			}
			//找到最大值的下标
			if (a[i] > a[maxi])
			{
				maxi = i;
			}
		}
		//将最小值放到开头
		Swap1(&a[begin], &a[mini]);

		//将最大值放到末尾
		Swap1(&a[end], &a[maxi]);
		//缩小区间
		begin++;
		end--;
	}
}

We can use a set of data to demonstrate: 9, 8, 5, 6, 3, 2, 1, 4, 7, 0

 It can be found that the result of this sorting is not the result we want. So what is the reason? We can find the problem through debugging:

Therefore, in order to prevent the special situation that begin and maxi overlap, after the first exchange is completed, the position of mini is the position of the maximum value at this time, so directly assign mini to maxi to complete the correct exchange.

Optimized code: 

:: Complete code of direct sorting algorithm

 

void Swap1(int* p1, int* p2)
{
	int tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}

//选择排序
//排升序
void SelectSort1(int* a, int n)
{
	int begin = 0, end = n - 1;

	while (begin < end)
	{
		//一趟选择排序
	//先将第一个值设置为最大值和最小值
		int mini = begin, maxi = begin;
		//遍历整个数据
		for (int i = begin; i <= end; i++)
		{
			//找到最小值的下标
			if (a[i] < a[mini])
			{
				mini = i;
			}
			//找到最大值的下标
			if (a[i] > a[maxi])
			{
				maxi = i;
			}
		}
		//将最小值放到开头
		Swap1(&a[begin], &a[mini]);

		//如果begin和maxi重叠,需要进行修正
		if (begin == maxi)
		{
			maxi = mini;
		}

		//将最大值放到末尾
		Swap1(&a[end], &a[maxi]);
		//缩小区间
		begin++;
		end--;
	}
}

1.3 Characteristics of direct selection sorting algorithm 

Summary of features of direct selection sort:

1. Direct selection and sorting thinking is very easy to understand, but the efficiency is not very good. rarely used in practice

2. Time complexity: O(N^2)

3. Space complexity: O(1)

4. Stability: unstable

 2. Heap sort

Heap sorting has been introduced in previous articles, so let’s get started here. If you don’t understand anything, you can read the previous article: Sorting algorithm: heap sorting

We know that the best way to sort the heap is to adjust the heap downwards. The points to pay attention to when building the heap are: to build a small heap in descending order, and to build a large heap in ascending order. The premise of using the downward adjustment algorithm is the result of downward adjustment. Below the point there must be a heap.

:: Complete code of heap sort algorithm

//交换函数
void Swap(int* p1, int* p2)
{
	int tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}

//向下调整
void AdjustDown(int* a, int n, int parent)
{
	//假设左孩子为左右孩子中最小的节点
	int child = parent * 2 + 1;

	while (child < n)  //当交换到最后一个孩子节点就停止
	{
		if (child + 1 < n  //判断是否存在右孩子
			&& a[child + 1] > a[child]) //判断假设的左孩子是否为最小的孩子
		{
			child++;   //若不符合就转化为右孩子
		}
		//判断孩子和父亲的大小关系
		if (a[child] > a[parent])
		{
			Swap(&a[child], &a[parent]);
			//更新父亲和孩子节点
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break;
		}
	}
}

//O(N * logN)
void HeapSort(int* a, int n)
{
	//建堆--向下调整算法建堆
	//时间复杂度为O(N)
	for (int i = ((n - 1) - 1) / 2; i >= 0; --i)
	{//       这里的n-1表示最后一个叶子节点
		//       最后一个叶子节点的父亲就是:
		//           (n-1)-1/2;
		AdjustDown(a, n, i);
	}

	//O(N * logN)
	int end = n - 1;
	while (end > 0)
	{
		//交换堆顶和最后一个数据的位置
		Swap(&a[0], &a[end]);
		//向下调整,找次小的
		AdjustDown(a, end, 0);
		end--;
	}
}

 2.1 Characteristics of heap sort algorithm

1. Heap sort uses a heap to select numbers, which is much more efficient.

2. Time complexity: O(N*logN)

3. Space complexity: O(1)

4. Stability: unstable

 3. Algorithm efficiency comparison

To compare the speed of the algorithm, we still use this piece of code to detect:

// 测试排序的性能对比
void TestOP()
{
	srand(time(0));
	const int N = 100000;
	int* a1 = (int*)malloc(sizeof(int) * N);
	int* a2 = (int*)malloc(sizeof(int) * N);

	for (int i = 0; i < N; ++i)
	{
		a1[i] = rand();
		a2[i] = a1[i];
	}

	int begin1 = clock();
	SelectSort1(a1, N);
	int end1 = clock();


	int begin2 = clock();
	HeapSort(a2, N);
	int end2 = clock();

	

	printf("SelectSort1:%d\n", end1 - begin1);
	printf("HeapSort:%d\n", end2 - begin2);

	free(a1);
	free(a2);
}

It can be seen that heap sorting is more than 100 times faster than direct selection sorting, so direct selection sorting is not often used in normal times, we only need to learn its ideas, but heap sorting is a better algorithm, we need to master it.

Friends and guys, the good times are always short, and this is the end of our sharing in this issue. Don’t forget to leave your precious trilogy after reading it. Thank you for your support! 

Guess you like

Origin blog.csdn.net/Yikefore/article/details/132677666