NewCoder数据结构-刷题笔记

2019.2.19

1.考虑以下二分查找的代码:
#include <stdio.h>
int bsearch(int array[], int n, int v)
{
    int left, right, middle;
    left = 0, right = n - 1;
    while (left <= right) {
        middle = left + (right - left) / 2;
        if (array[middle] > v ) {
            right = middle;
        } else if (array[middle] < v) {
            left = middle;
        } else {
            return middle;
        }
  } 
    return -1;
}

对于输入array为:{2, 6, 8, 10, 13, 25, 36, 45, 53, 76, 88, 100, 127}, n = 13, v = 127时,
运行bsearch函数,while循环调用的次数为____。

  • 1
  • 3
  • 4
  • 5
  • 6
  • 无数次

m的取值为6,9,10,11,11,11,11所以会无限次循环。下面是正确的二分查找

public static int Method(int[] nums, int low, int high, int target)
        {
            while (low <= high)
            {
                int middle = (low + high) / 2;
                if (target == nums[middle])
                {
                    return middle;
                }
                else if (target > nums[middle])
                {
                    low = middle + 1;
                }
                else if (target < nums[middle])
                {
                    high = middle - 1;
                }
            }
            return -1;
        }
2.对N个元素的表做顺序查找时,若查找每个元素的概率相同,则平均查找长度为( )
  • (N+1)/2
  • N/2
  • N
  • [(1+N)*N ]/2

第一个数的比较次数为1,第二个数的比较次数为2。。。以此类推第N个数的比较次数为N,所以总的比较次数为1+2+…+N=N(N+1)/2,平均比较次数为(N+1)/2,也即平均查找长度。

3.对有18个元素的有序表r[0…17],进行二分查找,则查找r[3]的比较序列下标为()
  • 0、1、2
  • 8、4、1、2
  • 8、3
  • 8、3、1、2

第一次,下标范围0–17 比较序列r[8]
第二次,下标范围0–7 比较序列r[3]

4.对于关键字序列(16,10,20,12,18,7,14,13,5,19),不可能构成其二叉排序树中一条查找路径的序列是( )
  • 16,10,7,5
  • 16,20,18,19
  • 16,10,7,12,14
  • 16,10,12,14

二叉排序树或者是一棵空树,或者是具有下列性质的二叉树:
(1)若左子树不空,则左子树上所有结点的值均小于或等于它的根结点的值;
(2)若右子树不空,则右子树上所有结点的值均大于或等于它的根结点的值;
(3)左、右子树也分别为二叉排序树;

5.设顺序线性表的长度为30,分成5块,每块6个元素,如果采用分块查找并且索引表和块内均采用顺序查找,则其平均查找长度为( )。
  • 6
  • 11
  • 5
  • 6.5

分块查找会分两部分进行,第一步先进行索引表查找判断其在那个字表中,第二步然后进行在字表中的查找
索引表有5个元素 所以平均查找长度为:(1+5)/2=3
字表中有6个元素,所以平均查找长度为:(1+6)/2=3.5
所以总的平均查找长度为3+3.5=6.5

6.执行()操作时,需要使用队列做辅助存储空间
  • 查找哈希(Hash)表
  • 广度优先搜索网
  • 前序(根)遍历二叉树
  • 深度优先搜索网

深度优先搜索要借助栈;
广度优先搜索要借助队列;

7.具有12个关键字的有序表,折半查找的平均查找长度()
  • 3.1
  • 4
  • 2.5
  • 5

具体查找如下图所示:
查找一次:6.
查找两次:3、10
查找三次:1、4、8、11
查找四次:2、5、7、9、12

8.顺序表查找指的是在顺序存储结构上进行查找。( )
  • 正确
  • 错误

折半查找最坏的情况下查找log(n)+1次,而二叉查找树最坏的情况是查找n次。(退化为单链表)

9.请问对一个排好序的数组进行查找,用平均时间复杂度最小的算法,时间复杂度为()
  • O(n)
  • O(lgn)
  • O(nlgn)
  • O(1)
    在这里插入图片描述
10.折半查找与二元查找树的时间性能在最坏的情况下是相同的()

二叉查找树(英语:Binary Search Tree),也称为二叉搜索树、有序二叉树(ordered binary tree)或排序二叉树
二叉查找树数最坏的情况下是链表的形式。
折半查找最坏的情况是logN+1

11.KMP算法下,长为n的字符串中匹配长度为m的子串的复杂度为()
  • O(N)
  • O(M+N)
  • O(M+LOGM)
  • O(N+LOGM)

未解决!!!!!!

12.在一个有8个int数据的数组中,随机给出数组的数据,找出最大和第二大元素一定需要进行()次比较:
  • 8
  • 9
  • 10
  • 11

13. 既希望较快的查找又便于线性表动态变化的查找方法是()
  • 顺序查找
  • 折半查找
  • 分块查找
  • 哈希法查找

索引顺序查找又称为分块查找
顺序查找,算法简单,时间复杂度O(n);
折半查找,要求有序,O(log n);
二叉搜索树,动态,查找性能取决于二叉树的形状,——》二叉平衡树,越平衡,时间复杂度越接近于O(log n); 哈希表:特殊的应用,查找一步到位

2019.2.20

1.设有序顺序表中有n个数据元素,则利用二分查找法查找数据元素X的最多比较次数不超过()。

  • log2n+1
  • log2n-1
  • log2n
  • log2(n+1)

平衡二叉树:一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树,查找时间的时间复杂度为O(log2n)。
二叉查找树(Binary Search Tree),或者是一棵空树,或者是具有下列性质的二叉树:若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;它的左、右子树也分别为二叉排序树。

  1. 设散列表的长度为10,散列函数H(n)=n mod 7,初始关键字序列为 (33,24,8,17,21,10),用链地址法作为解决冲突的方法,平均查找长度是()
  • 1
  • 1.5
  • 2
  • 2.5

链地址法,将所有具有相同哈希地址的而不同关键字的数据元素连接到同一个单链表中
33%7=5 24%7=3 8%7=1 17%7=3 放在24后面(24->17)21%7=0 10%7=3放在17后面(24->17->10)
(1+1+1+2+1+3)/6=1.5

  1. 从n个数里面找最大的两个数理论最少需要比较
  • 2logn
  • 2 logn -1
  • n+ logn -2
  • 2n-3

所有次数控制着,最终冠军,每一层的控制着亚军。
类似比赛晋级,两两配对比较,赢的再两两配对,最后得到冠军(最大的数),可以看成是一棵二叉树,以4人为例:
0
0 2
0 1 2 3
可以看出,找出最大的数比较次数是n-1。然后第二大的数肯定是跟冠军比较过的数字,那么很明显每一层都有一个,所以有logn-1次比较。

所以总共是n+logn-2次比较

4.下面哪一方法可以判断出一个有向图是否有环(回路)( )

  • 深度优先遍历
  • 拓扑排序
  • Dijkstra求最短路径
  • 求关键路径

绝对能判断有向图是否有环的是:
1.DFS
2.拓扑排序
3.最短路径是允许有环的!C肯定不选。
4.D可选可不选。
关键路径能不能判断一个图有环还存在一些争议。关键路径本身虽然不允许有环,但求关键路径的算法本身无法判断是否有环,判断是否有环的是关键路径的第一步——拓扑排序。所以这个问题的答案主要是看你从哪个角度出发看问题。

  1. 若长度为n的线性表采用顺序存储结构,在其第i个位置插入一个新元素的算法的时间复杂度为()(1<=i<=n+1)
  • O(0)
  • O(1)
  • O(n)
  • O(n2)

6.有 1000 个无序的整数,希望使用最快的方式找出前 50 个最大的,最佳的选择是( )

  • 冒泡排序
  • 基数排序
  • 堆排序
  • 快速排序
  1. T(n)=O(f(n))中,函数O()的正确含义为()
  • T(n)为f(n)的函数
  • T(n)为n的函数
  • 存在足够大的正整数M,使得T(n)≤M×f(n)

8.线性表(a1,a2,…,an)以链接方式存储时,访问第i位置元素的时间复杂性为()

  • O(i)
  • O(1)
  • O(n)
  • O(i-1)
void recursive(int n, int m, int o)
{
    if (n <= 0)
    {
        printf("%d,%d\n", m, o);
    }
    else
    {
        recursive(n - 1, m + 1, o);
        recursive(n - 1, m, o + 1);
    }
}
  1. 以上函数的时间复杂度()
  • O(nmo)
  • O(n2*m2)
  • O(2^n)
  • O(n!)
  1. 下面是一段求最大值的程序,其中 datalist 是数据表, n 是 datalist 的长度
int GetMax(int n,int datalist[])
{
    int k=0;
    for(int j=1;j<n;j++)
        if(datalist[j]>datalist[k])
            k=j;
    return k;
}

请问该程序段的 McCabe 环路复杂性为多少?()

  • 2
  • 3
  • 4
  • 5
  1. 以下描述错误的是:
  • KMP算法的时间复杂度是O(n)
  • 最长路径问题有多项式时间解
  • 最大流问题和最小割问题是等价的
  • PageRank算法总是会收敛
  1. 算法的时间复杂度取决于()
  • 待处理数据的状态
  • 处理器的速度
  • 问题的规模
  • 程序所占空间
### C++数据结构笔记 #### 数组 数组是一种线性数据结构,用于存储相同类型元素的集合。在C++中,数组的大小在定义时就需要确定,并且元素在内存中是连续存储的。 ```cpp #include <iostream> int main() { int arr[5] = {1, 2, 3, 4, 5}; for(int i = 0; i < 5; ++i) { std::cout << arr[i] << " "; } return 0; } ``` #### 链表 链表由一系列节点组成,每个节点包含数据和指向下一个节点的指针。链表分为单链表、双链表和循环链表等。 ```cpp #include <iostream> // 定义单链表节点 struct ListNode { int val; ListNode* next; ListNode(int x) : val(x), next(nullptr) {} }; int main() { ListNode* head = new ListNode(1); ListNode* second = new ListNode(2); head->next = second; std::cout << head->val << " " << head->next->val << std::endl; return 0; } ``` #### 栈 栈是一种后进先出(LIFO)的数据结构,支持入栈(push)和出栈(pop)操作。 ```cpp #include <iostream> #include <stack> int main() { std::stack<int> s; s.push(1); s.push(2); std::cout << s.top() << std::endl; s.pop(); std::cout << s.top() << std::endl; return 0; } ``` #### 队列 队列是一种先进先出(FIFO)的数据结构,支持入队(push)和出队(pop)操作。 ```cpp #include <iostream> #include <queue> int main() { std::queue<int> q; q.push(1); q.push(2); std::cout << q.front() << std::endl; q.pop(); std::cout << q.front() << std::endl; return 0; } ``` #### 树 树是一种非线性数据结构,由节点和边组成。常见的树有二叉树、二叉搜索树等。 ```cpp #include <iostream> // 定义二叉树节点 struct TreeNode { int val; TreeNode* left; TreeNode* right; TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} }; int main() { TreeNode* root = new TreeNode(1); root->left = new TreeNode(2); root->right = new TreeNode(3); std::cout << root->val << " " << root->left->val << " " << root->right->val << std::endl; return 0; } ``` ### 资源 #### LeetCode LeetCode是一个非常知名的平台,上面有大量的数据结构法相关的目,并且有详细的解和讨论区。可以按照数据结构的类型进行分类,例如数组、链表、树等。 #### HackerRank HackerRank提供了各种编程挑战,包括数据结构法相关的目。它还有不同难度级别的目可供选择,并且支持多种编程语言,包括C++。 #### Codeforces Codeforces主要以竞赛编程为主,上面的目难度相对较高,适合有一定基础后进行挑战。可以通过参加比赛或者过往的目来提高自己的数据结构法能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值