Sorting - selection sort and heap sort


1. Selection sorting

Idea:
Use the first element of the array as min, and then traverse and compare it with other elements. If a number smaller than min is found, exchange it until the last element is reached. Then min the second element, traverse again, and continue until the last data
Flow chart:
Insert image description here
Code implementation:

//交换
void Swap(int* a,int* b) {
    
    
	int t = *a;
	*a = *b;
	*b = t;
}
//打印
void Print(int* arr, int n) {
    
    

	for (int i = 0;i < n; i++)
		printf("%d ", arr[i]);
}
//直接选择排序
void SelectSort(int* arr, int size) {
    
    

	for (int i = 0; i < size; i++)
	{
    
    
		int min = i;//从第一个开始
		//每次从i+1的位置开始就不会影响到前面的了
		for (int j = i+1; j < size; j++) {
    
    
		//比较
			if (arr[min] > arr[j])
				min =j;//记录下标
		}
		Swap(&arr[i], &arr[min]);//交换
	}
 }
int main() {
    
    
	int arr[] = {
    
     43152};
SelectSort(arr, sizeof(arr) / sizeof(arr[0]));
Print(arr, sizeof(arr) / sizeof(arr[0]));
	return 0;
}

Run result:
Insert image description here
Selection sort optimization:
We can set a min and a max, put the small ones on the left and the big ones on the left On the right, we set two more variables p and q that control the subscripts on the left and right, and it ends when they meet.
Flow chart:
Insert image description here
Special case: when the position of max is equal to p, we first exchange arr[p] and arr[min], but max points to the position p , but the value at position p has changed. At this time, we need to correct it and set max=min, so that we can successfully find the original value at position p
For example:< a i=6> Code implementation:
Insert image description here

//交换
void Swap(int* a,int* b) {
    
    
	int t = *a;
	*a = *b;
	*b = t;
}
//打印
void Print(int* arr, int n) {
    
    

	for (int i = 0;i < n; i++)
		printf("%d ", arr[i]);
}
//优化选择排序

void SelectSort1(int* arr, int size) {
    
    

	int p = 0, q = size-1;//p指向数组开头,q指向数组最后一个位置
	while (p < q) {
    
    //当错过或者相遇就结束
		int min = p, max = p;//迭代位置
		for (int i = p; i <= q; i++)
		{
    
    
			if (arr[min] > arr[i])//找到最小值
				min = i;
			if (arr[max] < arr[i])//找到最大值
				max = i;
		}
		Swap(&arr[min], &arr[p]);//交换
		if (max == p)//5 2 3 4 1//判断是否要纠正
			max = min;
		Swap(&arr[max], &arr[q]);//交换
		p++, q--;
	}
}
int main() {
    
    
	int arr[] = {
    
     4,3,1,5,2 };
		SelectSort1(arr, sizeof(arr) / sizeof(arr[0]));
	Print(arr, sizeof(arr) / sizeof(arr[0]));
	return 0;
}

operation result:
Insert image description here

2. Heap sort

heap:

Structural: a complete binary tree represented by an array;
Orderly: the key of any node is the maximum value (or minimum value) of all nodes in its subtree
"MaxHeap", also known as "Big Top Heap", that is, the maximum value of all fathers is greater than or equal to the child
"MinHeap", Also called "small top heap", that is, the minimum value of all fathers is less than or equal to the children

Small heap: The top data of the heap is the smallest, and all nodes are smaller than the left and right subtrees
Insert image description here

Large heap: The top data of the heap is the largest, and all nodes are larger than the left and right subtrees
Insert image description here
Use heap to implement sorting:
(1) Use the downward adjustment algorithm:
Prerequisite: The left and right subtrees must be small or large heaps
Function: Build a heap
For example :
Compare and select the left and right subtrees, and then compare with the root
Insert image description here
(2) Build a heap
When we want to implement ascending order, Through the downward adjustment method, we need to build a large pile
. The construction process: Because it is a complete binary tree, we can start from the last non-leaf node and end until there are no nodes.
For example:
Build a big pile
Insert image description here
Find the position of the left and right subtrees:

The subscript of the left subtree of the tree is equal to the subscript of the root *2+1, and the subscript of is equal to the subscript of the root *2+2

After is built, we can exchange the last element with the first element, and then adjust it downward without rebuilding the heap, and then exchange the first element with the penultimate element. And so on...
Why not build a small pile? If you build a small heap, the first root (minimum value) is the first element of the array. We cannot move it, then let the second element of the array be used as the root again, but in this case the order will be broken. The heap needs to be rebuilt again, which will increase the time complexity (you can build a small heap if you want to implement descending order)

Code:

//交换
void Swap(int* a,int* b) {
    
    
	int t = *a;
	*a = *b;
	*b = t;
}
//打印
void Print(int* arr, int n) {
    
    

	for (int i = 0;i < n; i++)
		printf("%d ", arr[i]);
}
//向下调整  大堆
void AdjustDwon(int *arr,int p,int size) {
    
    
	int q = p;//节点位置
	int z = q * 2 + 1;//节点左子树,z+1就是右子树的位置了
	while (z<size) {
    
    //当z大于数组长度时就说明该节点不存在左右子树
	//判断左右子树大小,后面是判断是否有右子树
		if (arr[z] <arr[z + 1]&&z+1<size)
			z += 1;
		if (arr[z] > arr[q]) {
    
    //判断是否比根大
			Swap(&arr[z], &arr[q]);
			q = z;
			z = q * 2 + 1;//迭代
		}
		else
			break;
	}
}
void  HeapSort(int* arr,  int size) {
    
    
	//建堆,size-1-1就是除2(求子树公式反过来用,最后减一是因为我们求的是下标)
	for (int i = (size - 1 - 1) / 2; i >= 0; i--) {
    
    
		AdjustDwon(arr, i, size);
	}
	int ned = size - 1;
//最后一个下标位置开始,和下标为0的元素交换,一直交换下去,并且交换一次就调整一次
	//当ned==1就证明排好了
	while (ned>0) {
    
    
		Swap(&arr[0], &arr[ned]);
		AdjustDwon(arr, 0, ned);//重新调整
		ned--;
	}
}

int main() {
    
    
	int arr[] = {
    
     4,3,1,5,2 };
	HeapSort(arr, sizeof(arr)/sizeof(arr[0]));
	Print(arr, sizeof(arr) / sizeof(arr[0]));
return 0}

operation result:
Insert image description here

3. Time complexity

Selection sort:
n-1,n-2…2,1
is an arithmetic sequence to find the sum of the first n-1 terms, Roughly speaking, it is n^2
, so the time complexity is O(n^2)

Heap sorting:
Heap building: O(n)
Insert image description here
The time complexity of downward adjustment is:
Suppose the height of the tree is h and the node of the tree is n, because n=2^h-1, then h=log(n-1) (based on 2)
So it is O (logn-1)
We have to make this downward adjustment n times (of course n will change during the process)
Then the total number of times n+nlogn
so the time complexity is O(n
logn)

4. Stability

stability:

Assume that there are multiple records with the same keyword in the record sequence to be sorted. If sorted, the relative order of these records remains unchanged, that is, in the original sequence, r[i]=r[4], and r [1] is before r[4], and in the sorted sequence, r[1] is still before r[4], then this sorting algorithm is called stable; otherwise it is called unstable.

Selection sort: unstable
For example:
Insert image description here
Heap sort: unstable
Insert image description here
The first 9 goes directly to Last

The above is what I shared. If there are any mistakes, please leave a message in the comment area.
Finally, thank you everyone for watching!

Guess you like

Origin blog.csdn.net/2302_79539362/article/details/134929772