算法时间复杂度以及代码实现
来源:互联网 发布:mac上如何打开rar文件 编辑:程序博客网 时间:2024/06/03 09:09
1 插入的时间复杂度
附:选择排序:思想为从所有序列中找最小的放第一个位置,之后从剩余的元素中找最小的放第二个位置,直到所有的。时间复杂度为O(n*n)。
折半插入排序(二分插入排序):在直接插入排序的基础上,对插入A[i]进行了修改,直接插入排序是从后向前比较,而折半插入排序为直接从A[i-1/2]那个位置进行比较,大了在[i-1/2]-A[i-1]查找,否则在A[0]-A[i-1/2]找,比直接插入减少了比较次数,单是元素移动次数不变,所以,时间复杂度仍为O(n^2)。
2 查找的时间复杂度
2.1 二分查找
二分查找又称折半查找,优点是查找速度快,平均性能好,缺点是待查表为有序表,且插入、删除困难。适用于:不经常变动而查找频繁的有序列表。
根据比较中间关键字来查找需要查找的关键字。
二分查找法的时间复杂度是O(log(n)),最坏情况下为O(n)
3代码实现
3.1 冒泡排序
package sort;
/*
比较相邻的元素,如果第一个比第二个大,则交换他们两个,依次类推
平均O(n*2) 最坏O(n*2),最好O(n) 空间O(1) 稳定,简单
输出为:
排序前为:1 4 6 2 3 7 9 5 10 0
排序后为:0 1 2 3 4 5 6 7 9 10
* */
public class BubbleSort {
public static void bubbleSort(int[] numbers){
int length=numbers.length;
int j,temp;
System.out.print("排序前为:");
for(j=0;j<length;j++){
System.out.print(numbers[j]+" ");
}
System.out.println();
for(int i=0;i<length-1;i++){
for(j=0;j<length-1-i;j++){
if(numbers[j]>numbers[j+1]){
temp=numbers[j];
numbers[j]=numbers[j+1];
numbers[j+1]=temp;
}
}
}
System.out.print("排序后为:");
for(j=0;j<length;j++){
System.out.print(numbers[j]+" ");
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] numbers={1,4,6,2,3,7,9,5,10,0};
bubbleSort(numbers);
}
}
3.2 快速排序
下面为数组输出函数
public static void printArray(int[] num){
for(int i=0;i<num.length;i++){
System.out.print(num[i]+" ");
}
}
/*
快速排序(平均为:O(nlogn),最坏为O(n*n) ,最好为O(nlogn),空间为O(nlogn),不稳定,较复杂)
从数列中挑出一个元素,称为基准,重新排列数列,所有比基准小的放到基准之前,所有比基准大的放到基准后面,之后递归的进行排列
输出为:
基准为:4排序后为:-4 0 2 1 3 4 9 5 10 7 11 6
基准为:-4排序后为:-4 0 2 1
基准为:0排序后为:0 2 1
基准为:2排序后为:1 2
基准为:9排序后为:6 5 7 9 11 10
基准为:6排序后为:5 6
基准为:11排序后为:10 11
结果为:
快速排序原先数组为:
4 6 2 1 3 7 9 5 10 0 11 -4 12
快速排序结果为:
-4 0 1 2 3 4 5 6 7 9 10 11 12
*
*/
public static void quickSort(int[] numbers,int start,int end){
int cir=0;
int base=numbers[start];
if(start<end){
int i=start,j=end;
while(i<j){
while(i<j&&numbers[j]>base)
j--;
numbers[i]=numbers[j];
while(i<j&&numbers[i]<base)
i++;
numbers[j]=numbers[i];
}
numbers[i]=base;
/*System.out.print("基准为:"+base+"排序后为:");
for(cir=start;cir<end;cir++){
System.out.print(numbers[cir]+" ");
}
System.out.println("");
*/
quickSort(numbers,start,i-1);
quickSort(numbers,i+1,end);
}
}
/*快速排序 start*/
int[] numbers={4,6,2,1,3,7,9,5,10,0,11,-4,12};
System.out.println("快速排序原先数组为:");
printArray(numbers);
quickSort(numbers,0,numbers.length-1);
System.out.println("\n快速排序结果为:");
printArray(numbers);//*****因为numbers为数组类型,调用函数交换为其内部的值已经发生改变,只需输出即可
/*快速排序 end*/
3.3 选择排序
/*
选择排序-平均-最坏-最好,均为O(n*n),
在未排序中找到最小的放在起始位置,再从剩余未排序的找出最小元素,依次类推
输出为:
选择排序原先数组为:
4 6 2 1 3 7 9 5 10 0 11 -4 12
选择排序结果为:
-4 0 1 2 3 4 5 6 7 9 10 11 12
*/
public static void selectSort(int[] num){
int length=num.length;
int i,j,min = 0;
for(i=0;i<length-1;i++){
min=i;
for(j=i+1;j<length;j++){
if(num[min]>num[j]){
min=j;
}
}
if(min==i){ //第一个为最小的元素,无需交换
//System.out.println();
//System.out.println(" 第"+(i+1)+"无需移动,值为: "+num[i]);
}else{ //需要交换
//System.out.println();
//System.out.println(" 第"+(i+1)+"与第"+(min+1)+"个交换,值分别为 "+num[i]+"和"+num[min]);
int temp=num[i];
num[i]=num[min];
num[min]=temp;
}
}
}
主方法调用为:
/*选择排序 start*/
int[] numbers2={4,6,2,1,3,7,9,5,10,0,11,-4,12};
System.out.println("\n\n选择排序原先数组为:");
printArray(numbers2);
selectSort(numbers2);
System.out.println("\n选择排序结果为:");
printArray(numbers2);
/*选择排序 end*/
3.4 插入排序
/*
插入排序:平均为O(n*n),最坏O(n*n),最好O(n),空间为O(1),稳定,简单
1.从第一个元素开始,该元素已经被认为排好序了
2.取下一个元素,在已经排好序的元素中,从后向前排
3.如果该元素大于新元素,将该元素移到下一个位置
4.重复步骤3,直到找到已排好序的元素小于或者等于新元素的位置
5.将新元素插入到该位置
6.重复步骤2
输出为:
插入排序原先数组为:
4 6 2 1 3 7 9 5 10 0 11 -4 12
插入排序结果为:
-4 0 1 2 3 4 5 6 7 9 10 11 12
*/
public static void insertSort(int[] num){
int length=num.length;
int temp,j;
for(int i=1;i<length;i++){
temp=num[i];//新的元素
for(j=i;j>0&&temp<num[j-1];j--){
num[j]=num[j-1];
}
num[j]=temp;
}
}
主方法调用:
/*插入排序 start*/
int[] numbers3={4,6,2,1,3,7,9,5,10,0,11,-4,12};
System.out.println("\n\n插入排序原先数组为:");
printArray(numbers3);
insertSort(numbers3);
System.out.println("\n插入排序结果为:");
printArray(numbers3);
/*插入排序 end*/
3.5 希尔排序
/*
希尔排序:平均为O(nlogn),最坏O(nlogn),最好无,空间为O(1),不稳定,较复杂
概念:希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。
步骤:先取一个小于n的整数d1作为第一个增量,把文件的全部记录分组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量
=1(<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。
*****一般的初次取序列的一半为增量,以后每次减半,直到增量为1。
实例:
希尔排序原先数组为:
16 4 6 2 1 3 7 9 5 10 0 11 -4 15
希尔排序结果为:
-4 0 1 2 3 4 5 6 7 9 10 11 15 16
*/
public static void shellSort(int[] num) {
int length=num.length,j;
for(int increase=length/2;increase>=1;increase/=2){
//System.out.println("increase="+increase);
for(int i=increase;i<length;i++){ //下面为插入排序
int temp=num[i];
//System.out.println("temp="+temp+" num["+i+"]="+num[i]);
for(j=i;j>=increase&&temp<num[j-increase];j-=increase){
//System.out.println("num["+j+"]="+num[j]+"num["+(j-increase)+"]="+num[(j-increase)]+" increase="+increase);
num[j]=num[j-increase];
}
num[j]=temp;
//System.out.println(" num["+j+"]="+num[j]);
}
}
}
主方法调用:
/*希尔排序 start*/
int[] numbers4={16,4,6,2,1,3,7,9,5,10,0,11,-4,15};
System.out.println("\n\n希尔排序原先数组为:");
printArray(numbers4);
shellSort(numbers4);
System.out.println("\n希尔排序结果为:");
printArray(numbers4);
/*希尔排序 end*/
3.6 归并排序
/*
归并排序:平均为O(nlogn),最坏O(nlogn),最好O(nlogn),空间O(n),稳定,较复杂
将一个数组分为2个,2个分为4个,一直到只有1个元素,后再开始合并元素,4合为2,2合为1,即可。
实例:
归并排序原先数组为:
16 4 6 2 1 3 7 9 5 10 0 11 -4 15
归并排序结果为:
-4 0 1 2 3 4 5 6 7 9 10 11 15 16
*/
public static void merge(int[] num,int low,int mid,int high){
int[] num1=new int[high-low+1]; //重新开辟空间,此时num1从0开始
//合并num[low..mid]与num[mid+1..high]为num[low..high]
int i,j,k=0; //注意k是从0开始
for(i=low,j=mid+1;i<=mid&&j<=high;k++){
if(num[ i]<num[j]){
num1[k]=num[i];
i++;
}else{
num1[k]=num[j];
j++;
}
}
if(i<=mid){ //前半段剩下的复制到num1数组中
for(;i<=mid;i++,k++){
num1[k]=num[i];
}
}
if(j<=high){ //后半段剩下的复制到num1数组中
for(;j<=high;j++,k++){
num1[k]=num[j];
}
}
for(i=low,k=0;i<=high;i++,k++){
num[i]=num1[k];
}
}
public static void MergSort(int[] num,int low,int high){ //将num[low..high]归并排序到num1[low..high]
if(low==high){ //无需交换
}else{ //归并开始排序
int mid=(low+high)/2;
MergSort(num,low,mid);
MergSort(num,mid+1,high);
merge(num,low,mid,high);
}
}
主方法调用:
/*归并排序 start*/
int[] numbers5={16,4,6,2,1,3,7,9,5,10,0,11,-4,15};
System.out.println("\n\n归并排序原先数组为:");
printArray(numbers5);
MergSort(numbers5,0,numbers5.length-1);
System.out.println("\n归并排序结果为:");
printArray(numbers5);
/*归并排序 end*/
3.7 堆排序
/*
堆排序:最好最坏平均均为O(nlogn),空间为O(1),不稳定,较复杂
整个过程为建堆和交换的过程,从第一个非叶子节点开始,比较节点和它的左右子节点,保证最大的为根节点
实例:
堆排序原先数组为:
16 4 6 2 1 3 7 9 5 10 0 11 -4 15
堆排序结果为:
-4 0 1 2 3 4 5 6 7 9 10 11 15 16
*/
public static void heapSort(int[] array){
buildHeap(array);
int n=array.length;
int i=0;
for(i=n-1;i>0;i--){
swap(array,0,i);
heapify(array,0,i-1); //注意**********调整时,不算已经排好序的最后一个
}
}
public static void buildHeap(int[] array){//构建堆
int n=array.length;
for(int i=n/2-1;i>=0;i--){
heapify(array,i,n-1);//调整堆,其中n-1为最大的边界值,即最后一个数字
}
}
public static void heapify(int[] num,int index,int max){
int left=2*index+1;
int right=2*index+2;
int largest=0;
if(left<=max&&num[left]>num[index]){ //注意顺序***left<=max与num[left]>num[index]
largest=left;
}else{
largest=index;
}
if(right<=max&&num[largest]<num[right]){ //
largest=right;
}
if(largest!=index){
swap(num,largest,index);
heapify(num,largest,max);
}
}
public static void swap(int[] array,int i,int j){
int temp=array[i];
array[i]=array[j];
array[j]=temp;
}
主方法调用:
/*堆排序 start*/
int[] numbers6={16,4,6,2,1,3,7,9,5,10,0,11,-4,15};
System.out.println("\n\n堆排序原先数组为:");
printArray(numbers6);
heapSort(numbers6);
System.out.println("\n堆排序结果为:");
printArray(numbers6);
/*堆排序 end*/
- 算法时间复杂度以及代码实现
- JS实现各种排序算法以及时间复杂度
- 快速排序算法原理,实现,以及时间复杂度分析
- 常用排序算法以及时间复杂度
- 常用排序算法以及时间复杂度(转)
- 排序算法的C语言实现以及各个算法的时间复杂度和空间复杂度分析(冒泡排序)
- 常用排序算法的时间复杂度以及空间复杂度
- 排序算法的时间复杂度以及空间复杂度 计数排序
- 排序算法的时间复杂度以及空间复杂度
- 常见排序算法以及时间复杂度和空间复杂度
- 快速排序实现以及时间复杂度分析
- 快速排序实现以及时间复杂度分析
- 各种常用排序的时间复杂度和稳定性以及代码实现
- 常用排序算法、时间复杂度、实现思路
- 算法 时间复杂度|空间复杂度
- 算法 时间复杂度|空间复杂度
- 算法 时间复杂度|空间复杂度
- 算法时间复杂度&空间复杂度
- netty学习(四)----伪异步IO的弊端
- POJ 3414 Pots
- [Android界面] 导航栏下划线出现偏移
- Leetcode: H-Index II
- leetcode: (235) Lowest Common Ancestor of a Binary Search Tree
- 算法时间复杂度以及代码实现
- 移动端布局浅谈
- 简单四则运算
- 解决方案:An error was encountered while running(Domain=FBSOpenApplicationErrorDomain, Code=4)
- Hadoop 案例6-----TopN问题:求最大的K个值并排序
- SQL Server 根据表名获取表的所有列及属性
- Learning Markdown
- GdiPlus控件Static和Button的使用
- java 平衡二叉树的实现