算法知识点

Sn的阶乘
T(n)=T(n-1)+O(1)=T(n-2)+2O(1)=…=T(1)+(n-1)O(1)=O(n)
全排列问题
T(n)=nT(n-1)=O(n!)
斐波那契数列
T(n)=O(2^n)
汉诺塔问题
T(n)=O(2^n)
选择、冒泡排序
T(n)=O(n^2)
分治法的基本思想:
将一个难以直接解决的大问题,分解为多个规模较小的相同子问题,各子问题相互独立,递归地解决各子问题,将子问题的解归并成原问题的解
二分查找:binarySearch
给定已排好序的n个元素s1…sn,在这n个元素中找到特定元素x
时间复杂度:
最好情况:O(1)
最坏情况:O(logn)
平均:O(logn)
合并排序:mergeSort
对n个元素进行排序
时间复杂度:
T(n)=O(1),n=1
T(n)=2T(n/2)+O(1)=O(n),n>1
快速排序:QuickSort
对n个元素进行排序
分:选定一个元素作为基准元素,小于基准元素的放左边,大于基准元素的放右边
治:递归求解子问题
取第一个元素为基准元素
通过一趟扫描将待排序的元素分割成三个独立的序列:第一个序列中所有元素均不大于基准元素,第二个序列中的元素是基准元素,第三个序列中的元素均大于基准元素。由于第二个元素已经处于正确位置,因此需要再按此方法将第一个序列和第三个序列分别进行排序,整个过程可以递归进行,最终可使整个序列变成有序序列。
时间复杂度:
最坏情况:O(n^2)
最好情况:O(nlogn)
平均:O(nlogn)
二分:
int BinarySearch(int s[n],int x,int low,int high)
{
 if (low>high) return -1;
 int middle=(low+high)/2;  
 if(x==s[middle]) return middle;
else if(x>s[middle])
      return BinarySearch (s, x, middle+1,
high);
   else
      return BinarySearch (s, x, low, middle-
1);
}    
合并
void Merge(int A[],int low,int middle,int high)
{
int i,j,k;
int *B=new int[high-low+1];
i=low; j=middle+1; k=0;
while(i<=middle&&j<=high)
if(A[i]<=A[j])   
B[k++]=A[i++];
   else            
B[k++]=A[j++];
while (i<=middle)
    B[k++]=A[i++];
while (j<=high)
   B[k++]=A[j++];
for(i=low, k=0; i<=high; i++)
A[i++]=B[k++];  }
快速排序
void QuickSort(int r[ ],int low,int high)

 int pivotpos; 
 if(low<high)
{
   pivotpos=Partition(r,low,high);
   QuickSort(r,low,pivotpos-1); 
   QuickSort(r,pivotpos+1,high); 
动态规划:
动态规划的解题步骤:
最优子结构性质分析 建立最优值的递归关系式 自底向上求最优值 构造最优解
思想:
将待求解问题分为若干个相互联系的子问题
在求解过程中将以求解的子问题的最优值进行保存,在需要时找出
用一个表来记录所有已解子问题的最优值,不管子问题是否被用到,都将其计算结果填入该表,需要时取出
根据最优值构造最优解
矩阵连乘问题:
stpe1:确定合适的数据结构。采用二维数组m来存放各子问题的最优值,二维数组来s来存放各个子问题的最优决策
step2:初始化。令m[i][i]=0,s[i][i]=0,其中i=1,2…n
step3:循环阶段:按照地推关系式计算两个矩阵AiAi+1相乘时的最优值并将其存入m[i][i+1],同时记录最优决策计入s[i][i+1],i=1,2,3…n。以此类推直到计算n个矩阵,将最优值和最优解记录到m[1][n],s[1][n]
step4:根据二维数组s记录的最优决策信息来构造最优解
时间复杂度:
T(n)=O(1),n=1
T(n)=T(n-1)+O(1)=O(n),n>1
递推关系式:
m[i][j]=0 ,i=j
m[i][j]=min[i][k]+m|k +1][j]+Pi-1PkPj },i< j
0-1背包问题:
约束条件:
(w1x1+w2x2+w3x3+…wnxn)≤W
xi=0或xi=1 ,1<=i<=n
目标函数:
max(v1x1+v2x2+…+vnxn)
递推关系式:
C[0][j]=C[i][0]=0
C[i][j]:
C[i-1][j] j<wi
max(C[i-1][j],C[i-1][j-wi]+vi) j≥wi
解的结构:
(x1,x2…xn),xi表示第i个物品的状态,xi=0表示物品不放入背包,xi=1表示物品放入背包
数据结构:
数组v[n]存放每个物品的价值
数组w[n]存放每个物品的重量
数组c[n+1][W+1]存放每一次迭代的结果
数组x[n]存放物品的状态
算法步骤:
输入:背包容量W,n个物品的重量和价值
输出:装入背包最优值和最优解
n<-物品个数
for i <-1 to n-1 do
for j<-1 to W do
if w[i]<=j then
c[i][j]<-max(c[i-1][j-w[i]]+v[i],c[i-1][j])
else
c[i][j]<-c[i-1][j]
j<-W
for i<-n until 0 do
if c[i][j]>c[i-1][j] then
x[i-1]<-1
j<-j-w[i-1]
return c[n][W],x
贪心算法:
思想:
从问题的某一个初始解出发,在每个阶段都根据贪心策略来做出当前最优的决策,逐步逼近给定的目标,尽可能快地求得更好的解,当进行到算法某一步不能继续前进时,算法结束
会议安排问题:
贪心策略:
优先安排结束时间早且不与已安排会议重叠的会议
根据结束时间从小到大排序
算法步骤:
输入:n个会议的开始和结束时间s[1,2,…n],f[1,2…n]
输出:会议状态x[1,2…n]
n<-会议个数
j<-1
for i<-2 to n do
if si>=fj then
x[i]<-1
j<-i
else
x[i]<-0
return x
多机作业调度问题
输入:m台机,n个作业,每个作业的处理时间t
输出:每台机器处理的任务序列,和每台机器的处理时间
num[1…m]=0;f[1…m]=0 //初始化
// 对t[1…n]按降序地址排序,排序结果返回到数组a[1…n]中
// 使得t[a[1]]>=t[a[2]]>=…>=t[a[n]]>.
a=sort(t,n)
for i = 1 to n:
j=min(f, m) //求f[1…m]的最小值对应的下标
num[j]=num[j]+1 //在第j台机器上安排作业a[i]
M[j,num[j]]=a[i]
f[j]=f[j]+t[a[i]]
end for
mint = max(f,m) //求f[1…m]的最大值
return mint,num,M
文字描述:
Step1:将输入的任务处理时间有大到小排序
Step2:首先将排列好的任务,安排前m(机器个数)个任务依次给所有机器。
Step3:比较机器当前处理时间,查找最先空闲的机器,将任务序列按顺序依次分配,并记录每台机器工作总时间。
Step:输出每个机器的任务分配及处理时间。
注:当任务总数小于等于机器数时,应直接考虑第二步。
O(n^2)
哈夫曼编码:
核心思想:让权值大的叶子离根近
输入:字符集C及每个字符出现的频率f(i),i∈C
输出:Q
n←|C|
Q←sort©//频率有小到大排序
for i←1 to n-1do
构造节点z
z.left←Q中频率第一小字符x
z.right←Q中频率第二小字符y
f(z)←f(x)+f(y)
insert(Q,z)
return Q
描述:
把字符看作孤立的根节点组树的集合,依次从集合中选择两个频率最小的字符,组成左右子树构造一个新树,新树的频率是左右子树频率之和,然后把新树插入到树的集合中,重复以上过程n-1次后构造出哈夫曼树,把左子树赋值为0,右子树赋值为1,从根到叶子的路径就是对应叶子字符的编码
单源最短路径:
数据结构:
顶点状态:s[i]=0或1 是否已找到源点到i点的最短路径
路径长度记录:dist数组
路径记录:前驱数组pre[]
算法:Dijkstra
输入:有向带权图G=(V,E,W),V={1,2,…,n},源点s=1。
输出:从s到每个顶点的最短路径pre
S[1]←1
dist[1]←0
pre[1]←0
for i←2 to n do
 dist[i]=w(s,i)//s到i没有边,则w(s,i)=∞
While V-S≠Ф do
 从V-S中取dist最短的路径顶点j
  S[j]←1
 for i←2 to n do
  if s[i]=0 and dist[j]+w(j,i)<dist[i] then
    dist[i]←dist[j]+w(j,i)
    pre[i]←j
return pre
最小生成树:
算法:Prim(G)
输入:无向带权图G,
输出:最小生成树T
U←{1},T←{ }
for i←1 to n do
 if G[1][i]<∞
   closest[i]←1
   lowcost←G[1][i]
while V-U≠Ф do
 从V-U中选择最小的lowcost[j]
 U←UU{j}
 T←T U{(closest[j],j)}
 for i←1 to n do
   if S[i]==0 and G[j][i]<lowcost[i]
      closest[i]←j
      lowcost[i]←G[j][i]
return T
T(n)=O(n^2)
算法:Kruskal
sort(E) //E为边集
T←Ф
j←0//记录加入的边的条数
for i←1 to |E| do//|E|是图中边的条数
 e←E[i]
 if e的两个端点不在同一个连通分支
 then
   T←{e}
   j←j+1
  if j=n-1//n为图顶点个数
    break;
return T
时间复杂度:T(n)=O(n(n-1))
是否形成回路:
Kruskal算法采用集合的性质来进行判定:
如果选择加入的边起点和终点都在T的集合里,那么就可以断定一定会形成回路

回溯法
搜索思想:
从根开始,以深度优先搜索的方式进行搜索
根节点是活节点并且是当前的扩展结点
在搜索的过程中,当前的扩展结点向纵深方向移动一个新节点,判断该新节点是否满足隐约束。
如果满足,则新节点成为活结点,并且成为当前的扩展结点,继续深一层的搜索
如果不满足,则换该新节点的兄弟节点继续搜索。如果新节点没有兄弟节点,或兄弟节点已全部搜索完毕,则扩展结点成为死节点,搜索回溯到其父节点处继续进行
搜索过程知道找到问题的解或根节点变成死节点为止
最长公共子序列
c[i][j]表示序列Xi和Yi的最长公共子序列的长度。
c[i][j]:0 i=0或j=0
c[i][j]: c[i-1][j-1]+1 i,j>0且xi=yi
c[i][j]:max(c[i][j-1],c[i-1],[j]) i,j>0; xi!=yi
算法步骤:
step1:确定合适的数据结构。采用二维数组c来存放各个子问题的最优值,二维数组b来存放各个子问题最优值的来源,b[i][j]=1表示c[i][j]由c[i-1][j-1]得到,b[i][j]=2表示c[i][j]由c[i][j-1]得到,b[i][j]=3表示c[i][j]由c[i-1][j]得到。数组x[1:m]和y[1:n]分别存放X序列和Y序列
step2:初始化。令c[i][0]=0,c[0][j]=0,其中0≤i≤m,0≤j≤n
step3:循环阶段。根据递推关系式依次求出最优值c[i][j],同时记录b[i][j],直到c[m][n]便是序列X和Y的最长公共子序列
step4:根据二维数组b记录的相关信息以自底向上的方式来构造最优解
图的m可着色问题
解的形式:(x1,x2…xn),表示第i个节点着xi号颜色
解空间组织结构:满m叉树,树的深度为n
约束条件:和已确定颜色且有边相连的顶点颜色不同
限界条件:不需要
约束函数:
def Ok(k):
 for j in range(1,k):
   if ((a[k][j]==1) and (x[j]==x[k])):
     return False
 return True
时间复杂度:T(n)=O(nm^n) +O(nmn)=O(nmn)`
旅行售货员问题
解的形式:(x1,x2…xn),xi=1表示城市i在最短路线中,xi=0表示城市i不在最短路线中,其中起始点x1=1
解空间组织结构:深度为n排列树
约束条件:
用a[][]来存储无向带权图的邻接矩阵,如果a[i][j]不等于无穷大则表示城市i和城市j有边相连,能走通
限界条件:
cl<bestl
cl:当前已走过城市的路径长度
bestl:当前已找到最短路径的路径长度
时间复杂度:T(n)=O(n!)+O(n!)=O(n!)
n皇后问题
解的形式为(x1, x2, … , xn),xi表示第i个皇后位于第i行、第xi列
(i=1,2,3,…n)
初始状态为:(0,0,…,0)
解空间的组织结构可以是排列树,也可以是满n叉树。
只需要设置约束条件,不需要限界条件。
约束条件:不同列且不同斜线
解向量中的任意两个分量xi,xj满足:xi≠xj且|i-j|≠|xi-xj|
输入 N // 输入皇后的个数
q[1…N] //存储每行的皇后的具体位置(列标)
n_queens(k , n): // 确定第 k 行皇后的位置
if k > n: // 递归的出口
Print q // 输出各个皇后的位置
else:
for j <- 1 to n: // 从第 k 行第 1 列开始,判断各个位置是否可行
if isSafe(k , j): // 如果可行,继续判断下一行
q[k] <- j // 将第 k 行皇后放置的位置 j 记录下来
n_queens(k+1 , n) // 继续判断下一行皇后的位置
O(n*n!)
最大团
问题描述:找出包含顶点最多的团(完全图)
解的形式:(x1,x2…xn),xi表示第i个顶点是否在最大团中,xi=1表示在最大团中,xi=0表示不在最大团中
解空间结构:满二叉树深度为n或n+1
约束条件:任意两点间都有边相连
限界条件:
cn+rn>bestn
cn:当前在顶点集中的顶点个数
rn:剩余顶点个数
bestn:最优解包含的顶点个数
约束函数:
def place(t):
OK = True
for j in range(t):
if x[j] and a[t][j]==0
OK = False
break
return OK
E

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数据结构算法知识点包括以下内容: 1. 数据结构数据结构是指数据元素之间的关系和组织方式。常见的数据结构包括线性结构(如数组、链表、栈、队列)、树形结构(如二叉树、堆、哈夫曼树)和图形结构(如邻接矩阵、邻接表)\[1\]。 2. 算法算法是解决问题的一系列步骤或规则。常见的算法包括排序算法(如冒泡排序、快速排序、归并排序)、搜索算法(如线性搜索、二分搜索)、图算法(如深度优先搜索、广度优先搜索)和动态规划算法\[2\]。 3. 动态规划:动态规划是一种通过将问题拆分成一系列重复的子问题来求解问题的方法。它通常以自底向上的方式解决子问题,并将子问题的结果存储起来以避免重复计算\[2\]。 4. 贪心算法:贪心算法是一种通过每次选择局部最优解来得到整体最优解的方法。它通常以自顶向下的方式进行,每次作出贪心选择后将问题简化为规模更小的子问题\[3\]。 5. 位操作:位操作是在二进制数字符号的层面上进行的操作。它可以用来进行快速的比较和计算,比如按位与、按位或、按位异或等操作\[3\]。 这些知识点数据结构算法中的基础,掌握它们可以帮助我们更好地理解和解决各种问题。 #### 引用[.reference_title] - *1* [数据结构算法——知识点总结](https://blog.csdn.net/qq_41750911/article/details/125041841)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [数据结构算法知识点总结](https://blog.csdn.net/weixin_40922285/article/details/103183295)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值