Java最全面的基础算法总结(测试通过)

1.二分查找
     
     又叫折半查找,要求待查找的序列有序。每次取中间位置的值与待查关键字比较,如果中间位置
的值比待查关键字大,则在前半部分循环这个查找的过程,如果中间位置的值比待查关键字小,
则在后半部分循环这个查找的过程。直到查找到了为止,否则序列中没有待查的关键字。直接上代码
 
    
	// 二分查找
	public static int biSearch(int[] array, int a) {
		int lo = 0;
		int hi = array.length - 1;
		int mid;
		while (lo <= hi) {
			mid = (lo + hi) / 2;// 中间位置
			if (array[mid] == a) {
				return mid + 1;
			} else if (array[mid] < a) { // 向右查找
				lo = mid + 1;
			} else { // 向左查找
				hi = mid - 1;
			}
		}
		return -1;
	}
2.冒泡排序算法
 
(1)比较前后相邻的二个数据,如果前面数据大于后面的数据,就将这二个数据交换。
(2)这样对数组的第 0 个数据到 N-1 个数据进行一次遍历后,最大的一个数据就“沉”到数组第
N-1 个位置。
(3)N=N-1,如果 N 不为 0 就重复前面二步,否则排序完成。
	public static void bubbleSort(int[] array) {
		for (int i = 0; i < array.length; i++) {
			for (int j = 0; j < array.length - i -1; j++) {
				if (array[j] > array[j + 1]) {
					int temp;
					temp = array[j];
					array[j] = array[j+1];
					array[j+1] = temp;
				}
			}
		}
	}
3.插入排序算法
  
      通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应的位置并插入。
插入排序非常类似于整扑克牌。在开始摸牌时,左手是空的,牌面朝下放在桌上。接着, 一次从
桌上摸起一张牌,并将它插入到左手一把牌中的正确位置上。为了找到这张牌的正确位置,要将
它与手中已有的牌从右到左地进行比较。无论什么时候,左手中的牌都是排好序的。
如果输入数组已经是排好序的话,插入排序出现最佳情况,其运行时间是输入规模的一个线性函
数。如果输入数组是逆序排列的,将出现最坏情况。平均情况与最坏情况一样,其时间代价是(n2)。
	public void sort(int arr[]) {
		for (int i = 1; i < arr.length; i++) {
			// 插入的数
			int insertVal = arr[i];
			// 被插入的位置(准备和前一个数比较)
			int index = i - 1;
			// 如果插入的数比被插入的数小
			while (index >= 0 && insertVal < arr[index]) {
				// 将把 arr[index] 向后移动
				arr[index + 1] = arr[index];
				// 让 index 向前移动
				index--;
			}
			// 把插入的数放入合适位置
			arr[index + 1] = insertVal;
		}
	}
4.快速排序算法
 
        快速排序的原理:选择一个关键值作为基准值。比基准值小的都在左边序列(一般是无序的),
比基准值大的都在右边(一般是无序的)。一般选择序列的第一个元素。
一次循环:从后往前比较,用基准值和最后一个值比较,如果比基准值小的交换位置,如果没有
继续比较下一个,直到找到第一个比基准值小的值才交换。找到这个值之后,又从前往后开始比
较,如果有比基准值大的,交换位置,如果没有继续比较下一个,直到找到第一个比基准值大的
值才交换。直到从前往后的比较索引>从后往前比较的索引,结束第一次循环,此时,对于基准值
来说,左右两边就是有序的了。
	//快速排序
	public void sort(int[] a, int low, int high) {
		int start = low;
		int end = high;
		int key = a[low];
		while (end > start) {
			// 从后往前比较
			while (end > start && a[end] >= key)
		// 如果没有比关键值小的,比较下一个,直到有比关键值小的交换位置,然后又从前往后比较
				end--;
			if (a[end] <= key) {
				int temp = a[end];
				a[end] = a[start];
				a[start] = temp;
			}
			// 从前往后比较
			while (end > start && a[start] <= key)
				// 如果没有比关键值大的,比较下一个,直到有比关键值大的交换位置
				start++;
			if (a[start] >= key) {
				int temp = a[start];
				a[start] = a[end];
				a[end] = temp;
			}
			// 此时第一次循环比较结束,关键值的位置已经确定了。左边的值都比关键值小,右边的
		}
		// 递归
		if (start > low)
			sort(a, low, start - 1);// 左边序列。第一个索引位置到关键值索引-1
		if (end < high)
			sort(a, end + 1, high);// 右边序列。从关键值索引+1 到最后一个
	}
5.希尔排序算法
 
	// 希尔排序
	private void shellSort(int[] a) {
		int dk = a.length / 2;
		while (dk >= 1) {
			ShellInsertSort(a, dk);
			dk = dk / 2;
		}
	}

	private void ShellInsertSort(int[] a, int dk) {
		// 类似插入排序,只是插入排序增量是 1,这里增量是 dk,把 1 换成 dk 就可以了
		for (int i = dk; i < a.length; i++) {
			if (a[i] < a[i - dk]) {
				int j;
				int x = a[i];// x 为待插入元素
				a[i] = a[i - dk];
				for (j = i - dk; j >= 0 && x < a[j]; j = j - dk) {
					// 通过循环,逐个后移一位找到要插入的位置。
					a[j + dk] = a[j];
				}
				a[j + dk] = x;// 插入
			}
		}
	}
6.桶排序算法
 
     桶排序的基本思想是: 把数组 arr 划分为 n 个大小相同子区间(桶),每个子区间各自排序,最
后合并 。计数排序是桶排序的一种特殊情况,可以把计数排序当成每个桶里只有一个元素的情况。
1.找出待排序数组中的最大值 max、最小值 min
2.我们使用 动态数组 ArrayList 作为桶,桶里放的元素也用 ArrayList 存储。桶的数量为(max
min)/arr.length+1
3.遍历数组 arr,计算每个元素 arr[i] 放的桶
4.每个桶各自排序
 
	public static void bucketSort(int[] arr) {
		int max = Integer.MIN_VALUE;
		int min = Integer.MAX_VALUE;
		for (int i = 0; i < arr.length; i++) {
			max = Math.max(max, arr[i]);
			min = Math.min(min, arr[i]);
		}
		// 创建桶
		int bucketNum = (max - min) / arr.length + 1;
		ArrayList<ArrayList<Integer>> bucketArr = new ArrayList<>(bucketNum);
		for (int i = 0; i < bucketNum; i++) {
			bucketArr.add(new ArrayList<Integer>());
		}
		// 将每个元素放入桶
		for (int i = 0; i < arr.length; i++) {
			int num = (arr[i] - min) / (arr.length);
			bucketArr.get(num).add(arr[i]);
		}
		// 对每个桶进行排序
		for (int i = 0; i < bucketArr.size(); i++) {
			Collections.sort(bucketArr.get(i));
		}
	}
7.基数排序算法
 
   将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位
开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后,数列就变成一个有序序
列。

 

class radixSort {
		int a[] = { 49, 38, 65, 97, 76, 13, 27, 49, 78, 34, 12, 64, 5, 4, 62, 99, 98, 54, 101, 56, 17, 18, 23, 34, 15,
				35, 25, 53, 51 };

		public radixSort() {
			sort(a);
			for (int i = 0; i < a.length; i++) {
				System.out.println(a[i]);
			}
		}

		public void sort(int[] array) {
			// 首先确定排序的趟数;
			int max = array[0];
			for (int i = 1; i < array.length; i++) {
				if (array[i] > max) {
					max = array[i];
				}
			}
			int time = 0;
			// 判断位数;
			while (max > 0) {
				max /= 10;
				time++;
			}
			// 建立 10 个队列;
			List<ArrayList> queue = new ArrayList<ArrayList>();
			for (int i = 0; i < 10; i++) {
				ArrayList<Integer> queue1 = new ArrayList<Integer>();
				queue.add(queue1);
			}
			// 进行 time 次分配和收集;
			for (int i = 0; i < time; i++) {
				// 分配数组元素;
				for (int j = 0; j < array.length; j++) {
					// 得到数字的第 time+1 位数;
					int x = array[j] % (int) Math.pow(10, i + 1) / (int) Math.pow(10, i);
					ArrayList<Integer> queue2 = queue.get(x);
					queue2.add(array[j]);
					queue.set(x, queue2);
				}
				int count = 0;// 元素计数器;
				// 收集队列元素;
				for (int k = 0; k < 10; k++) {
					while (queue.get(k).size() > 0) {
						ArrayList<Integer> queue3 = queue.get(k);
						array[count] = queue3.get(0);
						queue3.remove(0);
						count++;
					}
				}
			}
		}
	}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值