排序算法

排序算法:

  • 插入排序:直接插入排序,希尔排序
  • 交换排序:冒泡排序,快速排序
  • 选择排序:简单选择排序,堆排序
  • 归并排序

1. 直接插入排序

(1) 直接插入排序: 依次将待排序序列中的每一个记录插入到一个已经排好序的序列中,直到所有记录都排好序.

(2) 时间复杂度:最好情况下,即待排序序列为正序,时间复杂度为O(n);最坏情况下,即待排序序列为逆序,时间复杂度为O(n^2);平均情况下,时间复杂度为O(n^2).

(3) 空间复杂度: O(1)

(4) 代码如下:

	//ascending
	public static void InsertSort(int[] nums){
		int len = nums.length;
		for(int i=1;i<len;i++){
			int j;
			for(j=i;j>0;j--){
				if(nums[j]<nums[j-1]){					
					int temp = nums[j];
					nums[j] = nums[j-1];
					nums[j-1] = temp;
				}
			}
			
			for(j=0;j<len;j++)
				System.out.print(nums[j]+" ");
			System.out.print("\n");			
		}
	}

2. 希尔排序

(1) 希尔排序是对直接插入排序的改进;

(2) 希尔排序: 先将整个待排序序列分割成若干个子序列, 在子序列内分别进行直接插入排序, 待整个序列中的记录基本有序时, 再对全体记录进行一次直接插入排序;固定增量大小的分为一组;

(3) 时间复杂度: O(nlogn)~O(n^2)

(4) 空间复杂度: O(1)

实现代码如下:

public static void shellSort(int[] nums){
		int len = nums.length;
		int d = len/2; //增量大小
		int k;
		while(d>0){
			k=0;
			while(k<d){
				for(int i=k;i<len;i+=d){
					for(int j=i;j>=0&&j-d>=0;j-=d){
						if(nums[j]<nums[j-d]){
							int temp = nums[j];
							nums[j] = nums[j-d];
							nums[j-d] = temp;
						}
					}
				}
				k++;
			}
			
			d/=2;
			for(int j=0;j<len;j++)
				System.out.print(nums[j]+" ");
			
			System.out.print("\n");			
		}

3. 冒泡排序

(1) 冒泡排序:从头开始,两两比较相邻记录的关键码,如果是反序则交换,直到没有反序的记录为止。
(2) 时间复杂度:在最好情况下,即待排序序列为正序, 其时间复杂度为O(n);在最坏情况下,待排序序列为逆序,时间复杂度为O(n^2),平均时间复杂度为O(n^2).
(3) 空间复杂度:O(1)

(4) 实现代码:每一次外循环将最大的值移到后面,后面是有序的

public static void bubbleSort(int[] nums){
		int len = nums.length;
		for(int i=len-1;i>=0;i--){
			for(int j=0;j<i;j++){
				if(nums[j]>nums[j+1]){
					int temp = nums[j+1];
					nums[j+1] = nums[j];
					nums[j] = temp;
				}
			}
			for(int j=0;j<len;j++)
				System.out.print(nums[j]+" ");
			
			System.out.print("\n");	
			
		}
	}

4. 快速排序

(1) 快速排序是对冒泡排序的改进.

(2) 快速排序流程: 首先选一个参考值, 将待排序序列分割成独立的两部分, 左侧的值均小于参考值,右侧的值均大于或等于参考点;接着对这两部分分别重复这一过程,直到整个序列有序.

(3) 时间复杂度: 最好情况下,每次划分参考值的时候左侧子序列与右侧子序列的长度相同,时间复杂度为O(nlogn);最坏情况下,待排序序列为正序或逆序,时间复杂度为O(n^2);平均情况下,时间复杂度为O(nlogn).

(4) 空间复杂度: O(logn)

(5) 算法实现代码如下:

public static void quickSort(int[] nums,int low,int high){
		
		int mid;
		if(low<high){
			mid = partition(nums,low,high); 
			quickSort(nums,low,mid-1);
			quickSort(nums,mid+1,high);
		}else
			return;
	}
	
	public static int partition(int[] nums,int low,int high){
		int temp = nums[low]; //选取做左边的为参考值
		
		while(low<high){
			while(high>low&&nums[high]>=temp)
				high--;
			
			nums[low] = nums[high];
			
			while(low<high&&nums[low]<temp)
				low++;
			
			nums[high] = nums[low];

				
		}
		nums[low] = temp;
		
		for(int j=0;j<nums.length;j++)
			System.out.print(nums[j]+" ");
		
		System.out.print("\n");	
		
		return low;
	}

5. 简单选择排序

(1) 简单选择排序: 将最小值的下标和值记录下来,一轮遍历完后,进行一次交换;第i轮时,前i-1个值大小顺序已经排好.

(2) 时间复杂度: 最好最坏平均情况下都是O(n^2)

(3) 空间复杂度: O(1)

(4) 代码如下:

public static void selectSort(int[] nums){
		int len = nums.length;
		int j;
		for(int i=0;i<len-1;i++){
			int sIndex=i,sValue=nums[i];
			for(j=i+1;j<len;j++){
				if(nums[j]<sValue){
					sValue = nums[j];
					sIndex = j;
				}
			}
			nums[sIndex] = nums[i];
			nums[i] = sValue;
			
			for( j=0;j<nums.length;j++)
				System.out.print(nums[j]+" ");
			
			System.out.print("\n");	
		}
	}

6. 堆排序

(1) 堆排序是对简单选择排序的改进;

(2) 堆排序: 使用最小堆排序后的是递减数组;

堆的存储:一般都使用数组来表示堆,i节点的父节点下标为(i-1)/2.它的左右子节点下表为2i+1,2i+2;

(3) 时间复杂度: 最好,最坏,平均的时间复杂度都是O(nlogn)

(4) 空间复杂度: O(nlogn)

(5) 实现代码如下:

minHeap(nums,nums.length);
minHeapSort(nums,nums.length);

	//从第i个节点开始调整,num为节点总数,i节点的子节点为2i+1,2i+2
	public static void minHeapFix(int[] nums,int i,int num){
		int j = 2*i+1;
		int temp = nums[i];
		
		while(j<num){
			//找出左右孩子节点中值最小的节点
			if((j+1)<num&&nums[j+1]<nums[j])
				j++;
			
			//说明父节点依然是以其为根的节点中的最小点
			if(nums[j]>temp)
				break;
			
			//将值小的子节点替换其父节点
			nums[i] = nums[j];
		
			//由于替换后,父节点的到来可能使得其子树不再是最小堆,故需要继续调整
			i=j;
			j = 2*i+1;
		}
		nums[i] = temp;
	}
	
	//建立最小堆
	public static void minHeap(int[] nums,int len){
		//从下往上调整最小堆,忽略叶子节点,因为叶子节点自身就是最小堆
		for(int i=len/2-1;i>=0;i--){
			minHeapFix(nums,i,len);
		}
	}
	
	public static void minHeapSort(int[] nums, int len){
		minHeap(nums,len);//得先构建最小堆,此时第0个元素即是堆中最小的值,再实现排序
                int temp;
		for(int i=len-1;i>=1;i--){
			temp = nums[0];
			nums[0] = nums[i];
			nums[i]=temp;
			minHeapFix(nums,0,i);
			
			for(int j=0;j<nums.length;j++)
				System.out.print(nums[j]+" ");
			
			System.out.print("\n");	
		}
	}
	


7. 归并排序

(1) 归并排序: 将2个有序序列合并成一个有序序列为止;关键在于合并.

(2) 时间复杂度: 最好,最坏,平均的时间复杂度都是O(nlogn)

(3) 空间复杂度: O(n)

(4) 实现代码如下:

  • 申请空间,空间大小为2个有序序列大小之和,用于存放排好序后的元素;
  • 2个指针,分别指向2个已排序的序列,进行合并;
<span style="font-size:18px;">public static void mergeSort(int[] nums,int low,int high){
		int mid = (low+high)/2;
		if(low<high){
			mergeSort(nums,low,mid);
			mergeSort(nums,mid+1,high);
			merge(nums,low,mid,high);
		}
		else
			return;
	}
	
	public static void merge(int[] nums,int low,int mid,int high){
		int[] temp = new int[high-low+1];
		int left = low, right = high,center = mid+1;
		
		int i=0;
		while(low<=mid&¢er<=high){
			if(nums[low]<nums[center]){
				temp[i++] = nums[low];
				low++;
			}
			else{
				temp[i++] = nums[center];
				center++;
			}
		}
		while(low<=mid){
			temp[i++] = nums[low++];
		}
		while(center<=high){
			temp[i++] = nums[center++];
		}
		
		for(i=0;i<right-left+1;i++)
			nums[left+i] = temp[i];
		
		for(int j=0;j<nums.length;j++)
			System.out.print(nums[j]+" ");
		
		System.out.print("\n");	
		
	}</span>


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值