C/C++ 笔试、面试题目大汇总(三)

本次主要介绍循环链表、队列、栈和堆

1、已知n个人(以编号1,2,3,...,n分别表示)围坐在一张圆桌周围,从编号为k的人开始报数,数到m的那个人出列,他的下一个人又从k开始报数,数到m的那个人出列,依次重复下去,直到圆桌的人全部出列。试用C++编写实现。

    解析:本题就是约瑟夫环问题的实际场景,要通过输入n、m、k三个正整数,求出列的序列。这个问题采用的是典型的循环链表的数据结构,就是将一个链表的尾元素指针指向队首元素:

    p->link=head;

    解决问题的核心步骤如下:

    (1)建立一个具有n个链节点、无头节点的循环链表。

    (2)确定第一个报数人的位置。

    (3)不断的从链表中删除链节点,直到链表为空。

    答案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include<iostream>
using  namespace  std;
 
typedef  struct  LNode
{
     int  data;
     struct  LNode *link;
}LNode,*LinkList;
 
//n为总人数,k为第一个开始报数的人,m为出列者喊到的数
void  JOSEPHUS( int  n, int  k, int  m)
{
     //p为当前节点,r为辅助节点,指向p的前驱节点,list为头节点
     LinkList p,r,list,curr;
     //简历循环链表
     p=(LinkList) malloc ( sizeof (LNode));
     p->data=1;
     p->link=p;
     curr=p;
     for ( int  i=2;i<=n;i++)
     {
         LinkList t=(LinkList) malloc ( sizeof (LNode));
         t->data=i;
         t->link=curr->link;
         curr->link=t;
         curr=t;
     }
     //把当前指针移动到第一个报数的人
     r=curr;
     while (k--)
         r=p,p=p->link;
     while (n--)
     {
         for ( int  s=m-1;s--;r=p,p=p->link);
         r->link=p->link;
         printf ( "%d->" ,p->data);
         free (p);
         p=r->link;
     }
}

 

2、编程实现队列的入队/出队操作。

    答案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include<iostream>
using  namespace  std;
 
typedef  struct  student
{
     int  data;
     struct  student *next;
}node;
 
typedef  struct  linkqueue
{
     node *first,*rear;
}queue;
 
//队列的入队
queue *insert(queue *HQ, int  x)
{
     node *s;
     s=(node *) malloc ( sizeof (node));
     s->data=x;
     s->next=NULL;
     if (HQ->rear==NULL)
     {
         HQ->first=s;
         HQ->rear=s;
     }
     else
     {
         HQ->rear->next=s;
         HQ->rear=s;
     }
     return  (HQ);
}
 
//队列的出队
queue * remove (queue *HQ)
{
     node *p;
     if (HQ->first==NULL)
         printf ( "\n yichu" );
     else
     {
         p=HQ->first;
         if (HQ->first==HQ->rear)
         {
             HQ->first=NULL;
             HQ->rear=NULL;
         }
         else
         {
             HQ->first=HQ->first->next;
             free (p);
         }
         return  (HQ);
     }
}

 

3、用两个栈实现一个队列的功能,请用C++实现。

    解析:思路如下:

    假设两个栈A和B,且都为空。

    可以认为栈A提供入队列的功能,栈B提供出队列的功能。

    入队列:入栈A。

    出队列:

    (1)如果栈B不为空,直接弹出栈B的数据。

    (2)如果栈B为空,则依次弹出栈A的数据,放入栈B中,再弹出栈B的数据。

    答案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include<iostream>
#include<stack>
using  namespace  std;
 
template < class  T>
struct  Queue
{
     void  push(T &t)
     {
         s1.push(t);
     }
 
     T front()
     {
         if (s2.empty())
         {
             if (s1.size()==0) throw ;
             while (!s1.empty())
             {
                 s2.push(s1.top());
                 s1.pop();
             }
         }
         return  s2.top();
     }
 
     void  pop()
     {
         if (s2.empty())
         {
             while (!s1.empty())
             {
                 s2.push(s1.top());
                 s1.pop();
             }
         }
         if (!s2.empty())
             s2.pop();
     }
 
     stack<T> s1;
     stack<T> s2;
}

 

4、请讲诉heap和stack的差别。

    解析:在进行C/C++编程时,需要程序员对内存的了解比较精准。经常需要操作的内存可分为以下几个类别:

    (1)栈区(stack):由编译器自动分配和释放,存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈。

    (2)堆区(heap):一般由程序员分配和释放,若程序员不释放,程序结束时可能由操作系统回收。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表

    (3)全局区(静态区)(static):全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和静态变量在相邻的另一块区域。程序结束后由系统释放。

    (4)文字常量区:常量字符串就是放在这里的,程序结束后由系统释放。

    (5)程序代码区:存放函数体的二进制代码。

 

   答案:

(1)stack的空间由操作系统自动分配/释放,heap上的空间手动分配/释放。

(2)stack空间有限,heap是很大的自由存储区。

(3)C中的malloc函数分配内存空间即在堆上,C++中对应的是new操作符。

(4)程序在编译期对变量和函数分配内存都在栈上进行,且程序运行过程中函数调用时参数的传递也在栈上进行。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fullstack_lth

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值