【数据结构】八种排序方法(完整代码)

完成功能

插入排序

1.直接插入排序:
默认第一个数是有序数列,将后面的数依次经过比较插入正确的位置
2.希尔排序:
设置gap值,先将间隔gap的值进行插入排序,再设置几个gap插入排序,最后gap=1时,即排序完成。

选择排序

3.直接选择排序:
i>每次从待排数据中选择最小的数,若它不是第一个位置的值则与第一个位置的值进行交换,将剩下n-1个值继续操作,直到待排数据全部排完。
ii>用两个指针begin和end,分别从待排数据两边开始找到最大值和最小值,将最大值放在最后一个位置,将最小值放在第一个位置,再将剩下n-2个值继续操作,直到待排数据全部排完。
4.堆排序:数组本身看作一个堆,且升序建大堆,降序建小堆。
调堆(建大堆):将堆顶元素与堆最后一个元素交换,从堆顶开始往下调整为大顶堆,再将剩下n-1个元素进行调整

交换排序

5.冒泡排序:
相邻的两个元素依次比较,较大的元素向下沉,一共需要排n-1趟。
6.快速排序:
i>挖坑法:用k保存a[key]的值,则在key处有一个坑,右边end指针向左找比k小的值补左坑(可直接覆盖),再左边begin指针向右找比k大的值补右坑,直到end=begin停止,此时用k补坑。
ii>递归方法:以最左边的值k为标准划分,end向左找比k小的值,begin向右找比k大的值,begin找到的值与end找到的值进行交换,直到end=begin停止,交换k和end指针的值。
iii>前后指针法:k=a[key],key=begin。用cur指向k的下一个值,prev指向k。如果cur找到比k小的值,则交换k的下一个值和cur的值,直到cur指向NULL为止,最后交换prev和k。
三数取中法:在begin,end,(begin+end)/2三个值中找到中间值作为划分依据。
非递归方法:用栈保存数组中被划分的左右区间的值。

7.归并排序:
先使每个子序列有序,再使子序列段间有序,将两个有序表二路归并成一个有序表。
8.计数排序:
统计相同元素出现次数,再根据统计的结果将序列回收到原来的序列中
用两个数组,一个存原数组一个存统计后数组

完整代码

sort.c
#define _CRT_SECURE_NO_WARNINGS 1
#include 
#include 
#include 


typedef int STDataType;

typedef struct Stack
{
	STDataType* _a;
	int _top;
	int _capacity;
}Stack;

void StackInit(Stack* ps);
void StackDestory(Stack* ps);

void StackPush(Stack *ps, STDataType x);
void StackPop(Stack* ps);
STDataType  StackTop(Stack* ps);
int StackEmpty(Stack* ps);

void StackInit(Stack* ps)
{
	assert(ps);
	ps->_a = NULL;
	ps->_capacity = 0;
	ps->_top = 0;
}

void StackDestory(Stack* ps)
{
	assert(ps);
	ps->_capacity = 0;
	ps->_top = 0;
	free(ps->_a);
	ps->_a = NULL;
}

void StackPush(Stack *ps, STDataType x)
{
	assert(ps);
	if (ps->_top == ps->_capacity)
	{
		size_t newcapacity = (ps->_capacity == 0 ? 4 : ps->_capacity * 2);
		ps->_a = (STDataType*)realloc(ps->_a, sizeof(STDataType)*newcapacity);
		ps->_capacity = newcapacity;
	}
	ps->_a[ps->_top] = x;
	ps->_top++;
}

void StackPop(Stack* ps)
{
	assert(ps&&ps->_top>0);
	ps->_top--;
}

STDataType  StackTop(Stack* ps)
{
	assert(ps&&ps->_top>0);
	return ps->_a[ps->_top - 1];
}

int StackEmpty(Stack* ps)
{
	assert(ps);
	if (ps->_top == 0)
		return 0;
	else return 1;
}

void Swap(int* a, int* b)
{
	int tmp = *a;
	*a = *b;
	*b = tmp;
}


void sortPrint(int* a, int n)
{
	for (int i = 0; i < n; i++)
	{
		printf("%d ", a[i]);
	}
	printf("\n");
}

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

//希尔排序
void ShellSort(int* a, int n)
{
	int gap = n;
	while (gap > 1)
	{
		gap = gap / 3 + 1;
		for (int i = 0; i < n - gap - 1; i++)
		{
			int end = i;
			int tmp = a[end + gap];
			while (end >= 0)
			{
				if (a[end]>tmp)
				{
					a[end + gap] = a[end];
					end -= gap;
				}
				else break;
			}
			a[end + gap] = tmp;
		}
	}
}

//选择排序
void SelectSort(int* a, int n)
{
	int begin = 0;
	int end = n - 1;
	while (begina[i])
				min = i;
			if (a[max] a[son])
			son++;
		if (a[parent] < a[son])
		{
			Swap(&a[parent], &a[son]);
			parent = son;
			son = 2 * parent + 1;
		}
		else break;
	}
}
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 > 0)
	{
		Swap(&a[0], &a[end]);
		AdjustDown(a, end, 0);
		end--;
	}
}

//冒泡排序
void BubbleSort(int* a, int n)
{
	int end = n - 1;
	while (end > 0)
	{
		int exchange = 0;
		for (int i = 1; i < n; i++)
		{
			if (a[i - 1]>a[i])
				Swap(&a[i - 1], &a[i]);
			    exchange = 1;
		}
		if (exchange == 0)
		{
			break;
		}
		end--;
	}
}

//直接快速排序
int PartSort1(int* a, int begin, int end)
{
	int key = begin;
	while (begin < end)
	{
		while (begin= a[key])
			end--;
		while (begina[end])  return begin;
		else   return  end;
	}
	//a[begin]>a[mid]
	else
	{
		if (a[mid]>a[end])  return mid;
		else if (a[end] > a[begin])  return begin;
		else return end;
	}
}
int PartSort2(int* a, int begin, int end)
{
	int key = begin;
	int mid = GetMidIndex(a,begin,end);
	Swap(&a[begin], &a[mid]);
	while (begin < end)
	{
		while (begin= a[key])
			end--;
		while (begin=k)
			end--;
		a[begin] = a[end];
		while (begin < end&&a[begin] <= k)
			begin++;
		a[end] = a[begin];
	}
	a[end] = k;
	return begin;
}
 
//前后指针法
int PartSort4(int* a, int begin,int end)
{
	int cur = begin + 1;
	int prev = begin;
	while (cur<=end)
	{
		if (a[cur] < a[begin]&&prev++!=cur)
			Swap(&a[cur], &a[prev]);
		cur++;
	}
	Swap(&a[prev], &a[begin]);
	return prev;
}

//快速排序
void QuickSort(int* a, int left, int right)
{
	if (left >= right)
	{
		return;
	}
	else
	{
		//int div = PartSort1(a, left, right);
		//int div = PartSort2(a, left, right);
		int div = PartSort3(a, left, right);
		//int div = PartSort4(a, left, right);
		QuickSort(a, left, div - 1);
		QuickSort(a, div + 1, right);
	}
}

void QuickSort1(int* a, int left, int right)
{
	if (left - right < 1)
	{
		int div = PartSort3(a, left, right);
		QuickSort(a, left, div - 1);
		QuickSort(a, div + 1, right);
	}
	else
	{
		InsertSort(a + left, right - left + 1);
	}
	
}

//非递归的快速排序
void QSort(int* a, int left, int right)
{
	Stack st; 
	StackInit(&st);
	StackPush(&st, right);
	StackPush(&st, left);
	while (StackEmpty(&st) != 0)
	{
		int begin = StackTop(&st);
		StackPop(&st);
		int end = StackTop(&st);
		StackPop(&st);
		int div = PartSort4(a, begin, end);
		//划分区间
		if (begin < (div-1))
		{
			StackPush(&st, div-1);
			StackPush(&st, begin);
		}
		if ((div + 1) < end)
		{
			StackPush(&st, end);
			StackPush(&st, div+1);
		}
	}
}

//归并排序
void _MergeSort(int* a, int begin, int end, int* tmp)
{
	if (begin >= end)  return;
	int mid = begin + ((end - begin) >> 1);
	_MergeSort(a, begin, mid, tmp);
	_MergeSort(a, mid+1,end, tmp);
	int b1 = begin, e1 = mid;
	int b2 = mid + 1, e2 = end;
	int index = begin;
	while (b1<=e1&&b2<=e2)
	{
		if (a[b1] < a[b2])  tmp[index++] = a[b1++];
		else  tmp[index++] = a[b2++];
	}
	while (b1 <= e1)
		tmp[index++] = a[b1++];
	while (b2 <= e2)
		tmp[index++] = a[b2++];
	index = begin;
	while (begin<=end)
		a[begin++] = tmp[index++];
}
void MergeSort(int* a, int n)
{ 
	int* tmp = (int*)malloc(sizeof(int)*n);
	_MergeSort(a, 0, n - 1, tmp);
	free(tmp);
} 

//计数排序
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 *count = (int*)malloc(sizeof(int)*range);
	memset(count, 0, sizeof(int)*range);
	for (int i = 0; i < n; i++)
	{
		count[a[i] - min]++;
	}
	int j = 0;
	for (int i = 0; i < range; i++)
	{
		while (count[i]--)
			a[j++] = i + min;
	}
}

void sortTest()
{
	int a[] = {9,4,5, 3, 4, 5, 1, 2, 7, 6, 9, 8 };
	int size = sizeof(a) / sizeof(a[0]);
	printf("插入排序的结果是: ");
	InsertSort(a, size);
	sortPrint(a, size);
	int b[] = { 9, 4, 5, 3, 4, 5, 1, 8 };
	int size1 = sizeof(b) / sizeof(b[0]);
	printf("希尔排序的结果是: ");
	ShellSort(b, size1);
	sortPrint(b, size1);
	int c[] = { 1, 2, 5,6,9,3, 4 };
	int size2 = sizeof(c) / sizeof(c[0]);
	printf("选择排序的结果是: ");
	SelectSort(c, size2);
	sortPrint(c, size2);
	int d[] = { 1, 2,3,7, 6, 9, 3, 4 };
	int size3 = sizeof(c) / sizeof(c[0]);
	printf("堆排序的结果是:   ");
	HeapSort(d, size3);
	sortPrint(d , size3);
	int e[] = { 6,5,7,9,2,1,0 };
	int size4 = sizeof(e) / sizeof(e[0]);
	printf("冒泡排序的结果是: ");
	BubbleSort(e , size4);
	sortPrint(e , size4);
	int f[] = { 6, 5,3,5, 2, 1, 0 };
	int size5 = sizeof(f) / sizeof(f[0]);
	printf("快速排序的结果是:   ");
	QuickSort(f , 0, size5 - 1);
	//QuickSort1(f, 0, size5 - 1);
	//QSort(f, 0, size5 - 1);
	sortPrint(f , size5);
	int g[] = { 6, 5, 3, 5, 2, 1, 0 };
	int size6 = sizeof(g) / sizeof(g[0]);
	printf("计数排序的结果是:   ");
	CountSort(g, size6);
	sortPrint(g, size6);
	int h[] = { 6, 5, 3, 5, 2,7,8, 1, 0 };
	int size7 = sizeof(h) / sizeof(h[0]);
	printf("归并排序的结果是:   ");
	MergeSort(h, size7);
	sortPrint(h, size7);

}

main.c
#define _CRT_SECURE_NO_WARNINGS 1
#include 
#include 
int main()
{
	sortTest();
	system("pause");
	return 0;

}

你可能感兴趣的:(C++,/,数据结构,算法思想)