数据结构&算法-时间复杂度
Posted 彩色墨水
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构&算法-时间复杂度相关的知识,希望对你有一定的参考价值。
时间复杂度
计算机的性能体现主要是程序消耗时间和占用空间大小,如果一个程序算法实现同样的功能,所消耗的时间越短越好,占用的空间越小越好。这里就引入了时间复杂度的概念。
各复杂度消耗时间长度大小排序:
O(1)<O(logn)<O(n)<O(nlogn)<O(n2)<O(n3)<O(2n)<O(n!)<O(nn)
常见算法的时间复杂度
using System;
using System.Collections.Generic;
namespace TimeComplexity
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("时间复杂度");
Case c = new Case();
//c.BullsAndCows(100);
c.SortRandomNumList(20);
}
}
class Case
{
//等差数列求和:1+2+3+4+······+n
//----------时间复杂度 O(n)--------------------------
int NormCalcSum(int n)
{
int sum = 0;
for (int i = 0; i < n; i++)//执行n次
{
sum += i;
}
return sum;
}
//-----------------时间复杂度 O(1)-----------------------
int ArithCalcSum(int n)
{
int sum = 0;
sum = (1 + n) * n / 2;//执行1次
return sum;
}
}
}
//猜数字,数字1-n之间,猜中这个数字的次数
//------------------------时间复杂度 O(logn)------------------
public void BullsAndCows(int n)
{
Random rd = new Random();
int target = rd.Next(1, n);
int maxnum = n;
int mygustNumA = 0;
int mygustNumB = maxnum / 2;
int gusttimes = 0;
while (true)
{
gusttimes++;//最多执行logn次,这里其实是二分法,底数为2,但对于logn,n趋于无穷大时,底数是2还是10,不重要。
int temp = mygustNumB;
Console.WriteLine("猜测的次数:{0};目标数字:{1};我猜的数字:{2}", gusttimes, target, mygustNumB);
double ddd = Math.Abs(mygustNumB - mygustNumA) / 2d;
if (mygustNumB > target)
{
mygustNumB = mygustNumB - (int)Math.Round(ddd);
}
else if (mygustNumB < target)
{
mygustNumB = mygustNumB + (int)Math.Round(ddd);
}
else
break;
mygustNumA = temp;
}
}
//给无序数列排序
//------------------------时间复杂度 O(n²)------------------
public void SortRandomNumList(int n)
{
if (n < 1)
{
return;
}
Random rd = new Random();
List<int> myList = new List<int>();
while (n > 0)
{
myList.Add(rd.Next(1, 100));
n--;
}
Console.WriteLine("---------排序前-----------");
for (int i = 0; i < myList.Count; i++)
{
Console.WriteLine(myList[i]);
}
for (int i = 0; i < myList.Count; i++)
{
for (int j = i; j < myList.Count-1; j++)//冒泡排序,双层for循环
{
if (myList[i] > myList[j + 1])
{
int temp = myList[i];
myList[i] = myList[j + 1];
myList[j + 1] = temp;
}
}
}
Console.WriteLine("---------排序后---------");
for (int i = 0; i < myList.Count; i++)
{
Console.WriteLine(myList[i]);
}
}
//给无序数列排序
//------------------------时间复杂度 O(nlogn)------------------
public int[] GroupingArray(int[] array)
{
if (array == null || array.Length == 0)
{
return array;
}
if (array.Length == 2)//最终分组后只能是2个数或者1个数
{
Console.WriteLine("最小分拆数组:{0},{1};", array[0], array[1]);
int[] temp = new int[2];
if (array[0] < array[1])
{
temp[0] = array[0];
temp[1] = array[1];
}
else
{
temp[0] = array[1];
temp[1] = array[0];
}
return temp;
}
else if (array.Length == 1)//最终分组后只能是2个数或者1个数
{
Console.WriteLine("最小分拆数组:{0};", array[0]);
int[] temp = new int[1];
temp = array;
return temp;
}
else
{
int mid = array.Length / 2;
int[] left = new int[mid];
for (int i = 0; i < mid; i++)//分拆为两个数组
{
left[i] = array[i];
}
int[] right = new int[array.Length - mid];
for (int i = mid; i < array.Length; i++)//分拆为两个数组
{
right[i - mid] = array[i];
}
int[] templeft = GroupingArray(left);
int[] tempright = GroupingArray(right);//递归 logn
int[] colletArray = new int[templeft.Length + tempright.Length];
colletArray = SortSimpArray(templeft, tempright);//将两个数组排序
return colletArray;
}
}
/// <summary>
/// 两个有序的数组,合并排序
/// </summary>
/// <param name="left"></param>
/// <param name="right"></param>
/// <returns></returns>
int[] SortSimpArray(int[] left, int[] right)
{
int[] temp = new int[left.Length + right.Length];
int leftindex = 0;
int rightindex = 0;
for (int i = 0; i < temp.Length; i++)//执行n次
{
if (leftindex >= left.Length)
{
temp[i] = right[rightindex];
rightindex++;
}
else if (rightindex >= right.Length)
{
temp[i] = left[leftindex];
leftindex++;
}
else if (left[leftindex] < right[rightindex])
{
temp[i] = left[leftindex];
leftindex++;
}
else if (left[leftindex] >= right[rightindex])
{
temp[i] = right[rightindex];
rightindex++;
}
}
return temp;
}
以上是关于数据结构&算法-时间复杂度的主要内容,如果未能解决你的问题,请参考以下文章
Java 数据结构 & 算法宁可累死自己, 也要卷死别人 2 时间复杂度 & 空间复杂度