3-1 Deque

3-1 Deque

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

代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
C (gcc)

思路:(哪有在写小作文呀…哼!)

创建队列:
定义Deque D,PtrToNode p,并为两个变量申请内存空间。
p的前后指针均指向空 D的头尾指针均指向p
返回创建的队列D

从头指针向队列中插入元素:

先定义一个PtrToNode p,并申请空间。
然后将p的元素值赋值为X
如果D为空的话,将p的后指针置为空,p的前指针指向D的头指针,D的头指针的下一个指针指向p,D的尾指针指向p,完成插入
如果D不为空的话,将p的后指针指向D的头指针的下一个指针(保存原来的第一个结点),p的前指针指向D的头指针,D的头指针的下一个指针指向p,p的下一个指针的前指针指(即原来的第一个结点)向p。

从队头出队:

如果队列为空的话,返回ERROR
将p指向第一个数据节点
定义一个变量x用来存第一个结点的数据
如果p是尾结点的话,即队列中只有一个数据节点,那么D的第一个节点置为空,D的头结点等于尾结点
如果不是尾结点的话,正常出队,D的头指针指向第一个结点的下一个结点,下一个节点的前指针指向头指针。
最后释放第一个节点即p的空间,返回出队的第一个节点的数据

从尾部入队:

定义一个PtrToNode p并申请空间。
将p的元素值赋值为X;
p的后指针置空
p的前指针指向D的尾指针
D 的尾指针指向p
D 的尾指针赋值为p

从尾部出队:

如果队列为空的话,返回ERROR
p指向尾结点
定义一个整型变量x用来存储尾结点的数据
p的上一个元素的后指针置为空
D的尾指针指向p的上一个结点
释放p的空间
返回出队的元素值

代码样例:

Deque CreateDeque(){
    Deque D;
    PtrToNode p;
    D=(Deque)malloc(sizeof(struct DequeRecord));
    p=(PtrToNode)malloc(sizeof(struct Node));
    p->Last=NULL;
    p->Next=NULL;
    D->Front=p;
    D->Rear=p;
    return D;
}
int Push( ElementType X, Deque D ){
    PtrToNode p;
    p=(PtrToNode)malloc(sizeof(struct Node));
    p->Element=X;
    if(D->Front==D->Rear){
        //队列为空
        p->Next=NULL;
        p->Last=D->Front;
        D->Front->Next=p;
        D->Rear=p;
    } else{
        p->Next=D->Front->Next;
        p->Last=D->Front;
        D->Front->Next=p;
        p->Next->Last=p;
    }
    return 1;
}
ElementType Pop( Deque D ){
    //队列为空
    if(D->Front==D->Rear) return ERROR;
    PtrToNode p=D->Front->Next;//p指向第一个数据节点
    int x=p->Element;
    if(p==D->Rear){
        D->Front->Next=NULL;
        D->Rear=D->Front;
    }
    else{
        D->Front->Next=p->Next;
        p->Next->Last=D->Front;
    }
    free(p);
    return x;
    
}
int Inject( ElementType X, Deque D ){
    PtrToNode p=(PtrToNode)malloc(sizeof(struct Node));
    p->Element=X;
    p->Next=NULL;
    p->Last=D->Rear;
    D->Rear->Next=p;
    D->Rear=p;
    return 1;
}
ElementType Eject( Deque D ){
    //队列为空
    if(D->Front==D->Rear) return ERROR;
    PtrToNode p=D->Rear;//p指向尾结点
    int x=p->Element;
    p->Last->Next=NULL;
    D->Rear=p->Last;
    free(p);
    return x;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值