java排序算法自己总结版本

 差不多开始要找工作了,因此今天特意对排序算法进行了复习,把一些心得记录下来。先给出各种算法的原理和实现,最后再做些总结吧。

1.冒泡排序,这个应该是大家都熟悉的。(都是从小到大排)

原理:简单理解就是依次把最小的数往上冒。

	public void bubbleSort(int[] data) {

		//较小的数往前冒,每一次外层循环,保证第i个数是第i大的
			for(int i=0;i<data.length;i++){
				for(int j=i+1;j<data.length;j++){
					//如果后面有比data[i]小的,就交换过来
					if(data[i]>data[j])
						swap(data, i, j);
				}				
			}

 其中的swap方法表示交换数组中两个位置的数据,代码如下:

private void swap(int[] data, int x, int y) {

		int temp = data[x];

		data[x] = data[y];

		data[y] = temp;

	}

 

2.选择排序

个人感觉可以看作是冒泡排序方法的改进版。冒泡排序是只要后面的比当前的小就交换,而选择排序是从后面没排好的找到最小值的位置,最后只需要交换一次。

	public void selectSort(int[] data) {
			int index;//当前最小值的位置
			for(int i=0;i<data.length;i++){
				index=i;
				for(int j=i+1;j<data.length;j++){
					if(data[index]>data[j]){
						index=j;//记录最小位置
					}
				}
				swap(data, i, index);//把当前最小值保存到第i个位置
			}
	}

 3.插入排序

这种方法的思路是,将一个记录插入到已排好序的有序表(有可能是空表)中,从而得到一个新的记录数增1的有序表。也就是说程序开始把第一个数当作一个有序表,然后依次加入后面的n-1个数,每加入一个数,都要保证得到的序列是排好序的。

public void insertSort(int[] data) {
		for (int i = 1; i < data.length; i++) {
			// 把第i个位置的数插到前i-1个数的某个位置,保证前i个数排好序
			int temp = data[i];// 首先保存第i个数的值
			int j;
			for (j = i; j > 0; j--) {

				if (data[j - 1] > temp)// 如果前面的数比第i个位置的数大,说明得往后移
					data[j] = data[j - 1];
				else
					break;
			}
			data[j] = temp;// 找到合适位置后,插入即可
		}
	}

 4.快速排序

    从数组中随意找出一个数(这里取数组的第一个数),将大于和小于它的数分置于其两边,然后再将其两边的数组都以同样的方法执行 .主要分三步:1) 从数列中挑出一个元素,称为 "基准"(pivot) 2)重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分割之后,这个称为分割(partition)操作。3)递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

private void quickSort(int data[], int low, int high) {

		int i, j, pivot;
		i = low;
		j = high;
		if (low < high) {// 通过这个条件结束循环
			// 第一步,选择基准,这里就选择第一个数
			pivot = data[i];
			//第二步,通过下面这个循环,把数组中小于基准的放到数组左边,大于基准的放到数组右边
			while (i < j) {
				// 1.从右往左找到第一个小于pivot的元素
				while (i < j && data[j] > pivot)
					j--;
				if (i < j) {
					data[i] = data[j];// 第i个元素保存右边第一个小于pivot的
					i++;
				}
				//2.从左往右找,找到第一个大于pivot的元素
				while (i < j && data[i] < pivot)
					i++;
				if (i < j) {
					data[j] = data[i];// 第j个元素保存左边第一个大于pivot的
					j--;
				}
			}
			data[i] = pivot;//第i个位置就是基准的位置
			//第三步,递归调用该算法,把基准左边,右边的分别排序
			quickSort(data, low, i - 1);
			quickSort(data, i + 1, high);

		}
	}

 5.希尔排序(shell)缩小增量排序

      Shell排序法是对相邻指定距离(称为间隔)的元素进行比较,直到使用当前间隔进行比较的元素都按顺序排序为止.Shell把间隔缩小一半,然后继续处理,当间隔最终变为1,并且不再出现变化时,Shell排序也就完成了其处理过程.实际上就是根据增量把数组分成几部分,每部分进行插入排序即可。个人理解对每个部分的排序可以采取任何的简单排序方法。

public void shellSort(int[] data) {
		//这里把增量初始化为数组长度的一半,然后依次减半,当然也可以传进一个增量数组
		for (int inc = data.length / 2; inc > 2; inc /= 2) {
			for (int j = 0; j < inc; j++) {
				shellInsertSort(data, j, inc);//每一组内进行插入排序
			}
		}
		shellInsertSort(data, 0, 1);//最后进行一次所有元素的排序
	}

	//这个算法其实就是一次插入排序,只不过有个增量inc
	private void shellInsertSort(int[] data, int start, int inc) {
		int temp;
		for (int i = start+inc; i < data.length; i+=inc) {
			// 把第i个位置的数插到前i-1个数的某个位置,保证前i个数排好序
			temp = data[i];// 首先保存第i个数的值
			int j;
			for (j = i; j >=inc; j-=inc) {

				if (data[j - inc] > temp)// 如果前面的数比第i个位置的数大,说明得往后移
					data[j] = data[j - inc];
				else
					break;
			}
			data[j] = temp;// 找到合适位置后,插入即可
		}
	}

 

从代码中可以看出,组内的排序方法和前面讲过的插入排序完全一样。 

6.归并排序

算法思想是每次把待排序列分成两部分,分别对这两部分递归地用归并排序,完成后把这两个子部分合并成一个
序列。
归并排序借助一个全局性临时数组来方便对子序列的归并,该算法核心在于归并。

/** 
	 * @param data 是需要排序的原数组
	 * @param temp 是个临时数组,数组大小和data一样
	 * @param left 左边界
	 * @param right 右边界
	 */
	private void mergeSort(int[] data, int[] temp, int left, int right) {
		
		if (left >= right)//就剩一个元素时,直接返回,直接合并就行了。
			return;
		
		int mid = (left + right) / 2;//获得数组的中间位置
		mergeSort(data, temp, left, mid);//对左半部分递归调用排序算法
		mergeSort(data, temp, mid + 1, right);//对右半部分分递归
		
		//这一步是把原数组中的值保存到临时数组中
		for (int i = left; i <= right; i++) {			
			temp[i] = data[i];
		}
		
		//下面是完成合并,也就是把左右两个有序的数组合并到一个数组中,并使之有序
		int l= left;
		int r = mid + 1;
		for (int cur = left; cur <= right; cur++) {
			if (l == mid + 1)//如果第一个数组已经全部比较完了,那么我们只要直接复制第二个数组的条目到合并数组中即可
				data[cur] = temp[r++];
			else if (r > right)//如果第二个数组已经全部比较完了,那么我们只要直接复制第一个数组的条目到合并数组中即可
				data[cur] = temp[l++];
			else if (temp[l] < temp[r])//把比较的两个条目中关键值小的放到合并数组中
				data[cur] = temp[l++];
			else
				data[cur] = temp[r++];
		}
	}

 

7、堆排序 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值