3-1 Deque —2022秋.3.6-7

题目:

A "deque" is a data structure consisting of a list of items, on which the following operations are possible:

  • Push(X,D): Insert item X on the front end of deque D.
  • Pop(D): Remove the front item from deque D and return it.
  • Inject(X,D): Insert item X on the rear end of deque D.
  • Eject(D): Remove the rear item from deque D and return it.
    Write routines to support the deque that take O(1) time per operation.

 Format of functions:

Deque CreateDeque();
int Push( ElementType X, Deque D );
ElementType Pop( Deque D );
int Inject( ElementType X, Deque D );
ElementType Eject( Deque D );

 where Deque is defined as the following:

typedef struct Node *PtrToNode;
struct Node {
    ElementType Element;
    PtrToNode Next, Last;
};
typedef struct DequeRecord *Deque;
struct DequeRecord {
    PtrToNode Front, Rear;
};

Here the deque is implemented by a doubly linked list with a header. Front and Rear point to the two ends of the deque respectively. Front always points to the header. The deque is empty when Front and Rear both point to the same dummy header.
Note: Push and Inject are supposed to return 1 if the operations can be done successfully, or 0 if fail. If the deque is empty, Pop and Eject must return ERROR which is defined by the judge program.

 Sample program of judge:

#include <stdio.h>
#include <stdlib.h>

#define ElementType int
#define ERROR 1e5
typedef enum { push, pop, inject, eject, end } Operation;

typedef struct Node *PtrToNode;
struct Node {
    ElementType Element;
    PtrToNode Next, Last;
};
typedef struct DequeRecord *Deque;
struct DequeRecord {
    PtrToNode Front, Rear;
};
Deque CreateDeque();
int Push( ElementType X, Deque D );
ElementType Pop( Deque D );
int Inject( ElementType X, Deque D );
ElementType Eject( Deque D );

Operation GetOp();          /* details omitted */
void PrintDeque( Deque D ); /* details omitted */

int main()
{
    ElementType X;
    Deque D;
    int done = 0;

    D = CreateDeque();
    while (!done) {
        switch(GetOp()) {
        case push: 
            scanf("%d", &X);
            if (!Push(X, D)) printf("Memory is Full!\n");
            break;
        case pop:
            X = Pop(D);
            if ( X==ERROR ) printf("Deque is Empty!\n");
            break;
        case inject: 
            scanf("%d", &X);
            if (!Inject(X, D)) printf("Memory is Full!\n");
            break;
        case eject:
            X = Eject(D);
            if ( X==ERROR ) printf("Deque is Empty!\n");
            break;
        case end:
            PrintDeque(D);
            done = 1;
            break;
        }
    }
    return 0;
}

/* Your function will be put here */

Sample Input:

Pop
Inject 1
Pop
Eject
Push 1
Push 2
Eject
Inject 3
End

 Sample Output:

Deque is Empty!
Deque is Empty!
Inside Deque: 2 3

分析:

       本人基础不太好,所以在理解Deque的定义方式那里费了时间,好在最后有了自己的理解(仅仅是自己好理解,Front指向的是空,它的下一个才是存有element的第一个,而Rear指向的确实是最后一个存有element的),不过本题除了是英文之外(我觉得别急的用APP翻译,自己翻译也很简单的),思路很简单,我第一次测试没通过是在pop()函数,并未考虑到D->Front->Next==D->Rear的情况。

代码实现:

Deque CreateDeque(){
    PtrToNode p=(PtrToNode)malloc(sizeof(struct Node));
   /* p->Last=NULL;
    p->Next=NULL;*/
    Deque q=(Deque)malloc(sizeof(struct DequeRecord));
    q->Front=q->Rear=p;
    return q;
}

int Push( ElementType X, Deque D )
{
    PtrToNode p=(PtrToNode)malloc(sizeof(struct Node));
    p->Element=X;
    if(D->Front==D->Rear)
    {
        D->Front->Next=p;
        D->Rear=p;
        p->Last=D->Front;
    }
    else
    {
        p->Next=D->Front->Next;
        D->Front->Next=p;
        p->Last=D->Front;
        p->Next->Last=p;
    }
    return 1;
}

ElementType Pop( Deque D )
{
    if(D->Front==D->Rear)
        return ERROR;
    else
    {
        PtrToNode p=D->Front->Next;
        ElementType x=p->Element;
        if(p!=D->Rear)
        {
            D->Front->Next=p->Next;
             p->Next->Last=D->Front->Next;
        }
        else if(p==D->Rear)
        {
            D->Rear=D->Front;
        }
         //free(p);
         return x;
    }
}

int Inject( ElementType X, Deque D )
{
    PtrToNode p=(PtrToNode)malloc(sizeof(struct Node));
    p->Element=X;
    if(D->Front==D->Rear)
    {
        D->Rear=p;
        D->Front->Next=p;
        p->Last=D->Front;
       // p->Next=NULL;
    }
    else
    {
        D->Rear->Next=p;
        p->Last=D->Rear;
        D->Rear=p;
       // p->Next=NULL;
    }
    return 1;
}

ElementType Eject( Deque D )
{
    if(D->Front==D->Rear)
        return ERROR;
    else
    {
        PtrToNode p=D->Rear;
        ElementType x=p->Element;
        D->Rear=p->Last;
       // D->Rear->Next=NULL;
        return x;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这是一个运行错误,发生在第171行第16列,错误信息是“引用绑定到未对齐的地址0xbebebebebebec0ba,类型为'int',需要4字节对齐(stl_deque.h)”,指向的地址是0xbebebebebebec0ba,但是该地址没有被打印出来。总结是未定义行为。该错误信息出现在stl_deque.h文件的第180行第16列。 ### 回答2: 这个错误是由于使用了一个未对齐的内存地址引用所导致的。该错误指向了一个STL deque库中的模板函数stl_deque.h。错位参考绑定引用到不对齐的地址上,这个地址是0xbebebebebebec0ba,该地址不满足int类型需要的4字节对齐。同时,该错误指出该地址的指针指向这里,但是由于未知原因无法打印出该地址,即该地址的内存无法被读取。 这一错误可以由许多原因引起,例如使用不正确的指针值、内存泄漏、堆栈溢出或内存覆盖。其中,最常见的原因是访问未初始化或已经释放的堆内存。这个错误会导致程序崩溃或不可预测的行为,因此必须加以调试和修复。 对于这种错误,建议使用内存分析工具来确定具体的原因。例如,使用Valgrind和GDB可以检测出内存泄漏和许多其他内存错误。同时,也可以通过仔细地检查代码逻辑,确保指针和地址的处理是正确的来避免出现此类错误。另外,可以使用C++11标准中的std::aligned_storage和std::align函数来进行内存对齐,以避免该类错误的出现。 ### 回答3: 这是一个运行时错误,意味着在程序运行时出现了问题。具体来说,这个错误是在调用STL库中的deque容器时发生的。错误的信息是“reference binding to misaligned address”,也就是说,引用绑定到了一个没有按照4个字节对齐的地址上。 出现这个错误的原因可能是内存泄漏、访问越界或者数据类型不匹配等问题。这里的0xbebebebebebec0ba是一个指针地址,指向一个在内存中的位置,但是这个地址可能因为某些原因导致了访问越界或者数据类型不匹配的问题。 要解决这个问题,首先需要找到引起这个错误的原因。可以使用一些调试工具,比如Valgrind或者GDB等,对程序进行调试,找到出现错误的位置。然后根据错误的信息进行分析,进一步确定问题所在。最后,针对问题进行修复和改进,使代码更加健壮、可靠。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值