常用高级排序算法

首先初始化了一个MAX大小的数组,用乱序函数将数组打乱,用于测试各个排序函数,先附上要测试的几个基础排序函数,后面附上乱序函数和主调度函数。代码就那么几行,只是注释的思乱占了比较多的行数

快速排序

//快速排序,思想的重点是 递归+分组(分治)+前后交叉操作
void quickSort(int *array, int low, int hight)
{
	//判断是否满足条件
	if (hight <= low)	//如果只有一个元素或者前后错位了,就不用排序了,一个元素就是成序的
		return;
	//满足排序条件,进入排序部分
	int i = low, j = hight;	//定义函数内的临时变量为low和hight的副本,避免修改low和 hight,后面还要使用
	int temp = array[low];
	//对整个序列进行一次筛选,以目标值为分割点,只有当i<j时表示遍历没有完成,需要继续遍历
	while (i < j){
		while (i<j && array[j]>temp){
			j--;
		}
		if (i < j){
			array[i++] = array[j];
		}
		while (i < j && array[i] < temp){
			i++;
		}
		if (i < j){
			array[j--] = array[i];
		}
	}
	//循环跳出,证明i=j,遍历相遇,一轮筛选完成,将目标数放在中间
	array[i] = temp;
	//递归部分
		//将前半部分交给快排函数
	quickSort(array, low, i - 1);
		//将后半部分交给快拍函数
	quickSort(array, i + 1, hight);
}

shell排序(基于插入排序)

//shell排序(希尔排序)
void shellSort(int *array, int size, int d)
{
	//循环1 控制步长的循环
	for (int increment = d; increment > 0; increment /= 2){
		//循环2 属于插入排序内容,控制遍历次步长可以访问到的元素
		for (int i = increment; i < size; i += increment){
			int temp = array[i];
			int j = i - increment;
			//循环3 属于插入排序内容,赋值寻找目前元素可以插入的位置
			while (j >= 0 && array[j]>temp){
				array[j + increment] = array[j];
				j -= increment;
			}
			array[j + increment] = temp;
		}
	}
}

shell排序(基于选择排序)

相比于基于插入排序实现的shell排序,这个看起来循环多,实现的时候逻辑也不简单于基于插入排序,

不知道是我写的问题,还是问题的本身就是这样的,求指教

void shellSort2(int *array, int size, int d)
{
	//循环1,控制步长变化,直到步长为1也执行后结束
	for (int increment = d; increment > 0; increment /= 2){
		//循环2,找出每组的开头
		for (int k = 0; k < increment; k++){
			//循环3,属于选择排序范围了,对上面提供的开头的组内元素做选择排序
			for (int i = k; i < size - 1; i += increment){
				int tempIndex = i;
				//循环4,属于选择排序
				for (int j = i + increment; j < size; j += increment){
					if (array[j] < array[tempIndex]){
						tempIndex = j;
					}
				}
				if (tempIndex != i){
					int temp = array[i];
					array[i] = array[tempIndex];
					array[tempIndex] = temp;
				}
			}
		}
	}
}

辅助的操作函数,包括 乱序函数,打印数组函数,交换元素值得函数

//交换函数
void swap(int *a, int *b)
{
	int c = *a;
	*a = *b;
	*b = c;
}
//乱序函数,通过从后往前遍历数组,使得当前索引的值与随机一个比它索引小的元素交换
void shuffle(int *array, int size)
{
	srand((unsigned int)time(NULL));
	for (int i = size - 1; i > 0; i--){
		int index = rand() % i;
		swap(&array[i], &array[index]);
	}
}
//打印数组函数
void printArray(int *array, int size)
{
	for (int i = 0; i < size; i++){
		printf("%d\t",array[i]);
	}
}

主函数,负责测试各个排序函数

int main()
{
	//定义并初始化数组
	int array[MAX] = { 0 };
	for (int i = 0; i < MAX; i++){
		array[i] = i;
	}
	//对数组数据进行乱序
	shuffle(array, MAX);
	//打印乱序后的数组
	printArray(array, MAX);
	//测试各个排序的效果
	/*printf("\n快速排序后\n");
	quickSort(array, 0, MAX - 1);
	printArray(array, MAX);*/
	printf("\nshell排序后\n");
	shellSort(array, MAX, MAX / 2);
	printArray(array, MAX);
	return 0;
}
时间: 2024-12-12 23:18:58

常用高级排序算法的相关文章

数据结构之高级排序算法

一.希尔排序 希尔排序(缩小增量法) 属于插入类排序,由Shell提出,希尔排序对直接插入排序进行了简单的改进:它通过加大插入排序中元素之间的间隔,并在这些有间隔的元素中进行插入排序,从而使数据项大跨度地移动,当这些数据项排过一趟序之后,希尔排序算法减小数据项的间隔再进行排序,依次进行下去,进行这些排序时的数据项之间的间隔被称为增量,习惯上用字母h来表示这个增量. 具体代码实现: 1 package data.struct.algorithm; 2 3 //高级排序算法之希尔排序 4 class

javascript数据结构与算法--高级排序算法

高级排序算法是处理大型数据集的最高效排序算法,它是处理的数据集可以达到上百万个元素,而不仅仅是几百个或者几千个.现在我们来学习下2种高级排序算法---- 希尔排序和快速排序. 一:希尔排序: 希尔排序的核心理念是:首先比较距离较远的元素,而非相邻的元素. 基本原理:通过定义一个间隔序列来表示在排序过程中进行比较的元素之间有多远的间隔. 下面我们来看看数组[0,9,1,8,7,6,2,3,5,4] 来使用希尔排序的原理:如下图: 代码分析如下: 1. 执行 "间隔序列=3的步骤" A.

JavaScript实现常用的排序算法

▓▓▓▓▓▓ 大致介绍 由于最近要考试复习,所以学习js的时间少了 -_-||,考试完还会继续的努力学习,这次用原生的JavaScript实现以前学习的常用的排序算法,有冒泡排序.快速排序.直接插入排序.希尔排序.直接选择排序 ▓▓▓▓▓▓ 交换排序 交换排序是一类在排序过程中借助于交换操作来完成排序的方法,基本思想是两两比较排序记录的关键字,如果发现两个关键字逆序,则将两个记录位置互换,重复此过程,直到该排序列中所有关键字都有序为止,接下来介绍交换排序中常见的冒泡排序和快速排序 ▓▓▓▓▓▓

【计算机基础】 常用的排序算法的时间复杂度和空间复杂度

常用的排序算法的时间复杂度和空间复杂度 排序法 最差时间分析 平均时间复杂度 稳定度 空间复杂度 冒泡排序 O(n2) O(n2) 稳定 O(1) 快速排序 O(n2) O(n*log2n) 不稳定 O(log2n)~O(n) 选择排序 O(n2) O(n2) 稳定 O(1) 二叉树排序 O(n2) O(n*log2n) 不一顶 O(n) 插入排序 O(n2) O(n2) 稳定 O(1) 堆排序 O(n*log2n) O(n*log2n) 不稳定 O(1) 希尔排序 O O 不稳定 O(1) 1

7 种常用的排序算法-视觉直观感受

7 种常用的排序算法-可视化 1. 快速排序 介绍: 快速排序是由东尼·霍尔所发展的一种排序算法.在平均状况下,排序 n 个项目要Ο(n log n)次比较.在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见.事实上,快速排序通常明显比其他Ο(n log n) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来,且在大部分真实世界的数据,可以决定设计的选择,减少所需时间的二次方项之可能性. 步骤: 从数列中挑出一个元素,称为 “基准”(pivot),

java SE 常用的排序算法

java程序员会用到的经典排序算法实现 常用的排序算法(以下代码包含的)有以下五类: A.插入排序(直接插入排序.希尔排序) B.交换排序(冒泡排序.快速排序) C.选择排序(直接选择排序.堆排序) D.归并排序 E.分配排序(基数排序) 以下算法都是可以实现的,但是什么情况使用什么算法都是根据实际情况选用的. 如果有用的话就顶起吧,谢谢. import java.util.ArrayList; import java.util.List; public class Sort { // test

几种常用的排序算法总结

主要针对于插入排序,交换(冒泡和快速),选择,堆排序,归并这几种排序的基本原理和时间复杂度,及空间复杂度的一个总结. 一.插入排序 基本执行过程:3  5  2  7  9  8 1.从小到大:从第二个数开始,每次比较都与前边的几个数进行比较 但是从大到小,要先与前边排好序的几个数中的最大的开始进行比较即倒序比较,依次往前推. 如:5 先与3进行比较,比3大,所以直接排在3的后边为:3 5: 2要先与5进行比较,比5小,再与3比较,比3小,所以排序后为 2 3 5: 7要先与5比,比5大,所以直

C#中常用的排序算法的时间复杂度和空间复杂度

常用的排序算法的时间复杂度和空间复杂度 常用的排序算法的时间复杂度和空间复杂度 排序法 最差时间分析 平均时间复杂度 稳定度 空间复杂度 冒泡排序 O(n2) O(n2) 稳定 O(1) 快速排序 O(n2) O(n*log2n) 不稳定 O(log2n)~O(n) 选择排序 O(n2) O(n2) 稳定 O(1) 二叉树排序 O(n2) O(n*log2n) 不一顶 O(n) 插入排序 O(n2) O(n2) 稳定 O(1) 堆排序 O(n*log2n) O(n*log2n) 不稳定 O(1)

常用查找排序算法

1.折半查找算法: 对于一个已排好序的数组,若要查找某元素是否属于数组中,则可以用这种算法. 返回找到的元素在数组中的下标,找不到则返回-1 #include <stdio.h> #define LEN 8 int a[LEN] = { 1, 3, 3, 3, 4, 5, 6, 7 }; int binarysearch(int number) { int mid, start = 0, end = LEN - 1; while (start <= end) { mid = (start