数据结构习题(一)

举报
irrational 发表于 2022/01/18 00:44:31 2022/01/18
【摘要】 单链表 实现一个单链表,链表初始为空,支持三种操作: 向链表头插入一个数;删除第 k 个插入的数后面的数;在第 k 个插入的数后插入一个数。 现在要对该链表进行 M 次操作,进行完所有操作后,从头到尾输出整个链表。 注意:题目中第 k 个插入的数并不是指当前链表的第 ...

单链表

实现一个单链表,链表初始为空,支持三种操作:

  1. 向链表头插入一个数;
  2. 删除第 k 个插入的数后面的数;
  3. 在第 k 个插入的数后插入一个数。

现在要对该链表进行 M 次操作,进行完所有操作后,从头到尾输出整个链表。

注意:题目中第 k 个插入的数并不是指当前链表的第 k 个数。例如操作过程中一共插入了 n 个数,则按照插入的时间顺序,这 n 个数依次为:第 1 个插入的数,第 2 个插入的数,…第 n 个插入的数。

输入格式

第一行包含整数 M,表示操作次数。

接下来 M 行,每行包含一个操作命令,操作命令可能为以下几种:

  1. H x,表示向链表头插入一个数 x。
  2. D k,表示删除第 k 个插入的数后面的数(当 k 为 0 时,表示删除头结点)。
  3. I k x,表示在第 k 个插入的数后面插入一个数 x(此操作中 k 均大于 0)。

输出格式

共一行,将整个链表从头到尾输出。

数据范围

1≤M≤100000
所有操作保证合法。

输入样例:


   
  1. 10
  2. H 9
  3. I 1 1
  4. D 1
  5. D 0
  6. H 6
  7. I 3 6
  8. I 4 5
  9. I 4 5
  10. I 3 4
  11. D 6

输出样例:

6 4 6 5

  

  
  1. #include <iostream>
  2. using namespace std;
  3. const int N = 100010;
  4. // head 表示头结点的下标
  5. // e[i] 表示节点i的值
  6. // ne[i] 表示节点i的next指针是多少
  7. // idx 存储当前已经用到了哪个点
  8. int head, e[N], ne[N], idx;
  9. // 初始化
  10. void init()
  11. {
  12. head = -1;
  13. idx = 0;
  14. }
  15. // 将x插到头结点
  16. void add_to_head(int x)
  17. {
  18. e[idx] = x, ne[idx] = head, head = idx ++ ;
  19. }
  20. // 将x插到下标是k的点后面
  21. void add(int k, int x)
  22. {
  23. e[idx] = x, ne[idx] = ne[k], ne[k] = idx ++ ;
  24. }
  25. // 将下标是k的点后面的点删掉
  26. void remove(int k)
  27. {
  28. ne[k] = ne[ne[k]];
  29. }
  30. int main()
  31. {
  32. int m;
  33. cin >> m;
  34. init();
  35. while (m -- )
  36. {
  37. int k, x;
  38. char op;
  39. cin >> op;
  40. if (op == 'H')
  41. {
  42. cin >> x;
  43. add_to_head(x);
  44. }
  45. else if (op == 'D')
  46. {
  47. cin >> k;
  48. if (!k) head = ne[head];
  49. else remove(k - 1);
  50. }
  51. else
  52. {
  53. cin >> k >> x;
  54. add(k - 1, x);
  55. }
  56. }
  57. for (int i = head; i != -1; i = ne[i]) cout << e[i] << ' ';
  58. cout << endl;
  59. return 0;
  60. }

 双链表

实现一个双链表,双链表初始为空,支持 55 种操作:

  1. 在最左侧插入一个数;
  2. 在最右侧插入一个数;
  3. 将第 kk 个插入的数删除;
  4. 在第 kk 个插入的数左侧插入一个数;
  5. 在第 kk 个插入的数右侧插入一个数

现在要对该链表进行 MM 次操作,进行完所有操作后,从左到右输出整个链表。

注意:题目中第 kk 个插入的数并不是指当前链表的第 kk 个数。例如操作过程中一共插入了 nn 个数,则按照插入的时间顺序,这 nn 个数依次为:第 11 个插入的数,第 22 个插入的数,…第 nn 个插入的数。

输入格式

第一行包含整数 MM,表示操作次数。

接下来 MM 行,每行包含一个操作命令,操作命令可能为以下几种:

  1. L x,表示在链表的最左端插入数 xx。
  2. R x,表示在链表的最右端插入数 xx。
  3. D k,表示将第 kk 个插入的数删除。
  4. IL k x,表示在第 kk 个插入的数左侧插入一个数。
  5. IR k x,表示在第 kk 个插入的数右侧插入一个数。

输出格式

共一行,将整个链表从左到右输出。

数据范围

1≤M≤1000001≤M≤100000
所有操作保证合法。

输入样例:


   
  1. 10
  2. R 7
  3. D 1
  4. L 3
  5. IL 2 10
  6. D 3
  7. IL 2 7
  8. L 8
  9. R 9
  10. IL 4 7
  11. IR 2 2

输出样例:

8 7 7 3 2 9
  

   
  1. #include <iostream>
  2. using namespace std;
  3. const int N = 100010;
  4. int m;
  5. int e[N], l[N], r[N], idx;
  6. // 在节点a的右边插入一个数x
  7. void insert(int a, int x)
  8. {
  9. e[idx] = x;
  10. l[idx] = a, r[idx] = r[a];
  11. l[r[a]] = idx, r[a] = idx ++ ;
  12. }
  13. // 删除节点a
  14. void remove(int a)
  15. {
  16. l[r[a]] = l[a];
  17. r[l[a]] = r[a];
  18. }
  19. int main()
  20. {
  21. cin >> m;
  22. // 0是左端点,1是右端点
  23. r[0] = 1, l[1] = 0;
  24. idx = 2;
  25. while (m -- )
  26. {
  27. string op;
  28. cin >> op;
  29. int k, x;
  30. if (op == "L")
  31. {
  32. cin >> x;
  33. insert(0, x);
  34. }
  35. else if (op == "R")
  36. {
  37. cin >> x;
  38. insert(l[1], x);
  39. }
  40. else if (op == "D")
  41. {
  42. cin >> k;
  43. remove(k + 1);
  44. }
  45. else if (op == "IL")
  46. {
  47. cin >> k >> x;
  48. insert(l[k + 1], x);
  49. }
  50. else
  51. {
  52. cin >> k >> x;
  53. insert(k + 1, x);
  54. }
  55. }
  56. for (int i = r[0]; i != 1; i = r[i]) cout << e[i] << ' ';
  57. cout << endl;
  58. return 0;
  59. }

文章来源: blog.csdn.net,作者:irrationality,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/weixin_54227557/article/details/120746603

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。