Pros and cons of the concept of sorting, as well as eight basic sorting algorithm to achieve the c language summary

1. Familiarize yourself with the sort of concepts: What is the sort of stability, internal and external sorting Sort of

Sort: Sort the so-called, it is to make a bunch of records, which follow a certain size or certain keywords, increasing or decreasing line up operations.


Stability: it is assumed that a sequence of records to be sorted, a plurality of records having the same key, if sorted, the relative order of these records remain unchanged, i.e. in the original sequence, r [i] = r [j] prior to, and r [i] before r [j], and in the sorted sequence, r [i] is still r [j], which is said sorting algorithm is stable; otherwise known as unstable.

Select the sort, quick sort, shell sort, heap sort is not a stable sorting algorithm

Bubble sort, insertion sort, merge sort algorithm to sort and radix sort are stable.

Internal Sort: All data elements on the sort memory.


External sorting: data can not be too many elements in memory, move data can not be sorted in the memory as required between the inner sorting process.


2. Insert familiar, Hill, select, discharge stack, bubbling, merge, count, following radix sorting:
Sort principle, code to achieve stability, time and space complexity, application scenarios

Insertion sort: direct insertion sort is a simple insertion sort, the basic idea is: the record to be sorted according to their size by one key value is inserted into an already sorted ordered sequence, until all records insert completion date, get a new ordered sequence.

Direct insertion sort characteristics are summarized:
1. The closer the ordered set of elements, the higher the direct insertion sort time efficiency

2. The time complexity: O (N ^ 2)

3. The space complexity: O (1), which is a stable sorting algorithm

4. Stability:

#include <stdio.h>
#include <stdlib.h>

void Printf(int array[],int size)
{
	for (int i = 0; i < size; ++i)
	{
		printf("%d ", array[i]);
	}
	printf("\n");
}

void Printf(int array[],int size)
{
	for (int i = 0; i < size; ++i)
	{
		printf("%d ", array[i]);
	}
	printf("\n");
}

void Insert_Sort(int *array, int size)
{
	int i, j;
	for (i = 1; i < size; ++i)	//待排序的
	{
		for (j = 0; j < i; ++j)	//排好序的
		{
			if (array[i] < array[j])
			{
				int tmp = array[i];	//需要排序的元素array[i]
				array[i] = array[j];	//向后搬移
				array[j] = tmp;		//填入记录的数据
			}
		}
	}
}

int main()
{
	int array[] = { 8,3,2,1,9,5,6,0,4,7 };
	int size = sizeof(array)/sizeof(array[0]);
	printf("原始数据:\n");
	Printf(array, size);

	//插入排序
	Insert_Sort(array, size);
	printf("插入排序后的数据:\n");
	Printf(array, size);

	system("pause");
	return 0;
}

Hill Sort: shell sort, also known as the narrow incremental method. Shell sort is the subject of pressing the recording packet in increments, the use of direct insertion sort each sorting algorithm; With increment is gradually reduced, more and more keywords each comprising, when reduced to an increment, the entire file is divided into just one group, the algorithm will terminate.

Hill sorting features summary:
1. Hill sorting is optimized for direct insertion sort.

2. When the gap> 1 is pre-sorted, the purpose is to get closer to an orderly array. When the gap == 1, the array has been close and orderly, so it will soon. In this way the whole, to achieve optimal results. We can achieve comparative performance tests.

3. The time complexity of sorting bad Hill calculation is required to derive, derived average time complexity: O (N ^ 1.3-N ^ 2)

4. Stability: Unstable 

#include <stdio.h>
#include <stdlib.h>

void Printf(int array[],int size)
{
	for (int i = 0; i < size; ++i)
	{
		printf("%d ", array[i]);
	}
	printf("\n");
}

void Shell_Sort(int *array, int size)
{
	int i, j;
	int gap;
	int tmp;
	for (gap = size / 2; gap > 0; gap = gap / 2)
	{
		for (i = gap; i < size; i++)
		{
			tmp = array[i];
			for (j = i - gap; (j >= 0) && (array[j] > tmp); j = j - gap)
			{
				array[j + gap] = array[j];
			}
			array[j + gap] = tmp;
		}
	}
}

int main()
{
	int array[] = { 8,3,2,1,9,5,6,0,4,7 };
	int size = sizeof(array)/sizeof(array[0]);
	printf("原始数据:\n");
	Printf(array, size);
        //希尔排序
	Shell_Sort(array, size);
	printf("希尔排序后的数据:\n");
	Printf(array, size);
	system("pause");
	return 0;
}

Selection sort: Each data element to be selected from the sorted minimum (or maximum) of an element stored in the starting position of the sequence, until all the data elements to be sorted drained.

Direct selection sort features summary: 
1. Direct Selection Sort think is very well understood, but the efficiency is not very good, in practice rarely used.

2. The time complexity: O (N ^ 2)

3. The space complexity: O (1)

4. Stability: Unstable

#include <stdio.h>
#include <stdlib.h>

void Printf(int array[],int size)
{
	for (int i = 0; i < size; ++i)
	{
		printf("%d ", array[i]);
	}
	printf("\n");
}

void Printf(int array[],int size)
{
	for (int i = 0; i < size; ++i)
	{
		printf("%d ", array[i]);
	}
	printf("\n");
}

void Select_Sort(int *array, int size)
{
	int i, j, k, tmp;
	for (i = 0; i < size; ++i)
	{
		for (j = i + 1; j < size; ++j)
		{
			//k = i;
			if (array[j] < array[i])
			{
				//k = j;
				tmp = array[j];
				array[j] = array[i];
				array[i] = tmp;
			}
		}
	}
}

int main()
{
	int array[] = { 8,3,2,1,9,5,6,0,4,7 };
	int size = sizeof(array)/sizeof(array[0]);
	printf("原始数据:\n");
	Printf(array, size);

	//选择排序
	Select_Sort(array, size);
	printf("选择排序后的数据:\n");
	Printf(array, size);

	system("pause");
	return 0;
}

HEAPSORT: heap sort (Heapsort) refers to a tree sort algorithm using a bulk (bulk) designed such a data structure, which is to select a sort. It is performed by selecting the data stack. Note that the row of piles to be built in ascending, descending row to build a small heap.

#include <stdio.h>
#include <stdlib.h>

void Printf(int array[],int size)
{
	for (int i = 0; i < size; ++i)
	{
		printf("%d ", array[i]);
	}
	printf("\n");
}

void Swap(int *a, int *b)
{
	int t = 0;
	t = *a;
	*a = *b;
	*b = t;
}
void AdjustDown(int *array, int i, int size)
{
	int child = i * 2 + 1;
	int tmp;
	for (tmp = array[i]; 2 * i + 1 < size; i = child) {
		child = 2 * i + 1; //注意数组下标是从0开始的,所以左孩子的求发不是2*i
		if (child != size - 1 && array[child + 1] > array[child])
			++child;                //找到最大的儿子节点
		if (tmp < array[child])
			array[i] = array[child];
		else
			break;
	}
	array[i] = tmp;
}

void Heap_Sort(int *array, int size)
{
	int i;
	for (i = (size - 2) / 2; i >= 0; i--)
	{
		AdjustDown(array, i, size);
	}
	for (i = size - 1; i > 0; --i)
	{
		Swap(&array[0], &array[i]);
		AdjustDown(array, 0, i);
	}
}

int main()
{
	int array[] = { 8,3,2,1,9,5,6,0,4,7 };
	int size = sizeof(array)/sizeof(array[0]);
	printf("原始数据:\n");
	Printf(array, size);

    //堆排序
	Heap_Sort(array, size);
	printf("堆排序后的数据:\n");
	Printf(array, size);

	system("pause");
	return 0;
}

Bubble sort: it repeatedly visited elements of the column to sort, in order to compare two adjacent elements, if their order (such as descending, the first letter from A to Z) errors they exchange took over. Working visit element is repeated until there is no need to swap adjacent elements, that is to say the element column has been sorted completed.

Characteristic bubble sort of summary:
1. The bubble sort is a very easy to understand ordering

2. The time complexity: O (N ^ 2)

3. The space complexity: O (1)

4. Stability:

#include <stdio.h>
#include <stdlib.h>

void Printf(int array[],int size)
{
	for (int i = 0; i < size; ++i)
	{
		printf("%d ", array[i]);
	}
	printf("\n");
}

void Printf(int array[],int size)
{
	for (int i = 0; i < size; ++i)
	{
		printf("%d ", array[i]);
	}
	printf("\n");
}

//冒泡排序(升序)
void Bubble_Sort(int *array, int size)
{
	int i = 0;
	int j = 0;
	for (int i = 0; i < size - 1; ++i)
	{
		for (j = 0; j < size - i - 1; ++j)
		{
			if (array[j] > array[j + 1])
			{
				int tmp = array[j];
				array[j] = array[j + 1];
				array[j + 1] = tmp;
			}
		}
	}
}

int main()
{
	int array[] = { 8,3,2,1,9,5,6,0,4,7 };
	int size = sizeof(array)/sizeof(array[0]);
	printf("原始数据:\n");
	Printf(array, size);

    //冒泡排序
	Bubble_Sort(array, size);
	printf("冒泡排序后的数据:\n");
	Printf(array, size);

	system("pause");
	return 0;
}

Merge sort: merge sort (MERGE-SORT) is based on an efficient operation of merge sorting algorithm, which is very typical application uses a divide and conquer (Divide and Conquer) a. The combined sequence has been ordered, fully ordered sequence; i.e., each first ordered sequence, and then ordered to make inter-segment sequences. If two merged into a sorted list ordered list, called way merge. 

Merge sort features summary: 
the disadvantage is the need to merge 1. O (N) space complexity, merge sort of thinking is more to solve the scheduling problem in the outer disk.

2. The time complexity: O (N * logN)

3. The space complexity: O (N)

4. Stability:
 

#include <stdio.h>
#include <stdlib.h>
#define N 10

void Printf(int array[],int size)
{
	for (int i = 0; i < size; ++i)
	{
		printf("%d ", array[i]);
	}
	printf("\n");
}

void merge(int arr[], int low, int mid, int high) 
{
	int i, k;
	int *tmp = (int *)malloc((high - low + 1) * sizeof(int));
	int left_low = low;
	int left_high = mid;
	int right_low = mid + 1;
	int right_high = high;

	for (k = 0; left_low <= left_high && right_low <= right_high; k++)
	{  
		if (arr[left_low] <= arr[right_low]) 
		{
			tmp[k] = arr[left_low++];
		}
		else 
		{
			tmp[k] = arr[right_low++];
		}
	}

	if (left_low <= left_high) 
	{ 
		for (i = left_low; i <= left_high; i++)
			tmp[k++] = arr[i];
	}

	if (right_low <= right_high) 
	{
		for (i = right_low; i <= right_high; i++)
			tmp[k++] = arr[i];
	}
	for (i = 0; i < high - low + 1; i++)
		arr[low + i] = tmp[i];
	free(tmp);
	return;
}

void Merge_Sort(int arr[], unsigned int first, unsigned int last) 
{
	int mid = 0;
	if (first < last) 
	{
		mid = (first + last) / 2; /* 注意防止溢出 */
		/*mid = first/2 + last/2;*/
		//mid = (first & last) + ((first ^ last) >> 1);
		Merge_Sort(arr, first, mid);
		Merge_Sort(arr, mid + 1, last);
		merge(arr, first, mid, last);
	}
	return;
}

int main()
{
	int array[] = { 8,3,2,1,9,5,6,0,4,7 };
	int size = sizeof(array)/sizeof(array[0]);
	printf("原始数据:\n");
	Printf(array, size);

    //归并排序
	Merge_Sort(array, 0, size - 1);
	printf("归并排序后的数据:\n");
	Printf(array, size);

    system("pause");
	return 0;
}

计数排序:计数排序的基本思想是对于给定的输入序列中的每一个元素x,确定该序列中值小于x的元素的个数(此处并非比较各元素的大小,而是通过对元素值的计数和计数值的累加来确定)。一旦有了这个信息,就可以将x直接存放到最终的输出序列的正确位置上。

如果用快速排序,该算法的复杂度为O(nlog^2n)。改用计数排序后,复杂度降为O(nlogn)

计数排序算法是一个稳定的排序算法

#include <stdio.h>
#include <stdlib.h>

void Printf(int array[],int size)
{
	for (int i = 0; i < size; ++i)
	{
		printf("%d ", array[i]);
	}
	printf("\n");
}

void Count_Sort(int *array, int size)
{
	int max = array[0];
	int min = array[0];
	for (int i = 0; i < size; i++)
	{
		if (array[i] > max)
			max = array[i];
		if (array[i] < min)
			min = array[i];
	}
	int range = max - min + 1;
	int *b = (int *)calloc(range, sizeof(int));
	for (int i = 0; i < size; i++)
	{
		b[array[i] - min] += 1;
	}
	int j = 0;	
	for (int i = 0; i < range; i++)
	{		
		while (b[i]--)
		{			
			array[j++] = i + min;		
		}	
	}	
	free(b);	
	b = NULL;
}

int main()
{
	int array[] = { 8,3,2,1,9,5,6,0,4,7 };
	int size = sizeof(array)/sizeof(array[0]);
	printf("原始数据:\n");
	Printf(array, size);
    Count_Sort(array, size);
	printf("计数排序后的数据:\n");
	Printf(array, size);
    system("pause");
	return 0;
}

基数排序:将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列。

时间效率 [1]  :设待排序列为n个记录,d个关键码,关键码的取值范围为radix,则进行链式基数排序的时间复杂度为O(d(n+radix)),其中,一趟分配时间复杂度为O(n),一趟收集时间复杂度为O(radix),共进行d趟分配和收集。 空间效率:需要2*radix个指向队列的辅助空间,以及用于静态链表的n个指针

#include <stdio.h>
#include <stdlib.h>
#define RADIX_10 10    
#define KEYNUM_31 10

void Printf(int array[],int size)
{
	for (int i = 0; i < size; ++i)
	{
		printf("%d ", array[i]);
	}
	printf("\n");
}

//基数排序(升序)
int GetNumInPos(int num, int pos)
{
	int temp = 1;
	for (int i = 0; i < pos - 1; i++)
		temp *= 10;
	return (num / temp) % 10;
}

void Radix_Sort(int *array, int size)
{
	int *array1[RADIX_10];
	for (int i = 0; i < 10; i++)
	{
		array1[i] = (int *)malloc(sizeof(int) * (size + 1));
		array1[i][0] = 0;
	}
	for (int pos = 1; pos <= KEYNUM_31; pos++)	
	{
		for (int i = 0; i < size; i++)		
		{
			int num = GetNumInPos(array[i], pos);
			int index = ++array1[num][0];
			array1[num][index] = array[i];
		}
		for (int i = 0, j = 0; i < RADIX_10; i++)	
		{
			for (int k = 1; k <= array1[i][0]; k++)
				array[j++] = array1[i][k];
			array1[i][0] = 0;	
		}
	}
}

int main()
{
	int array[] = { 8,3,2,1,9,5,6,0,4,7 };
	int size = sizeof(array)/sizeof(array[0]);
	printf("原始数据:\n");
	Printf(array, size);

    //基数排序
	Radix_Sort(array, size);
	printf("基数排序后的数据:\n");
	Printf(array, size);

	system("pause");
	return 0;
}

 

 

 

 


 

Guess you like

Origin blog.csdn.net/qq_43210641/article/details/89438674