数据结构与算法

最好到最坏的常用算法复杂度排序如下:
常数级O(1)、
对数级O(logn)、
线性级O(n)、
线性对数级(nlogn)、
平方级O(n^2)、
立方级O(n^3)、
指数级O(2^n)等。

排序算法

  以下是对

https://www.cnblogs.com/manshufeier/p/9364178.html

的总结

内排序
分类排序法最差时间分析平均时间复杂度空间复杂度稳定性
插入排序直接插入排序O(n^2)O(n^2)O(1)O(1)稳定
希尔排序O(n^2)O(n^1.3)-O(n^2)O(1)O(1)不稳定
交换排序冒泡排序O(n^2)O(n^2)O(1)O(1)稳定
快速排序O(n^2)O(nlogn)O(logn)~O(n)不稳定
选择排序简单选择排序O(n^2)O(n^2)O(1)O(1)不稳定
堆排序O(nlogn)O(nlogn)O(1)O(1)不稳定
归并排序2路归并排序O(nlogn)O(nlogn)O(n)稳定

常用排序算法的性能与待排数组的循序的关系作一个总结:

1)冒泡:无关;
2)选择:无关;
3)插入:有关,有序程度越大,比较越少;
4)shell:有关,它的基本思想基于插入排序;
5)合并:有关,有序程度愈大,合并过程的比较次数越少;
6)堆排序:有关,有序程度越大,建立堆下沉操作越少;
7)快排序:有关,如果选择最后值作为阀值,那么有序程度越好,就越可能退化成O(n^2);

摘要:内排序是在排序整个过程中,待排序的所有记录全部被放置在内存中。在数据结构里表示复杂度\log就是\log_{2}

外排序:

外排序是由于排序的记录个数太多,不能同时放置在内存,整个排序过程需要在内外存之间多次交换数据才能进行。

1、多路平衡归并排序 

2、置换-选择排序 

3、最佳归并树形排序

按照算法的复杂度分为两大类:

1.简单算法:冒泡排序、简单选择排序、直接插入排序

2.改进算法:希尔排序、堆排序 、归并排序、快速排序

使用了分治思想的排序算法

堆排序

 思想:将待排序序列构造成一个大顶堆,然后再进行排序,每次交换较大值都需要重新构造大顶堆

import java.util.Arrays;

public class HeapSort {
	
	public static void main(String[] args) {
		int[] arr = new int[] {9,6,8,7,0,1,10,4,2};
		heapSort(arr);
		System.out.println(Arrays.toString(arr));
	}
	
	public static void heapSort(int[] arr) {
		//开始位置是最后一个非叶子节点,即最后一个节点的父节点
		int start = (arr.length-1)/2;
		//调整为大顶堆
		for(int i=start;i>=0;i--) {
			maxHeap(arr, arr.length, i);
		}
		//先把数组中的第0个和堆中的最后一个数交换位置,再把前面的处理为大顶堆
		for(int i=arr.length-1;i>0;i--) {
			int temp = arr[0];
			arr[0]=arr[i];
			arr[i]=temp;
			maxHeap(arr, i, 0);
		}
	}
	
	public static void maxHeap(int[] arr,int size,int index) {
		//左子节点
		int leftNode = 2*index+1;
		//右子节点
		int rightNode = 2*index+2;
		int max = index;
		//和两个子节点分别对比,找出最大的节点
		if(leftNode<size&&arr[leftNode]>arr[max]) {
			max=leftNode;
		}
		if(rightNode<size&&arr[rightNode]>arr[max]) {
			max=rightNode;
		}
		//交换位置
		if(max!=index) {
			int temp=arr[index];
			arr[index]=arr[max];
			arr[max]=temp;
			//交换位置以后,可能会破坏之前排好的堆,所以,之前的排好的堆需要重新调整
			maxHeap(arr, size, max);
		}
	}

}

归并排序

 思想:两两合并排序后再合并排序

https://img-blog.csdn.net/20180812232926378?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM2NDQyOTQ3/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70

import java.util.Arrays;

public class MergeSort {

	public static void main(String[] args) {
		int[] arr = new int[] {1,3,5,2,4,6,8,10};
		System.out.println(Arrays.toString(arr));
		mergeSort(arr, 0, arr.length-1);
		System.out.println(Arrays.toString(arr));
	}
	
	//归并排序
	public static void mergeSort(int[] arr,int low,int high) {
		int middle=(high+low)/2;
		if(low<high) {
			//处理左边
			mergeSort(arr, low, middle);
			//处理右边
			mergeSort(arr, middle+1, high);
			//归并
			merge(arr,low,middle,high);
		}
	}
	
	public static void merge(int[] arr,int low,int middle, int high) {
		//用于存储归并后的临时数组
		int[] temp = new int[high-low+1];
		//记录第一个数组中需要遍历的下标
		int i=low;
		//记录第二个数组中需要遍历的下标
		int j=middle+1;
		//用于记录在临时数组中存放的下标
		int index=0;
		//遍历两个数组取出小的数字,放入临时数组中
		while(i<=middle&&j<=high) {
			//第一个数组的数据更小
			if(arr[i]<=arr[j]) {
				//把小的数据放入临时数组中
				temp[index]=arr[i];
				//让下标向后移一位;
				i++;
			}else {
				temp[index]=arr[j];
				j++;
			}
			index++;
		}
		//处理多余的数据
		while(j<=high) {
			temp[index]=arr[j];
			j++;
			index++;
		}
		while(i<=middle) {
			temp[index]=arr[i];
			i++;
			index++;
		}
		//把临时数组中的数据重新存入原数组
		for(int k=0;k<temp.length;k++) {
			arr[k+low]=temp[k];
		}
	}

}

快速排序

思想:选取一个关键字使他左边的值都比他小,右边的值都比他大,然后左边和右边进行相同的操作。

import java.util.Arrays;

public class QuickSort {

	public static void main(String[] args) {
		int[] arr = new int[] {3,4,6,7,2,7,2,8,0,9,1};
		quickSort(arr,0,arr.length-1);
		System.out.println(Arrays.toString(arr));
	}
	
	public static void quickSort(int[] arr,int start,int end) {
		if(start<end) {
			//把数组中的第0个数字做为标准数
			int stard=arr[start];
			//记录需要排序的下标
			int low=start;
			int high=end;
			//循环找比标准数大的数和比标准数小的数
			while(low<high) {
				//右边的数字比标准数大
				while(low<high&&stard<=arr[high]) {
					high--;
				}
				//使用右边的数字替换左边的数
				arr[low]=arr[high];
				//如果左边的数字比标准数小
				while(low<high&&arr[low]<=stard) {
					low++;
				}
				arr[high]=arr[low];
			}
			//把标准数赋给低所在的位置的元素
			arr[low]=stard;
			//处理所有的小的数字
			quickSort(arr, start, low);
			//处理所有的大的数字
			quickSort(arr, low+1, end);
		}
	}

}

 

 

一、综合实战—使用极轴追踪方式绘制信号灯 实战目标:利用对象捕捉追踪和极轴追踪功能创建信号灯图形 技术要点:结合两种追踪方式实现精确绘图,适用于工程制图中需要精确定位的场景 1. 切换至AutoCAD 操作步骤: 启动AutoCAD 2016软件 打开随书光盘中的素材文件 确认工作空间为"草图注释"模式 2. 绘图设置 1)草图设置对话框 打开方式:通过"工具→绘图设置"菜单命令 功能定位:该对话框包含捕捉、追踪等核心绘图辅助功能设置 2)对象捕捉设置 关键配置: 启用对象捕捉(F3快捷键) 启用对象捕捉追踪(F11快捷键) 勾选端点、中心、圆心、象限点等常用捕捉模式 追踪原理:命令执行时悬停光标可显示追踪矢量,再次悬停可停止追踪 3)极轴追踪设置 参数设置: 启用极轴追踪功能 设置角度增量为45度 确认后退出对话框 3. 绘制信号灯 1)绘制圆形 执行命令:"绘图→圆→圆心、半径"命令 绘制过程: 使用对象捕捉追踪定位矩形中心作为圆心 输入半径值30并按Enter确认 通过象限点捕捉确保圆形位置准确 2)绘制直线 操作要点: 选择"绘图→直线"命令 捕捉矩形上边中点作为起点 捕捉圆的上象限点作为终点 按Enter结束当前直线命令 重复技巧: 按Enter可重复最近使用的直线命令 通过圆心捕捉和极轴追踪绘制放射状直线 最终形成完整的信号灯指示图案 3)完成绘制 验证要点: 检查所有直线是否准确连接圆心和象限点 确认极轴追踪的45度增量是否体现 保存绘图文件(快捷键Ctrl+S)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值