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

直接选择排序

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);
}
相关推荐
_.Switch22 分钟前
Python 自动化运维持续优化与性能调优
运维·开发语言·python·缓存·自动化·运维开发
徐*红23 分钟前
java 线程池
java·开发语言
尚学教辅学习资料23 分钟前
基于SSM的养老院管理系统+LW示例参考
java·开发语言·java毕设·养老院
1 9 J25 分钟前
Java 上机实践4(类与对象)
java·开发语言·算法
Code apprenticeship26 分钟前
Java面试题(2)
java·开发语言
J不A秃V头A28 分钟前
Python爬虫:获取国家货币编码、货币名称
开发语言·爬虫·python
passer__jw7672 小时前
【LeetCode】【算法】3. 无重复字符的最长子串
算法·leetcode
passer__jw7672 小时前
【LeetCode】【算法】21. 合并两个有序链表
算法·leetcode·链表
sweetheart7-72 小时前
LeetCode22. 括号生成(2024冬季每日一题 2)
算法·深度优先·力扣·dfs·左右括号匹配
SRY122404193 小时前
javaSE面试题
java·开发语言·面试