初阶数据结构之直接选择排序和快速排序

直接选择排序

1.在元素集合 array[i]--array[n-1] 中选择关键码最⼤(⼩)的数据元素

2.若它不是这组元素中的最后⼀个(第⼀个)元素,则将它与这组元素中的最后⼀个(第⼀个)元素 交换

3.在剩余的 array[i]--array[n-2](array[i+1]--array[n-1]) 集合中,重复上述步 骤,直到集合剩余 1 个元素

代码实现过程如下:

SelectSort.h

c 复制代码
#pragma once
#include <stdio.h>
void Swap(int* x, int* y);
void SelectSort(int* arr, int n);
void Print(int* arr, int n);

SelectSort.c

c 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include "SelectSort.h"
//交换数组内的元素
void Swap(int* x, int* y)
{
	int tmp = *x;
	*x = *y;
	*y = tmp;
}
//选择排序
void SelectSort(int* arr, int n)
{
	//end=n-1是为了防止越界
	int begin = 0;
	int end = n - 1;
	while (begin < end)
	{
		//begin+1是为了减少比较的次数
		int mini = begin;
		int maxi = begin;
		for (int i = begin + 1; i <= end; i++)
		{
			if (arr[maxi] < arr[i])
			{
				maxi = i;
			}
			if (arr[mini] > arr[i])
			{
				mini = i;
			}
		}
		if (maxi == begin)
		{
			maxi = mini;
		}
		Swap(&arr[begin], &arr[mini]);
		Swap(&arr[end], &arr[maxi]);
		begin++;
		end--;
	}
	
}
void Print(int* arr, int n)
{
	for (int i = 0; i < n; i++)
	{
		printf("%d", arr[i]);
	}
	printf("\n");
}
c 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include "SelectSort.h"

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

直接选择排序的特性总结:

1.直接选择排序思考⾮常好理解,但是效率不是很好。实际中很少使⽤

2.时间复杂度: O(N^2^)

3.空间复杂度: O(1)

快速排序

交换排序基本思想:

所谓交换,就是根据序列中两个记录键值的⽐较结果来对换这两个记录在序列中的位置 交换排序的特点是:将键值较⼤的记录向序列的尾部移动,键值较⼩的记录向序列的前部移动

快速排序

快速排序是Hoare于1962年提出的⼀种⼆叉树结构的交换排序⽅法,其基本思想为:任取待排序元素 序列中的某元素作为基准值,按照该排序码将待排序集合分割成两⼦序列,左⼦序列中所有元素均⼩ 于基准值,右⼦序列中所有元素均⼤于基准值,然后最左右⼦序列重复该过程,直到所有元素都排列 在相应位置上为⽌。

hoare版本

算法思路 :

1)创建左右指针,确定基准值

2)从右向左找出⽐基准值⼩的数据,从左向右找出⽐基准值⼤的数据,左右指针数据交换,进⼊下次 循环

问题1:为什么跳出循环后right位置的值⼀定不⼤于key?

当 left > right 时,即right⾛到left的左侧,⽽left扫描过的数据均不⼤于key,因此right此时指 向的数据⼀定不⼤于key

代码如下:

QuickSort.h

c 复制代码
#pragma once
#include <stdio.h>

void Swap(int* x, int* y);
int _QuickSort(int* arr, int left, int right);
void QuickSort(int* arr, int left, int right);
void Print(int* arr, int n);

QuickSort.c

c 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include "QuickSort.h"
void Swap(int* x, int* y)
{
	int tmp = *x;
	*x = *y;
	*y = tmp;
}
//找基准值
int _QuickSort(int* arr, int left, int right)
{
	//keyi表示基准值
	int keyi = left;
	left++;
	//取等号是一个关键,如果不取等号会造成left和right相遇比基准值大
	while (left <= right)
	{
		//这里数组里面的值不取等,是因为要跳出循环,保证基准值在序列的中间位置
		while (left <= right && arr[right] > arr[keyi])
		{
			right--;
		}
		while (left <= right && arr[left] < arr[keyi])
		{
			left++;
		}
		if (left <= right)
		{
			//这里也是细节
			Swap(&arr[left++], &arr[right--]);
		}
	}
	Swap(&arr[keyi], &arr[right]);
	return right;
}
//快速排序
void QuickSort(int* arr, int left, int right)
{
	if (left <= right)
	{
		return;
	}
	//第一步找基准值
	int keyi = _QuickSort(arr, left, right);
	//左子序列
	QuickSort(arr, left, keyi - 1);
	//右子序列
	QuickSort(arr, keyi + 1, right);
}
相关推荐
逝去的秋风几秒前
【代码随想录训练营第42期 Day61打卡 - 图论Part11 - Floyd 算法与A * 算法
算法·图论·floyd 算法·a -star算法
万物得其道者成8 分钟前
React Zustand状态管理库的使用
开发语言·javascript·ecmascript
zero_one_Machel10 分钟前
leetcode73矩阵置零
算法·leetcode·矩阵
学步_技术14 分钟前
Python编码系列—Python抽象工厂模式:构建复杂对象家族的蓝图
开发语言·python·抽象工厂模式
BeyondESH36 分钟前
Linux线程同步—竞态条件和互斥锁(C语言)
linux·服务器·c++
wn53138 分钟前
【Go - 类型断言】
服务器·开发语言·后端·golang
青椒大仙KI1141 分钟前
24/9/19 算法笔记 kaggle BankChurn数据分类
笔记·算法·分类
^^为欢几何^^1 小时前
lodash中_.difference如何过滤数组
javascript·数据结构·算法
豆浩宇1 小时前
Halcon OCR检测 免训练版
c++·人工智能·opencv·算法·计算机视觉·ocr
Hello-Mr.Wang1 小时前
vue3中开发引导页的方法
开发语言·前端·javascript