Example:二分法

以下递归算法搜索排序数组中的值:

search(v,a,lo,hi):
|  Input  value v
|         array a[lo..hi] of values
|  Output true if v in a[lo..hi]
|         false otherwise
|
|  mid=(lo+hi)/2
|  if lo>hi then return false
|  if a[mid]=v then
|     return true
|  else if a[mid]<v then
|     return search(v,a,mid+1,hi)
|  else
|     return search(v,a,lo,mid-1)
|  end if

Cost analysis:

  • Ci = #calls to search() for array of length i
  • for best case, Cn = 1,刚好在中间
  • for   a[i..j]j<i (length=0) 数组为空
    • C0 = 0
  • for a[i..j]i≤j (length=n)
    • Cn = 1 + Cn/2   ⇒ Cn =

Thus, binary search is O() or simply O(logn)   (why?

总共有n个元素,每次查找的区间大小就是n,n/2,n/4,…,n/2^k(接下来操作元素的剩余个数),其中k就是循环的次数。

由于n/2^k取整后>=1,即令n/2^k=1,

可得k=log2n,(是以2为底,n的对数),所以时间复杂度可以表示O()=O(logn)。

相关数学公式

Exercise: Analysis of Algorithms

求复杂度

enqueue(Q,Elem):
|  Input  queue Q, element Elem
|  Output Q with Elem added at the end
|
|  Q.top=Q.top+1
|  for all i=Q.top down to 1 do
|     Q[i]=Q[i-1]
|  end for
|  Q[0]=Elem
|  return Q

Answer: O(|Q|)

binaryConversion(n):
|  Input  positive integer n
|  Output binary representation of n on a stack
|
|  create empty stack S
|  while n>0 do
|  |  push (n mod 2) onto S
|  |  n=n/2 log n
|  end while
|  return S

Answer: O(log n)

Relatives of Big-Oh

big-Omega

  • f(n) ∈ Ω(g(n)) 如果有连续的 c > 0 和连续整数 n0 ≥ 1 使得

    f(n) ≥ c·g(n)    ∀n ≥ n0

big-Theta

  • f(n) ∈ Θ(g(n)) if there are constants c',c'' > 0 and an integer constant n0 ≥ 1 such that

    c'·g(n) ≤ f(n) ≤ c''·g(n)    ∀n ≥ n0

当f(n)渐近小于或等于g(n)时,f(n)属于O(g(n))

当f(n)渐近地大于或等于g(n)时,f(n)属于Ω(g(n))

当f(n)渐近等于g(n)时,f(n)属于Θ(g(n))

  • ¼n2 ∈ Ω(n2)

    • need c > 0 and n0 ≥ 1 such that ¼n2 ≥ c·n2 for n≥n0
    • let c=¼ and n0=1
  • ¼n2 ∈ Ω(n)
    • need c > 0 and n0 ≥ 1 such that ¼n2 ≥ c·n for n≥n0
    • let c=1 and n0=4
  • ¼n2 ∈ Θ(n2)
    • since ¼n2 belongs to Ω(n2) and O(n2)

Static/Dynamic Sequences 静态 动态序列

以前我们使用数组来实现堆栈:

均匀元素的固定大小集合

可通过索引或“移动”指针访问

“固定大小”方面是一个潜在的问题:

(动态)数组有多大(大…以防万一)

如果满了怎么办?

刚性序列是另一个问题:

在数组中间插入/删除项

使用数组的问题可以通过 单独分配元素 把它们连在一起形成一条“链” 来解决

好处:

插入/删除对列表整体的影响最小

仅使用值所需的空间

要实现“元素链”,需要node包含

指向下一个节点的链接


要表示节点的链表,请执行以下操作:

我们需要一个指向第一个节点的指针

每个节点都包含指向下一个节点的指针

最后一个节点中的下一个指针为空

链表比数组更灵活:

值不必在内存中相邻

只需改变指针就可以重新排列值

值的数量可以动态更改

可以按任何顺序添加或删除值

缺点:

指针操作出错并不难

每个值还需要存储指向下一个的指针

makeNode(v)
|  Input  value v
|  Output new linked list node with value v
|
|  new.value=v      // initialise data
|  new.next=NULL    // initialise link to next node
|  return new       // return pointer to new node

Exercise: Creating a Linked List

Write pseudocode to create a linked list of three nodes with values 1, 42 and 9024.

mylist=makeNode(1) //get a new node
mylist.next=makeNode(42)
(mylist.next).next=makeNode(9024)

要访问当前节点中的数据:p.value

获取指向下一个节点的指针:p.next

要遍历链表,请执行以下操作:

将p设置为指向第一个节点(头部); 检查p指向的节点;将p改为指向下一个节点;当p到达列表末尾时停止(NULL)

Print all elements:

showLL(L):
|  Input linked list L
|
|  p=L
|  while p≠NULL do
|     print p.value
|     p=p.next
|  end while

Time complexity: O(|L|)

❖ Exercise: Traversing a linked list

What does this code do?

1  p=list
2  while p≠NULL do
3  |  print p.value
4  |  if p.next≠NULL then
5  |     p=p.next.next
6  |  else
7  |     p=NULL
8  |  end if
9  end while

每隔一个输出一个元素

如果p恰好是列表中的最后一个元素,那么p.next.next就不存在。

if语句确保我们不会试图将未定义的值赋给第5行中的指针p。

//判断next是否存在,存在把next.next赋值给p输出

❖ Exercise: Traversing a linked list

Rewrite showLL() as a recursive function.

showLL(L):
|  Input linked list L
|  if L≠NULL do
|     print L.value
|     showLL(L.next)
|  end if

Modifying a Linked List 修改链表

//在最前端插入
insertLL(L,d):Input  linked list L, value dOutput L with d prepended to the listnew=makeNode(d)  // create new list elementnew.next=L       // link to beginning of listreturn new       // new element is new head

O(1)

//Delete the first element:
deleteHead(L):Input  non-empty linked list L, value dOutput L with head deletedreturn L.next    // move to second element

//Delete a specific element (recursive version):

deleteLL(L,d):
|  Input  linked list L
|  Output L with element d deleted
|
|  if L=NULL then            // element not in list
|     return L
|  else if L.value=d then    // d found at front
|     return deleteHead(L)   // delete first element
|  else                      // delete element in tail list
|     L.next=deleteLL(L.next,d)
|  end if
|  return L

Time complexity: O(|L|)

Exercise: Implementing a Queue as a Linked List

基于链表为队列开发数据结构,以便…

元素排队需要固定的时间

元素出列需要固定的时间

Dequeue from the front …

dequeue(Q):
|  Input  non-empty queue Q
|  Output front element d, dequeued from Q
|
|  d=Q.front.value        // first element in the list
|  Q.front=Q.front.next   // move to second element
|  return d

Enqueue at the rear …

enqueue(Q,d):
|  Input queue Q
|
|  new=makeNode(d)     // create new list element
|  Q.rear.next=new     // add to end of list
|  Q.rear=new          // link to new end of list

Comparison Array vs. Linked List

array linked list
insert/delete at beginning O(n) O(1)
insert/delete at end O(1)
 
O(1)
("doubly-linked" list, with pointer to rear)
insert/delete at middle O(n) O(n)
find an element O(n)
(O(log n), if array is sorted)
O(n)
 
index a specific element O(1) O(n)

Complexity Classes

Classes of problems:

  • P = problems for which an algorithm can compute answer in polynomial time
  • NP = includes problems for which no P algorithm is known

简单示例:检查整数n是否为素数

生成/测试n的所有可能因素

如果他们都不通过测试⇒ n是素数

生成过程很简单:

生成从2到n-1的所有数字的序列

测试也很简单:

检查下一个数字是否正好除以n

21T2-COMP9024-week02 lec02相关推荐

  1. COMP9024 22T1Prof Aaron Quigley

    有需要的朋友qq 1703105484 COMP9024 22T1 Prof Aaron Quigley Large Assignment The World of Worlde Thanks to ...

  2. COMP9024笔记

    文章目录 General Question Programming in C Struct 结构体 typedef 与 #define Linked List 链表 Week 01 Introduct ...

  3. c语言字符AABB连续出现KMp,COMP9024 知识点整理+19T1 Final Exam试卷

    目录 关于 2019T1 COMP9024 相关的 1. 课程信息 2. 知识点梳理 3. 期末试卷(回忆版) 1. 课程信息 1.1 Lecturer: Wu Hui 1.2 Programming ...

  4. 21T2 9024-Week 01

    目录 printf Loops Functions Data Types Aggregate Data Types Arrays scanf and atoi Arrays and Functions ...

  5. 【411】COMP9024 Assignment1 问题汇总

    1. 构建 Makefile 文件后运行错误,undefined reference to 'sqrt' 实际上是没有链接math数学库,所以要 $gcc test.c –lm //-lm就是链接到m ...

  6. 【423】COMP9024 Revision

    目录: array '\0' 与 EOF 二维字符数组(字符串数组) 1. array: 参考:C 数组 参考:C 字符串 参考:C笔记之NULL和字符串结束符'\0'和EOF 总结:[个人理解,可能 ...

  7. C#操作excel(多种方法比较)

    我们在做excel资料的时候,通常有以下方法. 一.导入导出excel常用方法: 1.用查询表的方式查询并show在数据集控件上. 代码 public static string strCon = & ...

  8. MIT自然语言处理第二讲:单词计数(第三、四部分)

    MIT自然语言处理第二讲:单词计数(第三部分) 自然语言处理:单词计数 Natural Language Processing: (Simple) Word Counting 作者:Regina Ba ...

  9. java 单例 读写锁_终极锁实战:单JVM锁+分布式锁

    目录 1.前言 2.单JVM锁 3.分布式锁 4.总结 =========正文分割线================= 1.前言 锁就像一把钥匙,需要加锁的代码就像一个房间.出现互斥操作的典型场景:多 ...

最新文章

  1. cocos2d-x 错误异常抛出捕获和崩溃拦截
  2. 肝一波 ~ 手写一个简易版的Mybatis,带你深入领略它的魅力!
  3. IOS基础使用PCH文件全局定义宏常量
  4. matlab1 3倍频程,瞬时声压时域数据怎么用matlab进行1/3倍频程声压级分析
  5. Apache2.2与Tomcat7集成方案详解
  6. HDOJ2024C语言合法标识符
  7. Laravel 跨域问题解决
  8. Java毕业设计教程源码分享——简易网盘
  9. 2022全球程序员薪资排行:中国倒数,美国写Go最挣钱
  10. 新装的服务器wincc上一些图形不显示,wincc画面无法全部显示
  11. 旷世科技面试——CV岗/后端开发
  12. revit二次开发 IdlingExternalEvent 空闲事件与外部事件
  13. erlang游戏服务器
  14. 秦观 满庭芳-山抹微云 改阳韵
  15. P2947 向右看齐
  16. 原链YCC战略定位:公链+私链(联盟链、私有链),实现价值传递
  17. vue网络应用:天气查询
  18. 荣耀折叠屏手机如何超越华为?与三星合作就行
  19. .net Applcation FrameWork
  20. 如何快速创建注册表文件

热门文章

  1. 爬虫系列(1):极简爬虫——基于requests和re爬取安居客上海二手房价数据
  2. MacOS上效率神器 Alfred的基本用法
  3. 写在公众号之前——QT,ARM,DSP,单片机,电力电子与传动!
  4. Android的JSON解析(上)
  5. 化妆品电商网站响应式模板
  6. Java生成二维码并将其绘制成个人名片图片
  7. 过压保护电路设计学习笔记
  8. 【React】883- React hooks 之 useEffect 学习指南
  9. android融云自定义通知,Android SDK 体系架构 - 融云 RongCloud
  10. Android 13 开发者预览版