常见的排序算法

这篇具有很好参考价值的文章主要介绍了常见的排序算法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、冒泡排序

// 外层循环控制从第几个数组元素开始
		for (int i = 0; i < num.length - 1; i++) { // i<num. length-1,因为最后要用倒数第二个和最后一个比较
			// i=0确定第一大的的数,并放到倒数第一位. i=1确定第二大的的数,并放到倒数第二位................
			for (int j = 0; j < num.length - i - 1; j++) { // -i是因为最后一个已经是最大的,不需要再排
				if (num[j] > num[j + 1]) {
					// 通过引入变量a使前后交换顺序:1.把前面的num[j]交给一个变量a来记住;
					// 2.把后面的num[j+1]赋值给num[j];3.把变量a赋值给num[j+1]

					int a = num[j]; // 1.把前面的num[j]交给一个变量a来记住;
					num[j] = num[j + 1]; // 2.把后面的num[j+1]赋值给num[j];
					num[j + 1] = a; // 3.把变量a赋值给num[j+1]
				}
			}
		}

二、插入排序

// 插入排序
	public static int[] insertionSort(int[] arr) {
		int len = arr.length;
		for (int i = 1; i < len; i++) {
			// j表示当前元素的位置,将其和左边的元素比较,若当前元素小,就交换,也就相当于插入
			// 这样当前元素位于j-1处,j--来更新当前元素,j一直左移不能越界,因此应该大于0
			for (int j = i; j > 0 && arr[j] < arr[j - 1]; j--) {
				int temp = arr[j]; // 元素交换
				arr[j] = arr[j - 1];
				arr[j - 1] = temp;
			}
		}
		return arr;
	}

三、归并排序

// 分 与 和的方法  归并排序额外占用一个空间
	public static void mergeSort(int[] arr, int left, int right, int[] temp) {
		if (left < right) {
			int mid = (left + right) / 2;// 中间索引
			// 向左递归进行分解
			mergeSort(arr, left, mid, temp);
			// 向右递归进行分解
			mergeSort(arr, mid + 1, right, temp);
			// 开始合并
			merge(arr, left, mid, right, temp);
		}
	}

	// 合并的方法
	/**
	 * 
	 * @param arr   要排序的数组
	 * @param left  左边有序序列的初始索引
	 * @param mid   中间索引
	 * @param right 右边索引
	 * @param temp  做中转的数组
	 */
	public static void merge(int[] arr, int left, int mid, int right, int[] temp) {
		int i = left;// 初始化i,左边有序序列的初始索引
		int j = mid + 1;// 初始化j,右边有序序列的初始索引
		int t = 0;// temp数组的指针,指向temp数组

		// (一)
		// 先把左右两边(有序的)数据按照规则填充到temp数组中
		// 直到有一边处理完为止
		while (i <= mid && j <= right) {
			// 如果左边的元素小于右边的,将左边的拷贝到temp数组中
			// 同时i和t后移
			if (arr[i] < arr[j]) {
				temp[t] = arr[i];
				t++;
				i++;
			} else {// 反之,将右边的拷贝到temp中去
				temp[t] = arr[j];
				t++;
				j++;

			}
		}

		// (二)
		// 把有剩余的一边全部拷贝到temp中去
		while (i <= mid) {// 如果左边有剩余,将剩余的拷贝到temp中去
			temp[t] = arr[i];
			t++;
			i++;
		}

		while (j <= right) {// 如果右边有剩余,将剩余的拷贝到temp中去
			temp[t] = arr[j];
			t++;
			j++;
		}
		// (三)
		// 将temp数组中的元素全部拷贝到arr中
		// 并不是将所有的数据一下全部拷贝回去
		t = 0;
		int tempLeft = left;
		System.out.println("tempLeft = " + tempLeft + "  right = " + right);
		System.out.println(Arrays.toString(temp));
		while (tempLeft <= right) {
			// 第一次合并tempLeft = 0,right = 1;//第二次合并:tempLeft = 2,right = 3
			// 最后一次:tempLeft = 0,right = 7.
			arr[tempLeft] = temp[t];
			t++;
			tempLeft++;
		}
	}

四、快速排序

public static void quickSort(int[] arr, int left, int right) {
		// 递归退出条件
		if (left >= right) {
			return;
		}

		int l = left;
		int r = right;
		// 其中array[left]并未发生改变,是r和l在变
		while (r > l) {
			while (r > l && arr[r] >= arr[left]) { // 从右向左
				r--;
			}
			while (r > l && arr[l] <= arr[left]) { // 从左向右
				l++;
			}
			if (r == l) { // 说明第一次快排结束
				// 使基数(我们选的那个参照数,这里是指第一个数)到中间
				//
				int temp = arr[l];
				arr[l] = arr[left];
				arr[left] = temp;
			} else {
				// 引入变量temp作为中间值,使arr[l]和arr[r]交互
				// 最终还是要进入到r==l,结束第一次快排
				int temp = arr[r];
				arr[r] = arr[l];
				arr[l] = temp;
			}
		}
		// 递归调用
		quickSort(arr, left, l - 1);// 此时l和r相等
		quickSort(arr, r + 1, right);
	}

五、基数排序(与桶排序相似)

基数排序:稳定性排序,但是消耗的内存较大;对于正数使用,负数不适用

// 基数排序的方法
	public static void radixSort(int[] arr) {
		// 根据前面的推导,得到最终的代码
		// 首先得到最大的数
		int max = arr[0];
		for (int i = 1; i < arr.length; i++) {
			if (arr[i] > max) {
				max = arr[i];
			}
		}
		// 判断最大的元素的有几位,将它转换成字符串
		int maxLength = (max + "").length();

		// 定义一个二位数组,表示10个桶,每个桶就是一个一维数组
		// 说明
		// 1、二维数组包含10个一维数组
		// 2、为了防止在放入的时候,数据溢出,则每一个一维数组(桶),大小定为arr.length
		// 3.很明确,基数排序是使用空间换时间的经典算法
		int[][] bucket = new int[10][arr.length];

		// 为了记录每个桶中,实际存放了多少个数据,我们定义一个一维数组来记录各个桶每次放入的数据个数
		// 可以这样理解:buckElementCounts[0]代表的就是第一个桶中存放了多少个数据
		int[] bucketElementCounts = new int[10];

		// 定义一个for循环
		for (int i = 0, n = 1; i < maxLength; i++, n *= 10) {
			// 针对每个元素的位数进行排序处理,第一次是个位,之后是十位。。。。。。。。
			for (int j = 0; j < arr.length; j++) {
				// 取出每个元素位数的值
				int digitOfElement = arr[j] / n % 10;
				// 放入到对应的桶中
				bucket[digitOfElement][bucketElementCounts[digitOfElement]] = arr[j];
				bucketElementCounts[digitOfElement]++;
			}

			// 按照这个桶的顺序(一维数组的下标依次取出数据,放入原来的数组中)
			int index = 0;
			for (int k = 0; k < bucketElementCounts.length; k++) {
				// 如果桶内有数据,我们才放入到原数组
				if (bucketElementCounts[k] != 0) {
					// 循环第k个桶(即第k个一维数组),放入原数组中
					for (int l = 0; l < bucketElementCounts[k]; l++) {
						// 取出元素放入到arr中
						arr[index++] = bucket[k][l];
					}
				}

				// 第一轮处理后,将10个桶内寸的数据的个数的数据清零,即bucketElementCounts[k] = 0
				bucketElementCounts[k] = 0;
			}
		}

	}

六、选择排序

// 选择排序
	/**
	 * 原理: 第一轮比较:将第一个元素和后面的每一个元素比较,后面的哪一个元素比第一个元素小,则将他们交换位置,结果是数组的第一个元素为最小的
	 * 第二轮比较:以此类推,第二轮的结果是数组的第二个元素为第二小的元素 .......
	 * 
	 * @param args
	 */

	// 选择排序的代码实现
	public static void selectionSort(int[] arr) {
		for (int i = 0; i < arr.length; i++) {
			int index = i;// 将i记录下来,后面有用
			for (int j = 1 + i; j < arr.length; j++) {
				if (arr[index] > arr[j]) {
					int temp = arr[index];
					arr[index] = arr[j];
					arr[j] = temp;
				}
			}
		}
	}

七、希尔排序

基于插入排序,但是不是很稳定

public static void shellSort(int[] str) {

		if (str == null || str.length == 0) {
			return;
		}

		for (int temp = str.length / 2; temp >= 1; temp /= 2) {
			// 1.外边第一轮循环将0-->64比较,-4与-8,3与28,
			// 外边第一轮结束后,数组变成了0 -8 3 64 -4 28
			// 2.外边第二轮循环,将数组的第一个元素和第二个比较,若符合条件,则交换位置;
			// 再将第二个元素和第三个比较,依此类推.....
			for (int i = temp; i < str.length; i++) {
				int flag = str[i];
				int j = i - temp;
				while (j >= 0) {
					if (str[j] > flag) {
						str[j + temp] = str[j];
						j -= temp;
					} else {
						break;
					}
				}
				str[j + temp] = flag;
			}
		}
	}

未完待续...文章来源地址https://www.toymoban.com/news/detail-795528.html

到了这里,关于常见的排序算法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 常见排序算法之插入排序类

    顾得泉: 个人主页 个人专栏: 《Linux操作系统》  《C/C++》  《LeedCode刷题》 键盘敲烂,年薪百万!  插入排序,是一种简单直观的排序算法,工作原理是将一个记录插入到已经排好序的有序表中,从而形成一个新的、记录数增1的有序表。在实现过程中,它使用双层循环,

    2024年02月04日
    浏览(27)
  • 排序算法终极篇之手撕常见排序算法

       文章目录 引入 一、插入排序 1、1 插入排序的实现思想 1、2 插入排序的代码实现及特点分析  二、希尔排序 2、1 希尔排序的实现思想 2、2 希尔排序的代码实现及特点分析  三、选择排序 3、1 选择排序的实现思想 3、2 选择排序的代码实现及特点分析 四、堆排序 五、冒泡

    2023年04月16日
    浏览(26)
  • 【算法篇C++实现】常见排序算法

    算法精炼 每趟从待排序的记录中选出最小的记录,顺序放在已排序的记录序列末尾,直到全部排序结束为止。 简单排序处理流程 从待排序序列中,找到最小的元素; 如果最小元素不是待排序序列的第一个元素,将其和第一个元素互换; 从余下的 N - 1 个元素中

    2024年02月13日
    浏览(30)
  • Java常见算法_常见的查找算法和排序算法——简介及代码演示

            在本文中我将介绍Java中的常见算法,查找算法包括基本查找、二分查找、插值查找和分块查找。排序算法包括冒泡排序、选择排序、插入排序和快速排序 1.基本查找: 代码: 这是简单的基本查找,通过遍历数组来查看元素是否存在 运行结果: 基本查找小练习: 代

    2024年04月10日
    浏览(30)
  • 软考知识点——常见算法策略、设计模式、常见排序算法

    目录 一、常见算法策略 二、设计模式 1.设计模式分类 2.创建型设计模式应用场景 3.结构型设计模式应用场景  4.行为型设计模式应用场景 三、常见排序算法 算法名称 关键点 特征 典型问题 分治法 递归技术 把一个问题拆分成多个小模块的相同子问题,一般可用递归解决。

    2024年02月07日
    浏览(30)
  • Java常见的排序算法

    排序分为内部排序和外部排序(外部存储) 常见的七大排序, 这些都是内部排序 。 1、插入排序:每次将一个待排序的记录,按其 的大小插入到前面已排序好的记录序列 中的适当位置,直到全部记录插入完成为止。 稳定排序算法 一个排序算法的稳定性与不稳定性是

    2024年02月11日
    浏览(29)
  • 常见的排序算法-(字解版)

    例如:3 1 2 7 5 6 第一次基数: 3 [] 1 2 7 5 6 3 和 6 5 7 比都比 3 大 , 位置不变 [] 1 2 7 5 6 3 和 2 比 ,大于 2 放在右边。 2 1 [] 7 5 6 3 和 1 比 ,大于 1 位置不变。 2 1 3 7 5 6 把 3 的左边和右边,再次快速排序 左边:2 1 基数: 2 [] 1 2 和 1 比 2 大于 1, 转换:1 [] 最终: 1 2 右边:7 5 6

    2024年03月11日
    浏览(19)
  • 常见的排序算法

    基数排序:稳定性排序,但是消耗的内存较大;对于正数使用,负数不适用 基于插入排序,但是不是很稳定 未完待续...

    2024年01月16日
    浏览(6)
  • 常见排序算法详解

    排序是我们在日常生活和工作中常见的一种操作。在计算机科学中,排序算法就是将一串或一组数据按照特定的顺序进行排列的算法。这些顺序可能是数字的升序或降序,也可能是字母或字词的字母顺序等。我们将探讨几种不同的排序算法,包括他们的原理、优缺点以及代码

    2024年02月16日
    浏览(23)
  • 常见排序算法

      一 插入排序 1.直接插入排序 1.1基本思想 1.2代码实现 1.3图解分析 1.4特性 2.希尔排序 2.1基本思想 2.2代码实现 2.3图解分析  2.4特性 二 选择排序 1.直接选择排序 1.1基本思想 1.2代码实现 1.3特性          2.堆排序 2.1基本思想 2.2相关概念图解  2.3向下调整算法 2.4 图解分析

    2024年02月04日
    浏览(10)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包