七大排序(插入排序,希尔排序,选择排序,堆排序,冒泡排序,快速排序,归并排序)

七大排序(插入排序,希尔排序,选择排序,堆排序,冒泡排序,快速排序,归并排序)
在这里插入图片描述

1.插入排序:把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列 。

2.希尔排序:先选定一个整数,把待排序文件中所有记录分成gap/2个组,所有距离为的记录分在同一组内,并对每一组内的记录进行排序。然后取,重复上述分组和排序的工作。当到达gap=1时,所有记录在统一组内排好序。

3.选择排序:每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完 。

4.堆排序:利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。它是通过堆来进行选择数据。

5.冒泡排序:根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置,然后交换完成排序.

6.快速排序:任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止。

7.归并排序:归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。

代码实现
Sort.h

#ifndef _SORT_H_
#define _SORT_H_


#define _CRT_SECURE_NO_WARNINGS

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

void swapArgs(int *pa, int *pb);
//插入排序
void InsertSort(int *src, int n);
//希尔排序
void ShellSort(int *src, int n);
//选择排序
void SelectSort(int *src, int n);
//堆排序
void AdjustDowm(int *src, int size, int n);//向下调整算法
void SwapHeap(int *src, int size);//交换堆
void HeapSort(int *src, int n);//堆排序
//冒泡排序
void BubbleSort(int *src, int n);
//快速排序
int doublePointerWay(int *src, int start, int end);//双指针法
int doublePointerWay2(int *src, int start, int end);
int digWay(int *src, int start, int end);//挖坑法
int hoareWay(int *src, int start, int end);//hoare法
void dealQuickSort(int *src, int start, int end);//处理快速排序
void QuickSort(int *src, int n);//快速排序
void QuickSortNonR(int *src, int n);
//归并排序(分治思想)
void dealMergeSort(int *src, int *tmp, int start, int end);//处理归并排序
void MergeSort(int *src, int n);//归并排序

#endif // !SORT_H_

Sort.c

#include "Sort.h"
#include "Queue.h"

//交换两个数字的位置
void swapArgs(int *pa, int *pb) {
	int tmp;
	tmp = *pa;
	*pa = *pb;
	*pb = tmp;
}

//插入排序 时间复杂度O(n^2)
//1.数组越有序,插排时间越短.
//2.当数组规模较小,插排是最优选.
void InsertSort(int *src, int n) {
	int i, j, tmp;
	for (i = 1; i < n; i++) {
		tmp = src[i];
		for (j = i; j > 0 && src[j-1] > tmp; j--) {
			src[j] = src[j - 1];
		}
		src[j] = tmp;
	}
}

//希尔排序(缩小增量法) 时间复杂度O(nlong)~O(n^2)
//希尔排序是多重插排,核心是数组越有序,插排越快.
void ShellSort(int *src, int n) {
	int i, j, k, tmp;
	int gap;
	for (gap = n / 2; gap; gap /= 2) {
		for (k = 0; k < gap; k++) {
			for (i = gap + k; i < n; i += gap) {
				tmp = src[i];
				for (j = i; j > gap - 1 && src[j - gap] > tmp; j -= gap) {
					src[j] = src[j - gap];
				}
				src[j] = tmp;
			}
		}
	}
}

//选择排序 时间复杂度O(n^2)
void SelectSort(int *src, int n) {
	int i, j;
	int min;
	for (i = 0; i < n - 1; i++) {
		min = i;
		for (j = i + 1; j < n; j++) {
			if (src[j] < src[min]) {
				min = j;
			}
		}
		swapArgs(src + i, src + min);
	}
}

//堆排序 时间复杂度O(nlogn)
//向下调整算法
void AdjustDowm(int *src, int size, int n) {
	int cur;
	while (2 * n + 1 < size) {
		if (2 * n + 2 >= size) {
			cur = 2 * n + 1;
		}
		else {
			if (src[2 * n + 1] > src[2 * n + 2]) {
				cur = 2 * n + 1;
			}
			else {
				cur = 2 * n + 2;
			}
		}
		if (src[cur] > src[n]) {
			swapArgs(src + cur, src + n);
			n = cur;
		}
		else {
			break;
		}
	}
}

//交换堆
void SwapHeap(int *src, int size) {
	if (size == 0) {
		return;
	}
	swapArgs(src + 0, src + size - 1);
	AdjustDowm(src, size - 1, 0);
}

//堆排序
void HeapSort(int *src, int n) {
	for (int i = n / 2 - 1; i >= 0; i--) {
		AdjustDowm(src, n, i);
	}
	for (; n > 1; n--) {
		SwapHeap(src, n);
	}
}

//冒泡排序 时间复杂度O(n^2)
void BubbleSort(int *src, int n) {
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n - i - 1; j++) {
			if (src[j]>src[j + 1]) {
				swapArgs(src + j, src + j + 1);
			}
		}
	}
}

//快速排序 时间复杂度O(nlogn)
//双指针法
int doublePointerWay(int *src, int start, int end) {
	int a = start;
	int b = end;
	int flag = 0;
	while (src[b] > src[a]) {
		b--;
	}
	while (a < b) {
		swapArgs(src + b, src + a);
		flag = !flag;
		while (src[b] >= src[a]) {
			flag ? a++ : b--;
		}
	}
	return flag ? b : a;
}

//双指针法
int doublePointerWay2(int *src, int start, int end) {
	int a = start;
	int b = end - 1;
	int mid = (start + end) / 2;
	swapArgs(src + mid, src + end);
	while (a <= b) {
		while (src[a] <= src[end] && a < end) {
			a++;
		}
		while (src[b] >= src[end] && b > 0) {
			b--;
		}
		if ((a == b) && (a == 0 || a == end)) {
			break;
		}
		if (a < b) {
			swapArgs(src + a, src + b);
		}
		swapArgs(src + a, src + end);
	}
	return a;
}

//挖坑法
int digWay(int *src, int start, int end) {
	int a = start;
	int b = end;
	int flag = 0;
	int tmp = src[start];
	while (1) {
		while ((b > start) && (src[b] >= tmp)) {
			b--;
		}
		if (a < b) {
			src[a] = src[b];
		}
		else {
			src[a] = tmp;
			return a;
		}
		while ((a < end) && (src[a] <= tmp)) {
			a++;
		}
		if (a < b) {
			src[b] = src[a];
		}
		else {
			src[b] = tmp;
			return b;
		}
	}
}

//hoare法
int hoareWay(int *src, int start, int end) {
	int a = start + 1;
	int b = end - 2;
	int mid = (start + end) / 2;
	if (src[start] > src[mid]) {
		swapArgs(src + start, src + mid);
	}
	if (src[mid] > src[end]) {
		swapArgs(src + mid, src + end);
	}
	if (src[start] > src[mid]) {
		swapArgs(src +start, src + mid);
	}
	if (end - start <= 2) {
		return mid;
	}
	swapArgs(src + mid, src + end - 1);
	while (a <= b) {
		while (src[a] <= src[end - 1] && a <= end - 1) {
			a++;
		}
		while (src[b] >= src[end - 1] && b >= 1) {
			b--;
		}
		if ((a == b) && (a == 0 || a == end)) {
			break;
		}
		if (a < b) {
			swapArgs(src + a, src + b);
		}
	}
	swapArgs(src + a, src + end - 1);
	return a;
}

void dealQuickSort(int *src, int start, int end) {
	int mid;
	if (start + 8 < end) {
		mid = hoareWay(src, start, end);
		dealQuickSort(src, start, mid - 1);
		dealQuickSort(src, mid + 1, end);
	}
	else {
		InsertSort(src, end - start - 1);
	}
}

void QuickSort(int *src, int n) {
	dealQuickSort(src, 0, n - 1);
}

//非递归快速排序
void QuickSortNonR(int *src, int n) {
	int start = 0;
	int end = n - 1;
	int mid;
	Queue qu;
	QueueInit(&qu);
	QueuePush(&qu, start);
	QueuePush(&qu, end);
	while (QueueEmpty(&qu)) {
		start = QueueTop(&qu);
		QueuePop(&qu);
		end = QueueTop(&qu);
		QueuePop(&qu);
		mid = hoareWay(src, start, end);
		if (start < mid - 1) {
			QueuePush(&qu, start);
			QueuePush(&qu, mid - 1);
		}
		if (mid + 1 < end) {
			QueuePush(&qu, mid + 1);
			QueuePush(&qu, end);
		}
	}
	QueueDestory(&qu);
}

//归并排序 时间复杂度O(nlongn)(且时间复杂度一定为O(nlogn))
void dealMergeSort(int *src, int *tmp, int start, int end) {
	if (start >= end) {
		return;
	}
	int mid = (start + end) / 2;
	dealMergeSort(src, tmp, start, mid);
	dealMergeSort(src, tmp, mid + 1, end);
	int a = start;
	int b = mid + 1;
	int c = start;
	while (a <= mid && b <= end) {
		if (src[a] < src[b]) {
			tmp[c] = src[a];
			a++;
		}
		else {
			tmp[c] = src[b];
			b++;
		}
		c++;
	}
	for (; a <= mid; a++) {
		tmp[c] = src[a];
		c++;
	}
	for (; b <= end; b++) {
		tmp[c] = src[b];
		c++;
	}
	for (int i = start; i <= end; i++) {
		src[i] = tmp[i];
	}
}

void MergeSort(int *src, int n) {
	int *tmp = (int*)malloc(n*sizeof(int));
	dealMergeSort(src, tmp, 0, n - 1);
	free(tmp);
}

main.c

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Sort.h"

#define SIZE 1000

void PrintArray(int *src, int n) {
	int i;
	for (i = 0; i < n; i++) {
		printf("%d ", src[i]);
	}
	putchar('\n');
}

int main() {

#if 1
	int src[10] = { 9, 6, 7, 8, 5, 4, 3, 2, 1, 10 };
	InsertSort(src,10);
	PrintArray(src, 10);
	ShellSort(src, 10);
	PrintArray(src, 10);
	SelectSort(src, 10);
	PrintArray(src, 10);
	HeapSort(src,10);
	PrintArray(src, 10);
	BubbleSort(src, 10);
	PrintArray(src, 10);
	QuickSort(src, 10);
	PrintArray(src, 10);
	QuickSortNonR(src,10);
	PrintArray(src,10);
	MergeSort(src, 10);
	PrintArray(src, 10);
#else
	srand(time(NULL));
	int src[SIZE];
	int i;
	for (i = 0; i < SIZE; i++) {
		src[i] = rand() % 5000 + 1;
	}
	InsertSort(src, SIZE);
	PrintArray(src, SIZE);
	ShellSort(src, SIZE);
	PrintArray(src, SIZE);
	SelectSort(src, SIZE);
	PrintArray(src, SIZE);
	HeapSort(src, SIZE);
	PrintArray(src, SIZE);
	BubbleSort(src, SIZE);
	PrintArray(src, SIZE);
	QuickSort(src, SIZE);
	PrintArray(src, SIZE);
	PrintArray(src, SIZE);
	QuickSortNonR(src, SIZE);
	MergeSort(src, SIZE);
	PrintArray(src, SIZE);


#endif
	system("pause");
	return 0;
}
  • 2
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值