浅谈十大排序算法&力扣经典题目

本文深入探讨了包括冒泡排序、选择排序、插入排序、希尔排序、基数排序、归并排序和快速排序在内的十大排序算法。通过理解每个算法的原理,分析其效率,并提供了对应的代码实现。同时,文章提及这些排序算法在LeetCode等编程挑战中的应用,为读者提供了实战练习的机会。
摘要由CSDN通过智能技术生成

算法篇

冒泡排序

原理:基于相邻两个元素之间比较,如果符合排序规则则交换两者位置,直到元素走到最后。 遍历次数n-1次

void bubSort() {
		int temp;
		for (int i = 0; i < N - 1; i++) {			//外循环控制遍历次数
			for (int j = 0; j < N - i - 1; j++) {	//内循环完成相邻元素比较
				if (_arr[j] > _arr[j + 1]) {
					temp = _arr[j + 1];
					_arr[j + 1] = _arr[j];
					_arr[j] = temp;
				}
			}
		}
		travel(true);
	}

内循环为什么退出条件是: N - i - 1 ?

选择排序

原理:从第一个元素开始,依次从后面元素中选择最小或最大的元素替换其位置,注意只需要遍历到N-1位置即可,因为最后一位无比较值。

for (int i = 0; i < N - 1; i++) {			//从第一个元素开始,依次从后面元素中选择最小或最大的元素替换其位置
			int min_idx = i;		//最小元素下标
			for (int j = i; j < N; j++) {				//比较后面的所有元素 因此下标到N截止
				min_idx = ((_arr[min_idx] < _arr[j]) ? min_idx : j);
			}
			int temp = _arr[min_idx];
			_arr[min_idx] = _arr[i];
			_arr[i] = temp;
		}

插入排序

把待排的第一个元素看做是有序数组,依次把后面的元素按照大小规则插入到有序数组中。 插入规则:从待插数据的前一个位置开始,从后往前插入,如果没有找到插入位置,则有序数组往后覆盖,找到插入数据则结束循环,最后插入数据。

	for (int i = 1; i < N; i++) {		//把待排的第一个元素看做是有序数组,依次把后面的元素按照大小规则插入到有序数组中
			int temp = _arr[i];		//记录待插数据
			int j;
			for ( j = i - 1; j >= 0 && _arr[j]>temp; j--) {			//遍历有序数组,找到插入位置
				_arr[j + 1] = _arr[j];				//找不到位置,就依次往后覆盖有序数组
			}
			_arr[j + 1] = temp;
		}

希尔排序

原理,先对排序链表分组;在各组内部分别进行插入排序。 分组数量叫做步长,当分组数量为1时,所得排序解决即为我们想要的结果。

int step = N >> 1;
		int j;
		while (step) {
			for (int i = step; i < N; i++) {
				int temp = _arr[i];
				for (j = i - step; _arr[j] > temp && j >= 0; j -= step) {
					_arr[j + step] = _arr[j];
				}
				_arr[j + step] = temp;
			}

			step = step >> 1;
		}

基数排序

基于数组下标有序排列,但是限制太多:排序的数必须时正整数,数字不可重复,需要记得释放开辟的临时空间。

int* temp = new int[MAX + 1];
		for (int i = 0; i < MAX + 1; i++)temp[i] = -1;

		for (int i = 0; i < N; i++) {
			temp[_arr[i]] = _arr[i];
		}
		int k = 0;
		for (int i = 0; i <= MAX; i++) {
			if (temp[i] != -1) {
				_arr[k++] = temp[i];
			}
		}
		delete[] temp;

归并排序

先局部有序,再保证整体有序的算法。时间复杂度为O(nlog(n)),空间复杂度为n的算法。

void mergeSort(int left, int right) {
		if (right <= left) return;

		int m = left + (right - left) / 2;
		printf("l:%d,m:%d,r:%d\n", left, m, right);
		mergeSort( left, m);
		mergeSort( m + 1, right);
		_Merge_Sort(left, m, right);
	}


	//合并数组
	void _Merge_Sort(int left, int mid, int right) {
		int* ptemp = new int[right - left + 1];

		int l = left;
		int r = mid + 1;
		int k = 0;
		while (l <= mid && r <= right) {
			if (_arr[l] < _arr[r]) {
				ptemp[k++] = _arr[l++];
			}
			else {
				ptemp[k++] = ptemp[r++];
			}
		}
		while (l <= mid) {
			ptemp[k++] = _arr[l++];
		}
		while (r <= right) {
			ptemp[k++] = _arr[r++];
		}
		
		memcpy(_arr + left, ptemp, sizeof(int) * (right - left + 1));
		delete[] ptemp;
	}
	void merge_sort() {
		travel();
		mergeSort(0, N - 1);
		travel("归并排序", true);
	}

快速排序

假定一个中间值, 循环让列表中按照中间值 小的排左边,大的排在右边(一次遍历了,符合条件的移动)。循环让l和r并拢,如果l小于r,循环继续。先整体有序,然后再局部有序的算法。

// 分组排序 快速排序
	void quickSort(int left, int right) {
		if (right < left)return;
		int l = left;
		int r = right;
		int temp = _arr[left];		//假定中间值

		while (l < r) {
			while (l<r && _arr[r]>temp)r--;
			_arr[l] = _arr[r];

			while (l < r && _arr[l] < temp)l++;
			_arr[r] = _arr[l];
		}
		_arr[l] = temp;

		quickSort(left, l - 1);
		quickSort(l + 1, right);
	}
	void quick_Sort(int len) {
		travel();
		quickSort(0, len - 1);
		travel("快速排序",true);
	}

整体代码

sort.h

#pragma once
#define N 10
#define MAX 1000000
#include<iostream>

class sort {
public:
	void travel(const char* str = "排序前", bool isSort = false) {
		
		if (isSort) {
			cout <<str<<endl;
			for (auto i : _arr) {
				cout << " " << i;
			}
			cout << endl;
			cout << "**************************************************\n\n\n";

		}
		else {
			cout << "**************************************************" << endl;
			cout << "排序前:";
			for (int i = 0; i < N; i++) {
				_arr[i] = std::rand() % 1000;
				cout << " " << _arr[i];
			}
			cout << endl;
		}
		
	}
public:
	//排序算法
	void bubSort() {
		travel();
		int temp;
		for (int i = 0; i < N - 1; i++) {
			for (int j = 0; j < N - i - 1; j++) {
				if (_arr[j] > _arr[j + 1]) {
					temp = _arr[j + 1];
					_arr[j + 1] = _arr[j];
					_arr[j] = temp;
				}
			}
		}
		travel("冒泡排序",true);
	}
	void selSort() {
		travel();
		for (int i = 0; i < N - 1; i++) {
			int min_idx = i;		//最小元素下标
			for (int j = i; j < N; j++) {
				min_idx = ((_arr[min_idx] < _arr[j]) ? min_idx : j);
			}
			int temp = _arr[min_idx];
			_arr[min_idx] = _arr[i];
			_arr[i] = temp;
		}
		travel("选择排序", true);
	}
	void insertSort() {
		travel();
		for (int i = 1; i < N; i++) {
			int temp = _arr[i];
			int j;
			for ( j = i - 1; j >= 0 && _arr[j]>temp; j--) {
				_arr[j + 1] = _arr[j];
			}
			_arr[j + 1] = temp;
		}
		travel("插入排序", true);
	}
	void shellSort() {
		travel();
		int step = N >> 1;
		int j;
		while (step) {
			for (int i = step; i < N; i++) {
				int temp = _arr[i];
				for (j = i - step; _arr[j] > temp && j >= 0; j -= step) {
					_arr[j + step] = _arr[j];
				}
				_arr[j + step] = temp;
			}

			step = step >> 1;
		}
		travel("希尔排序",true);
	}

	void radixSort() {
		travel();
		int* temp = new int[MAX + 1];
		for (int i = 0; i < MAX + 1; i++)temp[i] = -1;

		for (int i = 0; i < N; i++) {
			temp[_arr[i]] = _arr[i];
		}
		int k = 0;
		for (int i = 0; i <= MAX; i++) {
			if (temp[i] != -1) {
				_arr[k++] = temp[i];
			}
		}
		delete[] temp;

		travel("基数排序", true);
	}
	void bucketSort() {
		travel();
		int wei = 1;
		int** temp = new int*[10];
		for (int i = 0; i < 10; i++) {
			temp[i] = new int[N]; 
		}
		int wei_data;			//记录当前位的数据
		int k = 0;
		while (wei < 1000) {		//设置位数为1000

			//给桶赋值
			for (int i = 0; i < 10; i++) {
				for (int j = 0; j < N; j++) {
					temp[i][j] = -1;
				}
			}

			// 分组
			for (int i = 0; i < N; i++) {
				wei_data = _arr[i] / wei % 10;
				temp[wei_data][i] = _arr[i];
			}

			//取出复位
			k = 0;
			for (int i = 0; i < 10; i++) {
				for (int j = 0; j < N; j++) {
					if (temp[i][j] != -1) {
						_arr[k++] = temp[i][j];	 
					}
				}
			}
			//进位
			wei *= 10;
		}
		travel("桶排序", true);

	}
	void mergeSort(int left, int right) {
		if (right <= left) return;

		int m = left + (right - left) / 2;
		printf("l:%d,m:%d,r:%d\n", left, m, right);
		mergeSort( left, m);
		mergeSort( m + 1, right);
		_Merge_Sort(left, m, right);
	}


	//合并数组
	void _Merge_Sort(int left, int mid, int right) {
		int* ptemp = new int[right - left + 1];

		int l = left;
		int r = mid + 1;
		int k = 0;
		while (l < mid && r < right) {
			if (_arr[l] < _arr[r]) {
				ptemp[k++] = _arr[l++];
			}
			else {
				ptemp[k++] = ptemp[r++];
			}
		}
		while (l <= mid) {
			ptemp[k++] = _arr[l++];
		}
		while (r <= right) {
			ptemp[k++] = _arr[r++];
		}
		
		memcpy(_arr + left, ptemp, sizeof(int) * (right - left + 1));
		delete[] ptemp;
	}
	void merge_sort() {
		travel();
		mergeSort(0, N - 1);
		travel("归并排序", true);
	}

	// 分组排序 快速排序
	void quickSort(int left, int right) {
		if (right < left)return;
		int l = left;
		int r = right;
		int temp = _arr[left];

		while (l < r) {
			while (l<r && _arr[r]>temp)r--;
			_arr[l] = _arr[r];

			while (l < r && _arr[l] < temp)l++;
			_arr[r] = _arr[l];
		}
		_arr[l] = temp;

		quickSort(left, l - 1);
		quickSort(l + 1, right);
	}
	void quick_Sort(int len) {
		travel();
		quickSort(0, len - 1);
		travel("快速排序",true);
	}
private:
	int _arr[N];
};

test.cpp

int main(){
	sort s;
	s.bubSort();
	s.selSort();
	s.insertSort();
	s.shellSort();
	s.radixSort();
	s.bucketSort();
	s.merge_sort();
	s.quick_Sort(N);
	return 0;
}

力扣题目

待续……

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Warm wolf

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值