排序算法集合

1、冒泡排序

1、基本思想

对于有n个数据的集合,我们对它遍历n次,在每次遍历中,如果第i个元素大于第i + 1个元素,我们就将这两个元素交换,以此类推,第一次遍历之后下标为n - 1的数(也就是最后一个数)就是最大的数,第k次遍历之后,从n - k 到 n - 1 的数就是最大的一组数。

2、代码实现

public void sort(int[] arrays) {
	int n = arrays.length;
	// 当n <= 1时,不需要排序
	if (n <= 1) {
		return;
	}

	int temp = 0;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n - i - 1; j++) {
			if (arrays[j] > arrays[j + 1]) {
				temp = arrays[j];
				arrays[j] = arrays[j + 1];
				arrays[j + 1] = temp;
			}
		}
	}
}

2、插入排序

1、基本思想

我们假设数组的前k个元素都是排好序的,这时候我们将第k + 1个元素cur与第k个元素比较,当k比cur大时,我们将第k个元素移动到第k + 1的位置,之后将元素cur与k - 1元素比较,直到找到一个比cur小的元素i,这时候我们将cur放到i + 1的位置即可,以此类推将所有元素插入到数组中。

2、代码实现

public void sort(int[] arrays) {
	int n = arrays.length;
	int cur = 0;
	int val = 0;

	for (int i = 1; i < n; i++) {
		cur = i - 1;
		val = arrays[i];
		while (cur >= 0) {
			if (val >= arrays[cur]) {
				break;
			}
			arrays[cur + 1] = arrays[cur];
			cur--;
		}
		arrays[cur + 1] = val;
	}
}

3、选择排序

1、基本思想

我们第一次找到一个最大的数,将这个数与最后一个数交换,第二次找到第二大的数并于倒数第二个数交换,以此类推。

2、代码实现

public void sort(int[] arrays) {
	int n = arrays.length;
	int curMaxVal = arrays[0];
	int curMaxIndex = 0;
	
	for (int i = 0; i < n; i++) {
		for (int j = 1; j < n - i; j++) {
			if (arrays[j] > curMaxVal) {
				curMaxVal = arrays[j];
				curMaxIndex = j;
			}
		}
		arrays[curMaxIndex] = arrays[n - i - 1];
		arrays[n - i - 1] = curMaxVal;
		curMaxVal = arrays[0];
		curMaxIndex = 0;
	}
}

4、希尔排序

1、基本思想

希尔排序是基于插入排序实现的,与插入不同的是,它将n个数量的数组分为i = n / 2个部分,我们把下标为0和i分为一组,把1和 i + 1 分为一组…,对每组的元素进行插入排序;之后,我们将这些数据分为j = n / 4个部分,同样地把下标为0、j、2 * j、3 * j 分为一组…,对每组元素进行插入排序…直到将所有数据都分为一组,这样就是上面提到的插入排序了。

2、代码实现

public void sort(int[] arrays) {
	int n = arrays.length;
	int curVal = 0;
	int cur = 0;
	
	for (int i = n / 2; i >= 1; i /= 2) {
		for (int j = 0; j < n; j++) {
			curVal = arrays[j];
			cur = j - i;
			while (cur >= 0 && curVal < arrays[cur]) {
				arrays[cur + i] = arrays[cur];
				cur -= i;
			}
			arrays[cur + i] = curVal;
		}
	}
}

5、快速排序

1、基本思想

我们首先选择数组最左边的元素cur,之后我们从右遍历数组,当找到一个比cur小的元素时,将这两个元素互换,之后我们从left + 1元素开始向右遍历,找到一个比cur元素大的元素并与cur互换,以此类推,当left指针或者right指针与cur指向同一个元素我们终止,这时候cur元素左边都是比它小的元素,右边都是比他大的元素;之后我们递归地执行上述操作,直到每个部分只有一个元素为止。

2、代码实现

public void sort(int[] arrays) {
	int n = arrays.length;
	quickSort(arrays, 0, n - 1);
}

private void quickSort(int[] arrays, int left, int right) {
	if (left >= right) {
		return;
	}
	
	int cur = left;
	int point = right;
	int curVal = arrays[cur];
	int temp = 0;

	while (point != cur) {
		while (point > cur && arrays[point] >= curVal) {
			point--;
		}
		arrays[cur] = arrays[point];
		arrays[point] = curVal;
		temp = cur;
		cur = point;
		point = temp;

		while (point < cur && arrays[point] <= curVal) {
			point++;
		}
		arrays[cur] = arrays[point];
		arrays[point] = curVal;
		temp = cur;
		cur = point;
		point = temp;
	}

	quickSort(arrays, left, cur - 1);
	quickSort(arrays, cur + 1, right);
}

6、归并排序

1、基本思想

我们首先将数据分组,每组两个元素,对这两个元素排序;之后我们将每组扩大为4个元素,这时我们只需要将两个内部排序好的小组进行排序即可,以此类推,最终将两个排好序的组进行排序,它与快排不同的是需要一个额外的空间。

2、代码实现

public void sort(int[] arrays) {
	int n = arrays.length;
	mergeSort(arrays, 0, n - 1);
}

private void mergeSort(int[] arrays, int left, int right) {
	int mid;
	if (left < right) {
		mid = (right + left) / 2 + 1;
		mergeSort(arrays, left, mid - 1);
		mergeSort(arrays, mid,  right);
		merge(arrays, left, mid, right);
	}
}

private void merge(int[] arrays, int left, int mid, int right) {
	if (left >= right) {
		return;
	}
	
	int[] temp = new int[right - left + 1];
	int tempCur = 0;
	int leftPoint = left;
	int rightPoint = mid;

	while (leftPoint < mid && rightPoint <= right) {
		if (arrays[leftPoint] <= arrays[rightPoint]) {
			temp[tempCur++] = arrays[leftPoint++];
		} else {
			temp[tempCur++] = arrays[rightPoint++];
		}
	}
	
	if (leftPoint < mid) {
		System.arraycopy(arrays, leftPoint, temp, tempCur, temp.length - tempCur);
	}
	if (rightPoint <= right) {
		System.arraycopy(arrays, rightPoint, temp, tempCur, temp.length - tempCur);
	}

	System.arraycopy(temp, 0, arrays, left, temp.length);
}

明天晚上会补充以下基数排序,关于外排序我就不会记录了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值