直接插入排序、希尔排序、简单选择排序、堆排序、冒泡、快速排序代码实现

一、插入类排序:

1.直接插入排序

#include<stdio.h>
void print(int a[], int n)
{
	for (int i = 0; i < n; i++)
	{
		printf("%d ", a[i]);
	}
	printf("\n");
}

void insertSort(int a[], int n)
{
	int i, j;
	for ( i = 1; i < n; i++)
	{
		int key = a[i];
       //注意有等号则算法就不稳定了
		for ( j = i - 1; j >= 0 && a[j] > key; j--)
		{
			a[j + 1] = a[j];

		}
		a[j + 1] = key;
	}
}

int main()
{
	printf("插入排序:\n");
	int a[] = { 2,4,6,8,10,1,3,5,7,9 };
	print(a, sizeof(a) / sizeof(a[0]));
	insertSort(a, 10);
	print(a, sizeof(a) / sizeof(a[0]));

	return 0;

}

2.希尔排序

//方式一
#include<stdio.h>
void print(int a[], int n)
{
	for (int i = 0; i < n; i++)
	{
		printf("%d ", a[i]);
	}
	printf("\n");
}
void shellSort(int a[], int n)
{
	int gap = 3;
	int i, j;
	while (gap--)
	{
		for ( i = gap; i < n; i++)
		{
			int key = a[i];
			for ( j = i - gap; j >= 0 && a[j] > key; j-=gap)
			{
				a[j + gap] = a[j];
			}
			a[j + gap] = key;
		}
	}
}

int main()
{
	int a[] = { 2,4,6,8,10,1,3,5,7,9 };
	printf("希尔排序:\n");
	print(a, sizeof(a) / sizeof(a[0]));
	shellSort(a, 10);
	print(a, sizeof(a) / sizeof(a[0]));

	return 0;

}



//方式二(注意gap差别)

#include<stdio.h>
void print(int a[], int n)
{
	for (int i = 0; i < n; i++)
	{
		printf("%d ", a[i]);
	}
	printf("\n");
}

void shellSort(int a[], int n)

{
	int gap = n;
	while (gap>1)
	{
		   gap = gap / 3 + 1;
			int i, j;
				
		 //int i, j;
     //这里i++而不是i+gap原因是比较下一组(隔相同步数的为一组)
		for ( i = gap; i < n; i++)
		{
		 int key = a[i];
		    for (j = i - gap; j >= 0 && key < a[j]; j-=gap)
			{
				a[j + gap] = a[j];
			}
			a[j + gap] = key;
		}

			//gap--;
	}
	
}

int main()
{
	int a[] = { 1,3,5,7,9,2,4,6,8,10 };
	printf("希尔排序:\n");
	print(a, sizeof(a) / sizeof(a[0]));
	shellSort(a, sizeof(a) / sizeof(a[0]));
	print(a, sizeof(a) / sizeof(a[0]));
	return 0;

}

二、选择类排序

1.简单选择排序

//方式一--先排最大的,即将最大的排在后面
#include<stdio.h>
void print(int a[], int n)
{
	for (int i = 0; i < n; i++)
	{
		printf("%d ", a[i]);
	}
	printf("\n");
}

void selectSort(int a[], int n)
{
	int i, j;
	for ( i = 0; i < n - 1; i++)
	{
		//max为当前最大值下标,从下标为0到下标为max-1中找最大的,不断更新max
		int max = n-1-i;
		for (j = 0; j < n - 1 - i; j++)
		{
			if (a[j] > a[max])
			{
				max = j;
			}
		}
			
			if (max != j)
			{	
				int temp = a[j];
			    a[j] = a[max];
			    a[max] = temp;
			}
	}
}


//或用以下写法
/*  
void selectSort(int array[], int size)
{
	for (int i = 0; i < size - 1; ++i)
	{
		// 找最大元素的位置
		int maxPos = 0;
		for (int j = 1; j < size - i; j++)
		{
			if (array[j] > array[maxPos])
				maxPos = j;
		}

		if (maxPos != size - i - 1)
			swap(&array[maxPos], &array[size - i - 1]);
	}
}
*/




int main()
{
	int a[] = { 1,3,5,7,9,2,4,6,8,10 };
	printf("选择排序:\n");
	print(a, sizeof(a) / sizeof(a[0]));
	selectSort(a, sizeof(a) / sizeof(a[0]));
	print(a, sizeof(a) / sizeof(a[0]));
	return 0;
}



//方式二--先排最小的,即将最小的放在前面

#include<stdio.h>
void print(int a[], int n)
{
	for (int i = 0; i < n; i++)
	{
		printf("%d ", a[i]);
	}
	printf("\n");
}

void selectSort(int a[], int n)
{
	for (int i = 0; i < n - 1; i++)
	{
		int min = i;
		for (int j = i + 1; j < n; j++)
		{
			if (a[j] < a[min])
			{
				int temp = a[j];
				a[j] = a[min];
				a[min] = temp;
			}
		}
	}



}

int main()
{
	int a[] = { 1,3,5,7,9,2,4,6,8,10 };
	printf("选择排序:\n");
	print(a, sizeof(a) / sizeof(a[0]));
	selectSort(a, sizeof(a) / sizeof(a[0]));
	print(a, sizeof(a) / sizeof(a[0]));
	return 0;
}

//也可以不用每趟交换多次,找到后面最小的和前面元素交换一次就好,如下:
#include <iostream>
 
using namespace std;
 
void selectSort(int r[], int n){

    int i,index,j,temp;

    for(i=1; i<n; i++)//执行第i遍扫描操作
    {
        index = i;
        for(j=i+1; j<n; j++)//比较无序序列中的记录
        {
            if(r[index] > r[j])//记录序列中最小值的位置
            {
                index = j;
            }
        }
        if(index != i)//如果无序序列中第一个记录不是最小值,则进行交换
        {
            temp = r[index];
            r[index] = r[i];
            r[i] = temp;
        }
    }
}
 
int main()
{
    int r[]  = {0,5,6,8,4,9,6,74,65,123,94};
    int n = sizeof(r)/sizeof(r[0]);
    selectSort(r, n);
    for(int i=1; i<n; i++)
    {
        cout<<r[i]<<"  ";
    }
    return 0;
}


//方式三--在一趟中同时找最大和最小元素,将最大元素和最小元素进行交换
#include<stdio.h>
#include<assert.h>

void swap(int* a, int* b)
{
	int t = *a;
	*a = *b;
	*b = t;
}

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

	printf("\n");
}

void SelectSort(int* a, int n)
{
	assert(a);
	int begin = 0, end = n - 1;
	while (begin < end)
	{
		int min = begin, max = begin;
		for (int i = begin; i <= end; i++)
		{
			if (a[i] >= a[max])
				max = i;


			if (a[i] < a[min])
				min = i;
		}
		//最小的放在
		swap(&a[begin], &a[min]);
		//如果最大的位置在begin位置
		//说明min是和最大的交换位置
		//这个时候max的位置就发生了变换
		//max变到了min的位置
		//所以要更新max的位置
		if (begin == max)
			max = min;


		swap(&a[end], &a[max]);
		++begin;
		--end;


		//PrintArray(a, n);
	}
}


int main()
{
	int a[] = { 3, 4, 6, 1, 2, 8, 0, 5, 7 };
	SelectSort(a, sizeof(a) / sizeof(int));
	PrintArray(a, sizeof(a) / sizeof(int));
	return 0;
}

2.堆排序

#include<stdio.h>
void print(int a[], int n)
{
	for (int i = 0; i < n; i++)
	{
		printf("%d ", a[i]);
	}
	printf("\n");
}

//n表示父节点,size表示总节点个数
void adjustDown(int a[], int size, int n)
{
	//n相当于parent
	int child = n * 2 + 1;
	while (child < size)
	{

		//若要排降序,只要该为a[child+1]<a[child]及下面if的条件改为if(a[child]<a[n]) 大堆---升序
		if (child + 1 < size && a[child + 1] > a[child])
		{
			child = child + 1;
		}

		if (a[child] > a[n])
			{
				int temp = a[child];
				a[child] = a[n];
				a[n] = temp;
				n = child;
			    child = child * 2 + 1;
			}
		else
		{
			return;
		}

	}
}

	void heapSort(int a[], int n)
	{
		//建堆
		for (int i = (n - 2) / 2; i >= 0; i--)
		{
			adjustDown(a, n, i);
		}

		//利用堆删除思想排序
		int end = n - 1;
		while (end)
		{
			int temp = a[0];
			a[0] = a[end];
			a[end] = temp;
			
			//heapSort(a, end);
			//上一次end的下标刚好是下一次要排的元素个数
			adjustDown(a, end, 0);
			end--;
		}

	}

	int main()
	{

		int a[] = { 1,3,5,7,9,2,4,6,8,10 };
		printf("堆排序:\n");
		print(a, sizeof(a) / sizeof(a[0]));
		heapSort(a, sizeof(a) / sizeof(a[0]));
		print(a, sizeof(a) / sizeof(a[0]));
		return 0;


	}

三、交换类排序

1.冒泡排序

#include<stdio.h>
void print(int a[], int n)
{
	for (int i = 0; i < n; i++)
	{
		printf("%d ", a[i]);
	}
	printf("\n");
}

void bubbleSort(int a[], int n)
{
	for (int i = 0; i < n - 1; i++)
	{
		int flag = 1;
		for (int j = 0; j < n - 1 - i; j++)
		{
			if (a[j + 1] < a[j])
			{
				int temp = a[j + 1];
				a[j + 1] = a[j];
				a[j] = temp;
				flag = 0;
			}
		}
		if (flag == 1)
		{
			break;
		}
	}
}

   int main()
   {
	   int a[] = { 2,4,6,8,10,1,3,5,7,9 };
	   printf("冒泡排序:\n");
	   print(a, sizeof(a) / sizeof(a[0]));
	   bubbleSort(a, sizeof(a) / sizeof(a[0]));
	   print(a, sizeof(a) / sizeof(a[0]));
	   return 0;
   }

2.快速排序

//有三种方式取基准值,分别是PartSort1、PartSort2、PartSort3
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>

typedef int DataType;

// 动态
typedef struct Stack
{
	DataType* array;
	int capacity;
	int top;  // 标记栈顶---实际就是顺序表中的有效元素的个数
}Stack;


void StackInit(Stack* ps,int n)
{
	assert(ps);

	ps->array = (DataType*)malloc(sizeof(DataType) * n);
	if (NULL == ps->array)
		assert(0);

	ps->capacity = n;
	ps->top = 0;
}

void StackCheckCapacity(Stack* ps)
{
	assert(ps);
	if (ps->top == ps->capacity)
	{
		int newCapacity = (ps->capacity << 1);

		// 1. 开辟新空间
		DataType* temp = (DataType*)malloc(sizeof(DataType) * newCapacity);
		if (NULL == temp)
			assert(0);

		// 2. 拷贝元素
		memcpy(temp, ps->array, sizeof(DataType) * ps->capacity);

		// 3. 释放旧空间,使用新空间
		free(ps->array);
		ps->array = temp;
		ps->capacity = newCapacity;
	}
}


// 入栈---尾插
void StackPush(Stack* ps, DataType data)
{
	StackCheckCapacity(ps);

	ps->array[ps->top] = data;
	ps->top++;
}

// 检测栈是否为空,如果为空返回真,否则返回假
int StackEmpty(Stack* ps)
{
	assert(ps);
	return 0 == ps->top;
}

// 出栈
void StackPop(Stack* ps)
{
	if (StackEmpty(ps))
		return;

	ps->top--;
}

// 获取栈顶元素
DataType StackTop(Stack* ps)
{
	assert(ps);
	// return ps->array[--ps->top];  // 错误写法
	return ps->array[ps->top - 1];  // 正确的

}


void PrintArray(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 = *a;
	*a = *b;
	*b = t;
}

// 三数取中法,三个中取一个中间值

int GetMidIndex(int* a, int begin, int end)
{
	int mid = begin + ((end - begin) >> 1);
	if (a[begin] < a[mid])
	{
		if (a[mid] < a[end])
		{
			return mid;
		}
		else if (a[begin] > a[end])
		{
			return begin;
		}
		else
		{
			return end;
		}
	}
	else // begin >= mid
	{
		if (a[mid] > a[end])
		{
			return mid;
		}
		else if (a[begin] < a[end])
		{
			return begin;
		}
		else
		{
			return end;
		}
	}

}

int PartSort1(int* a, int begin, int end)
{
	int midindex = GetMidIndex(a, begin, end);
	swap(&a[begin], &a[midindex]);

	int key = a[begin];
	int start = begin;
	/*
	这里要从右边走,如果从左边走,
	可能最后一步,如果找不到大于
	基准值的,会导致begin == end
	即相遇,但是右边还没有走,所以
	这里的值一定大于基准值,最后交换
	就会出问题,所以一定要从右边走,
	即使最后一次找不到小于基准值的,
	会和左边相遇,而左边此时还没走,
	一定比基准值小,最后交换肯定没有问题
	*/
	while (begin < end)
	{
		// end 找小
		while (begin < end && a[end] >= key)
			--end;

		// begin找大
		while (begin < end && a[begin] <= key)
			++begin;

		swap(&a[begin], &a[end]);
	}
	//最后的交换一定要保证a[begin] < a[start], 所以要从右边走
	swap(&a[begin], &a[start]);
	return begin;
}

int PartSort2(int* a, int begin, int end)
{
	//begin是坑
	int key = a[begin];
	while (begin < end)
	{
		while (begin < end && a[end] >= key)
			--end;

		// end给begin这个坑,end就变成了新的坑。
		a[begin] = a[end];

		while (begin < end && a[begin] <= key)
			++begin;

		// end给begin这个坑,begin就变成了新的坑。
		a[end] = a[begin];
	}

	a[begin] = key;

	return begin;
}


/*
前后指针法
*/
int PartSort3(int* a, int begin, int end)
{
	int midindex = GetMidIndex(a, begin, end);
	swap(&a[begin], &a[midindex]);

	int key = a[begin];
	int prev = begin;
	int cur = begin + 1;

	while (cur <= end)
	{
		// cur找小,把小的往前翻,大的往后翻
		if (a[cur] < key && ++prev != cur)
			swap(&a[cur], &a[prev]);

		++cur;
	}

	swap(&a[begin], &a[prev]);

	return prev;
}

void insertSort(int a[], int n)
{
	int j;
	for (int i = 1; i < n; i++)
	{
		int temp = a[i];
		for (j = i - 1; a[j] > temp && j >= 0; j--)
		{

			a[j + 1] = a[j];

		}
		a[j + 1] = temp;
	}

}



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

	if (right - left + 1 < 10)
	{
		insertSort(a + left, right - left + 1);
	}
	else
	{
		int div = PartSort1(a, left, right);
		//[left, div-1]
		//[div+1, right]
		QuickSort(a, left, div - 1);
		QuickSort(a, div + 1, right);
	}
}
//用栈模拟递归,用队列也可以实现
void QuickSortNor(int array[], int size)
{
	Stack s;
	StackInit(&s,10);

	int left = 0;
	int right = size;

	StackPush(&s, right);
	StackPush(&s, left);

	while (!StackEmpty(&s))
	{
		left = StackTop(&s);
		StackPop(&s);
		right = StackTop(&s);
		StackPop(&s);

		if (right - left <= 16)
			insertSort(array + left, right - left);
		else
		{
			int div = PartSort2(array, left, right);

			// 基准值的左侧:[left, div)
			// 基准值的右侧:[div+1, right);
			StackPush(&s, right);
			StackPush(&s, div + 1);

			StackPush(&s, div);
			StackPush(&s, left);
		}
	}
}


/*
void QuickSortR(int* a, int left, int right)
{
	Stack st;
	StackInit(&st, 10);
	//先入大区间
	if (left < right)
	{
		StackPush(&st, right);
		StackPush(&st, left);
	}
	//栈不为空,说明还有没处理的区间
	while (StackEmpty(&st) != 0)
	{
		left = StackTop(&st);
		StackPop(&st);
		right = StackTop(&st);
		StackPop(&st);
		//快排单趟排序
		int div = PartSort1(a, left, right);
		// [left div-1]
		// 把大于1个数的区间继续入栈
		if (left < div - 1)
		{
			StackPush(&st, div - 1);
			StackPush(&st, left);
		}

		// [div+1, right]
		if (div + 1 < right)
		{
			StackPush(&st, right);
			StackPush(&st, div + 1);
		}
	}

}
*/

int main()
{
	int a[] = { 3, 4, 6, 1, 2, 8, 0, 5, 7 };
	printf("快速排序:\n");
	PrintArray(a, sizeof(a) / sizeof(int));
	//QuickSort(a, 0, sizeof(a) / sizeof(int) - 1);
	QuickSortNor(a,  sizeof(a) / sizeof(int) );
	PrintArray(a, sizeof(a) / sizeof(int));
	return 0;
}

或: 

#include<iostream>
#include<vector>
using namespace std;

void quickSort(int nums[], int l, int r) {
	if (l + 1 >= r) return;
	int begin = l, end = r - 1, key = nums[begin];
	while (begin < end)
	{
		//右指针 从右向左扫描 将⼩于piv的放到左边
		while (begin < end && nums[end] >= key) 
			end--;
			nums[begin] = nums[end];

      //左指针 从左向右扫描 将⼤于piv的放到右边
		while (begin < end && nums[begin] <= key) 
			begin++;
		
			nums[end] = nums[begin];
	}
	nums[begin] = key;//更新piv
	quickSort(nums, l, begin);//递归排序 //以L为中间值,分左右两部分递归调⽤
	quickSort(nums, begin + 1, r);
}


int main()
{
	int m[] = { 2,4,6,8,10,1,3,5,7,9 };
	int n = sizeof(m) / sizeof(m[0]);
	for (int i = 0; i < n; i++)
	{
		cout << m[i] << " ";
	}
	cout << endl;

	quickSort(m, 0, 10);

	for (int i = 0; i < n; i++)
	{
		cout << m[i] << " ";
	}

}

 

四、归并排序:

//有递归和非递归两种方式,已测试
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>

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

	printf("\n");
}

void _MergeSort(int* a, int left, int right, int* tmp)
{
	if (left >= right)
		return;

	int mid = left + ((right - left) >> 1);

	// [left, mid]
	// [mid+1, right]
	_MergeSort(a, left, mid, tmp);
	_MergeSort(a, mid + 1, right, tmp);

	int begin1 = left, end1 = mid;
	int begin2 = mid + 1, end2 = right;
	int index = left;
	while (begin1 <= end1 && begin2 <= end2)
	{
		if (a[begin1] <= a[begin2])
			tmp[index++] = a[begin1++];
		else
			tmp[index++] = a[begin2++];
	}

	while (begin1 <= end1)
	{
		tmp[index++] = a[begin1++];
	}

	while (begin2 <= end2)
	{
		tmp[index++] = a[begin2++];
	}

	memcpy(a + left, tmp + left, sizeof(int) * (right - left + 1));
}

//封装一下,让用户好调用
void MergeSort(int* a, int n)
{
	assert(a);
	int* tmp = (int*)malloc(sizeof(int) * n);
	_MergeSort(a, 0, n - 1, tmp);
	free(tmp);
}

/*
非递归排序与递归排序相反,将一个元素与相邻元素构成有序数组,
再与旁边数组构成有序数组,直至整个数组有序。
要有mid指针传入,因为不足一组数据时,重新计算mid划分会有问题
需要指定mid的位置
*/
void merge(int* a, int left, int mid, int right, int* tmp)
{
	// [left, mid]
	// [mid+1, right]
	int begin1 = left, end1 = mid;
	int begin2 = mid + 1, end2 = right;
	int index = left;
	while (begin1 <= end1 && begin2 <= end2)
	{
		if (a[begin1] <= a[begin2])
			tmp[index++] = a[begin1++];
		else
			tmp[index++] = a[begin2++];
	}

	while (begin1 <= end1)
	{
		tmp[index++] = a[begin1++];
	}

	while (begin2 <= end2)
	{
		tmp[index++] = a[begin2++];
	}

	memcpy(a + left, tmp + left, sizeof(int) * (right - left + 1));
}

/*
k用来表示每次k个元素归并
*/
void mergePass(int* arr, int k, int n, int* temp)
{
	int i = 0;
	//从前往后,将2个长度为k的子序列合并为1个
	while (i < n - 2 * k + 1)
	{
		merge(arr, i, i + k - 1, i + 2 * k - 1, temp);
		i += 2 * k;
	}
	//合并区间[i, n - 1]有序的左半部分[i, i + k - 1]以及不及一个步长的右半部分[i + k, n - 1]
	if (i < n - k)
	{
		merge(arr, i, i + k - 1, n - 1, temp);
	}

}

// 归并排序非递归版
void MergeSortNonR(int* arr, int length)
{
	int k = 1;
	int* temp = (int*)malloc(sizeof(int) * length);
	while (k < length)
	{
		mergePass(arr, k, length, temp);
		k *= 2;
	}
	free(temp);
}

int main()
{
	int a[10] = { 4,1,3,2,7,6,5,9,10,8 };
	printf("归并排序:\n");
	PrintArray(a, 10);
	MergeSort(a, 10);
	PrintArray(a, 10);

	//printf("归并排序--非递归:\n");
	//MergeSortNonR(a, 10);
	//PrintArray(a, 10);
	return 0;
}

或:

#include<iostream>
#include<vector>
using namespace std;
void mergeCount(int a[], int L, int mid, int R) {
	//int* tmp = new int[L + mid + R];
	int* t = (int*)malloc((R + 1) * sizeof(int));
	int begin1 = L;
	int end1 = mid;
	int begin2 = mid + 1;
	int end2 = R;
	int k = 0;
	while (begin1 <= end1 && begin2 <= end2) {
		if (a[begin1] < a[begin2])
			t[k++] = a[begin1++];
		else
			t[k++] = a[begin2++];
	}
	///判断哪个⼦数组中有剩余的数据
	while (begin1 <= end1)
		t[k++] = a[begin1++];
	while (begin2 <= end2)
		t[k++] = a[begin2++];
	/// 将 tmp 中的数组拷⻉回 A[p...r]
	for (int i = 0; i < k; ++i)
		a[L + i] = t[i];
	//delete tmp;
	free (t);
}
void mergeSort(int a[], int L, int R) {
	///递归终⽌条件 分治递归
	/// 将 A[L...m] 和 A[m+1...R] 合并为 A[L...R]
	if (L >= R) { return; }
	int mid = L + (R - L) / 2;
	mergeSort(a, L, mid);
	mergeSort(a, mid + 1, R);
	mergeCount(a, L, mid, R);
}
int main() {
	int a[] = { 1,34,66,2,5,95,4,46,2,33 };
	int nums = sizeof(a) / sizeof(int);
	cout << "数组元素个数:" << sizeof(a) / sizeof(int) << endl;//10

	for (int i = 0; i < nums; ++i) {
		std::cout << a[i] << " "; // print => 1 2 4 5 27 34 46 66 95
	}

	//传递数组下标
	mergeSort(a, 0, nums-1);
	
	cout << endl;

	for (int i = 0; i < nums; ++i) {
		std::cout << a[i] << " "; // print => 1 2 4 5 27 34 46 66 95
	}
	std::cout << endl;
	return 0;
}

 

五、计数排序:

#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>
void PrintArray(int array[], int size)
{
	for (int i = 0; i < size; ++i)
	{
		printf("%d ", array[i]);
	}

	printf("\n");
}

void CountSort(int* a, int n)
{
	int max = a[0], min = a[0];
	for (int i = 0; i < n; ++i)
	{
		if (a[i] > max)
			max = a[i];

		if (a[i] < min)
			min = a[i];
	}
	//找到数据的范围 
	int range = max - min + 1;
	int* countArray = (int*)malloc(range * sizeof(int));
	memset(countArray, 0, sizeof(int) * range);
	//存放在相对位置,可以节省空间
	for (int i = 0; i < n; ++i)
	{
		countArray[a[i] - min]++;
	}
	//可能存在重复的数据,有几个存几个
	int index = 0;
	for (int i = 0; i < range; ++i)
	{
		while (countArray[i]--)
		{
			a[index++] = i + min;
		}
	}
}

//该方式好理解
void CountSort2(int array[], int size)
{
	// 0. 获取数据的范围
	int minValue = array[0];
	int maxValue = array[0];
	for (int i = 1; i < size; ++i)
	{
		if (array[i] > maxValue)
			maxValue = array[i];

		if (array[i] < minValue)
			minValue = array[i];
	}

	// 数据范围在[minValue, maxValue] 假设数据在1000-1009,其实只需要10个空间就可以
	int range = maxValue - minValue + 1;

	int* count = (int*)calloc(range, sizeof(int));
	if (NULL == count)
	{
		assert(0);
		return;
	}

	// 1. 先统计每个元素出现的次数
	for (int i = 0; i < size; ++i)
	{
		count[array[i] - minValue]++;
	}

	// 2. 排序--按照计数数组的下标对数据进行回收
	int index = 0;
	for (int i = 0; i < 10; ++i)
	{
		// 回收
		while (count[i] > 0)
		{
			array[index++] = i + minValue;//展开
			count[i]--;
		}
	}

	free(count);
}

int main()
{
	int a[10] = { 4,1,3,2,7,6,5,9,10,8 };
	printf("计数排序:\n");
	PrintArray(a, 10);
	CountSort2(a, 10);
	PrintArray(a, 10);
	return 0;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值