[C Language] A big mess of sorting - Meow Meow’s Growth Story

Baozi, don’t you like it? Don't you want to comment? Don't you want to collect it?

Finally, follow me, follow me, follow me, you will see more interesting blogs! ! !

Meow meow meow, you are really important to me.


Preface

Little Meow Meow’s class has begun. Today we will learn seven common sorting methods, oh yeah! ! !

Meow meow, please do your best today!

Come on, don’t yell, here’s the guide:

Table of contents

Preface

An overview of the eight classic rankings

direct insertion sort

Hill sort

selection sort

Heap sort

Bubble Sort

Quick sort (quick sort)

merge sort

Summarize


┗|`O′|┛ Wow~~, how could you forget radix sorting? Add to add:

An overview of the eight classic rankings

The eight major sorting algorithms refer to the eight common classic sorting algorithms, which are bubble sort, selection sort, insertion sort, Hill sort, merge sort, quick sort, heap sort and radix sort.

  1. Bubble sort: Compare adjacent elements, swap them if they are in the wrong order, and repeat this process until the entire array is sorted.
  2. Selection sort: Select the smallest (or largest) element from the array to be sorted each time and place it at the end of the sorted array until the entire array is sorted.
  3. Insertion sort: Traverse the array and insert the current element into the appropriate position in the sorted sub-array until the entire array is sorted.
  4. Hill sorting: Group the array by setting the interval, perform insertion sort on each group, and gradually reduce the interval until the last insertion sort is performed when the interval is 1.
  5. Merge sort: Using the idea of ​​divide and conquer, the array to be sorted is divided into smaller sub-arrays, then the sub-arrays are sorted recursively, and the sorted sub-arrays are merged into a larger ordered array.
  6. Quick sort: Select a benchmark element, divide the array into left and right parts, the left part is smaller than the benchmark element, and the right part is larger than the benchmark element, and recursively perform quick sorting on the left and right parts.
  7. Heap sort: Construct the array to be sorted into a large top heap, then swap the top element of the heap with the last element and realign the heap. Repeat this process until the entire array is sorted.
  8. Radix sort: Sort according to the value of each bit of the element, sort by the low bit first, then sort by the high bit, until all bits are sorted.

direct insertion sort

The sorting rules for direct insertion are as shown in the figure:

Substitute end and tmp into it and think about it. The first 3 is regarded as the starting point and the position is arranged as end. Then tmp is 44, 44>3, tmp>end, so the positions are not exchanged, and the position is arranged, end+ 1,tmp+1. Then in the second comparison, end is 44, tmp is 38, end>tmp, the positions are swapped, and 38 is ranked in front of 44. Then in the third comparison, 5 is smaller than 44, smaller than 38, and ranked ahead of 38. By analogy, the array is sorted in a loop.

void InSert(int* a, int n)
{
	for (int i = 1; i < n; i++)
	{
		int end = i - 1;
		int tmp = a[i];
		while (end >= 0)
		{
			if (tmp < a[end])
			{
				a[end + 1] = a[end];
				end--;
			}
			else
			{
				break;
			}
		}
		a[end + 1] = tmp;
	}
}

Hill sort

Hill sorting is an upgraded version of direct insertion sorting. The array is first grouped regularly into multiple groups, and then each group is subjected to direct insertion sorting. After each group is sorted, it is much easier to perform direct insertion sorting again, and it can be sorted quickly, which greatly improves the efficiency of sorting.

Divide them into three groups: green, blue, and red, and perform direct insertion sorting respectively.

void InsertSort(int* a, int n) 
{
	int gap = 3;
	for (j=0;j<gap;j++)
	{
		for (int i = j; i < n-gap; i+=gap)
		{
			int end = i;
			int tmp = a[i+gap];
			while (end >= 0)
			{
				if (tmp < a[end])
				{
					a[end + gap] = a[end];
					end-=gap;
				}
				else
				{
					break;
				}
			}
			a[end + gap] = tmp;
		}
	}
	

}
void InsertSort(int* a, int n) 
{
	int gap = n;

	int j = 0;
	while (gap > 1)
	{
		gap = gap / 2;
		for (j = 0; j < gap; j++)
		{
			for (int i = j; i < n - gap; i += gap)
			{
				int end = i;
				int tmp = a[i + gap];
				while (end >= 0)
				{
					if (tmp < a[end])
					{
						a[end + gap] = a[end];
						end -= gap;
					}
					else
					{
						break;
					}
				}
				a[end + gap] = tmp;
			}
		}
	}

}


selection sort

Selection sorting is very intuitive. We first select 3 as the ordered array, then select the smallest number from the array behind 3, and compare it with 3. Whoever is smaller will stand in front. 2 is smaller than 3, so 2 and 3 exchange places. Push back one by one and form an ordered array.

Meow, it's hard to comment. This is a simple version of one point movement, and what we usually use is the difficult version of two points. Meow, it's hard to understand. Meow, it took me a long time to understand it. Meow. So let’s get started! Cat team, go, go, go!

Movement of two points (it is recommended to combine the code and follow along, it will feel right!):

//这是两个点的移动
void SelectSort(int* a, int n)
{
	int left = 0, right = n - 1;
	while (left < right)
	{
		int mini = left, maxi = left;
		for (int i = left + 1; i <= right; i++)
		{
			if (a[i] < a[mini])
			{
				mini = i;
			}

			if (a[i] > a[maxi])
			{
				maxi = i;
			}
		}

		Swap(&a[left], &a[mini]);
		// 如果left和maxi重叠,交换后修正一下
		if (left == maxi)
		{
			maxi = mini;
		}

		Swap(&a[right], &a[maxi]);

		++left;
		--right;
	}
}

Heap sort

It is arranged in a hierarchical manner from bottom to top, from large to small. Build large piles in ascending order and small piles in descending order.

// 左右子树都是大堆/小堆
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;
		}
	}
}

void HeapSort(int* a, int n)
{
	// 建堆 -- 向下调整建堆 -- O(N)
	for (int i = (n - 1 - 1) / 2; i >= 0; --i)
	{
		AdjustDown(a, n, i);
	}

	// 自己先实现 -- O(N*logN)
	int end = n - 1;
	while (end > 0)
	{
		Swap(&a[end], &a[0]);
		AdjustDown(a, end, 0);

		--end;
	}
}

Bubble Sort

Bubble sorting is easy to understand and has great teaching significance. To put it simply, start from one end, swap them two by two, put the smaller one in front and that’s it!

void BubbleSort(int* a, int n)
{
	for (int j = 0; j < n; j++)
	{
		bool exchange = false;
		for (int i = 1; i < n - j; i++)
		{
			if (a[i - 1] > a[i])
			{
				Swap(&a[i - 1], &a[i]);
				exchange = true;
			}
		}

		if (exchange == false)
		{
			break;
		}
	}
}

Quick sort (quick sort)

There are many methods for quick sorting, such as the hoare method, the digging method, and the front and rear pointer method:

1.hoare method:

Speechless, as shown in the picture

int GetMidNumi(int* a, int left, int right)
{
	int mid = (left + right) / 2;
	if (a[left] < a[mid])
	{
		if (a[mid] < a[right])
		{
			return mid;
		}
		else if (a[left] > a[right])
		{
			return left;
		}
		else
		{
			return right;
		}
	}
	else // a[left] > a[mid]
	{
		if (a[mid] > a[right])
		{
			return mid;
		}
		else if (a[left] < a[right])
		{
			return left;
		}
		else
		{
			return right;
		}
	}
}
int PartSort1(int* a, int left, int right)
{
	// 三数取中
	int midi = GetMidNumi(a, left, right);
	if (midi != left)
		Swap(&a[midi], &a[left]);

	int keyi = left;
	while (left < right)
	{
		// 右边找小
		while (left < right && a[right] >= a[keyi])
			--right;

		// 左边找大
		while (left < right && a[left] <= a[keyi])
			++left;

		Swap(&a[left], &a[right]);
	}

	Swap(&a[keyi], &a[left]);
	keyi = left;

	return keyi;
}

Digging method:

int GetMidNumi(int* a, int left, int right)
{
	int mid = (left + right) / 2;
	if (a[left] < a[mid])
	{
		if (a[mid] < a[right])
		{
			return mid;
		}
		else if (a[left] > a[right])
		{
			return left;
		}
		else
		{
			return right;
		}
	}
	else // a[left] > a[mid]
	{
		if (a[mid] > a[right])
		{
			return mid;
		}
		else if (a[left] < a[right])
		{
			return left;
		}
		else
		{
			return right;
		}
	}
}
int PartSort2(int* a, int left, int right)
{
	// 三数取中
	int midi = GetMidNumi(a, left, right);
	if (midi != left)
		Swap(&a[midi], &a[left]);

	// 21:10继续
	int key = a[left];
	int hole = left;
	while (left < right)
	{
		// 右边找小
		while (left < right && a[right] >= key)
			--right;

		a[hole] = a[right];
		hole = right;

		// 左边找大
		while (left < right && a[left] <= key)
			++left;

		a[hole] = a[left];
		hole = left;
	}

	a[hole] = key;

	return hole;
}

Back and forth pointer method:

int GetMidNumi(int* a, int left, int right)
{
	int mid = (left + right) / 2;
	if (a[left] < a[mid])
	{
		if (a[mid] < a[right])
		{
			return mid;
		}
		else if (a[left] > a[right])
		{
			return left;
		}
		else
		{
			return right;
		}
	}
	else // a[left] > a[mid]
	{
		if (a[mid] > a[right])
		{
			return mid;
		}
		else if (a[left] < a[right])
		{
			return left;
		}
		else
		{
			return right;
		}
	}
}
int PartSort3(int* a, int left, int right)
{
	// 三数取中
	int midi = GetMidNumi(a, left, right);
	if (midi != left)
		Swap(&a[midi], &a[left]);

	int keyi = left;

	int prev = left;
	int cur = left + 1;
	while (cur <= right)
	{
		if (a[cur] < a[keyi] && ++prev != cur)
			Swap(&a[cur], &a[prev]);

		++cur;
	}

	Swap(&a[prev], &a[keyi]);
	keyi = prev;

	return keyi;
}

Merge sort (recursive):

int GetMidNumi(int* a, int left, int right)
{
	int mid = (left + right) / 2;
	if (a[left] < a[mid])
	{
		if (a[mid] < a[right])
		{
			return mid;
		}
		else if (a[left] > a[right])
		{
			return left;
		}
		else
		{
			return right;
		}
	}
	else // a[left] > a[mid]
	{
		if (a[mid] > a[right])
		{
			return mid;
		}
		else if (a[left] < a[right])
		{
			return left;
		}
		else
		{
			return right;
		}
	}
}
int PartSort3(int* a, int left, int right)
{
	// 三数取中
	int midi = GetMidNumi(a, left, right);
	if (midi != left)
		Swap(&a[midi], &a[left]);

	int keyi = left;

	int prev = left;
	int cur = left + 1;
	while (cur <= right)
	{
		if (a[cur] < a[keyi] && ++prev != cur)
			Swap(&a[cur], &a[prev]);

		++cur;
	}

	Swap(&a[prev], &a[keyi]);
	keyi = prev;

	return keyi;
}
void QuickSort(int* a, int left, int right)
{
	if (left >= right)
		return;

	int keyi = PartSort3(a, left, right);
	QuickSort(a, left, keyi - 1);
	QuickSort(a, keyi + 1, right);
}

Summarize

Crazy, crazy, how can I explain it clearly? There are a lot of vernacular texts, but pictures can make it clear. I can’t see it clearly, leave a message, meow meow duck, your understanding is my growth, sour Q meow.


Baozi, don’t you like it? Don't you want to comment? Don't you want to collect it?

Finally, follow me, follow me, follow me, you will see more interesting blogs! ! !

Meow meow meow, you are really important to me.

Guess you like

Origin blog.csdn.net/ormstq/article/details/133652053