我的圆形链表代码有什么问题?

时间:2013-04-26 01:14:58

标签: c pointers data-structures linked-list

我正在学习C和数据结构。我正在尝试创建一个带有一个标记的循环链表并打印6个数字。但是我很难完成这项任务。我一直在研究这个问题几个小时。我被卡住了。我希望有人可以帮我看看我的代码并给我一些关于问题的提示。在此先感谢您的时间!

我尝试在前面添加3个数字,在后面添加3个数字,然后打印出正面和背面的数字,它可以正常工作。但是当我试图打印整个列表时,我只能得到3个数字或遇到错误。

    struct DLink {
    TYPE value;         /* value of the link */
    struct DLink * next;    /* pointer to the next link */
    struct DLink * prev;    /* pointer to the previous link */
};

# define TYPE_SENTINEL_VALUE DBL_MAX 


struct cirListDeque {
    int size;                  /* number of links in the deque */
    struct DLink *Sentinel;         /* pointer to the sentinel */
};

/* internal functions prototypes */
struct DLink* _createLink (TYPE val);
void _addLinkAfter(struct cirListDeque *q, struct DLink *lnk, struct DLink *newLnk);

/* Initialize deque.

    param:  q       pointer to the deque
    pre:    q is not null
    post:   q->backSentinel is allocated and q->size equals zero
*/
void _initCirListDeque (struct cirListDeque *q) 
{
    assert(q != 0);

    //allocate the sentinel
    q->Sentinel = malloc(sizeof(struct DLink));
    assert(q->Sentinel != 0);

    //the start point and end point are equal to each other
    //q->Sentinel->next = q->Sentinel;
    q->Sentinel->next = q->Sentinel->prev;

    //set the size of the deque
    q->size = 0;
} 

/*
 create a new circular list deque

 */

struct cirListDeque *createCirListDeque()
{
    struct cirListDeque *newCL = malloc(sizeof(struct cirListDeque));
    _initCirListDeque(newCL);
    return(newCL);
}


//Create a link for a value.
struct DLink * _createLink (TYPE val)
{
    /* FIXME: you must write this */
    /*temporary return value..you may need to change it*/
    //Create a new link to store the value
    struct DLink *new_lnk = malloc(sizeof(struct DLink));
    assert(new_lnk != 0);
    new_lnk->value = val;

    return new_lnk;
}

//Adds a link after another link
void _addLinkAfter(struct cirListDeque *q, struct DLink *lnk, struct DLink *newLnk)
{
    assert(q != 0);
    assert(lnk != 0);
    assert(newLnk != 0);

    //The existing link is before the new link
    lnk->next = newLnk;
    newLnk->prev = lnk;

    //The link that was originally after the existing link is after the new link
    newLnk->next = q->Sentinel->next;

    //The new link is the last link
    //q->Sentinel->prev = newLnk;

    //update the size field
    q->size++;
}

// Adds a link to the back of the deque
void addBackCirListDeque (struct cirListDeque *q, TYPE val)
{
    /* FIXME: you must write this */
    assert(q != 0);

    //Create the new back link
    struct DLink *new_backLnk = _createLink(val);
    struct DLink *tmp = q->Sentinel->prev;

    q->Sentinel->prev = new_backLnk;
    new_backLnk->prev = tmp;
    new_backLnk->next = q->Sentinel->next;

}

// Adds a link to the front of the deque
void addFrontCirListDeque(struct cirListDeque *q, TYPE val)
{
    /* FIXME: you must write this */
    assert(q != 0);

    //create a temp link for the link that is originally after the sentinel
    struct DLink *tmp = q->Sentinel->next;

    //allocate the new front link
    struct DLink *new_frontLnk = _createLink(val);

    //add the new front link after the Sentinel
    _addLinkAfter(q, q->Sentinel, new_frontLnk);

    //Put the old front link after the new front link
    new_frontLnk->next = tmp;

    //new_frontLnk->prev = q->Sentinel->prev;

}

// Get the value of the front of the deque
TYPE frontCirListDeque(struct cirListDeque *q) 
{
    /* FIXME: you must write this */     
    /*temporary return value..you may need to change it*/
    assert(q != 0);
    assert(q->size > 0);

    return q->Sentinel->next->value;
}

// Get the value of the back of the deque
TYPE backCirListDeque(struct cirListDeque *q)
{
    /* FIXME: you must write this */     
    /*temporary return value..you may need to change it*/
    assert(q != 0);
    assert(q->size > 0);

    return q->Sentinel->prev->value;

}


// Check whether the deque is empty
int isEmptyCirListDeque(struct cirListDeque *q) {
    /* FIXME: you must write this */
    /*temporary return value..you may need to change it*/
    assert(q != 0);

    if (q->size == 0)
        return 1;

    return 0;
}

// Print the links in the deque from front to back
void printCirListDeque(struct cirListDeque *q)
{
    assert(q != 0);
    assert(!isEmptyCirListDeque(q));

    for (int i = 0; i < q->size; i++)
    {
        printf("The value is %g\n", q->Sentinel->next->value);
        q->Sentinel->next = q->Sentinel->next->next;
    }

}

1 个答案:

答案 0 :(得分:2)

在此代码中,malloc未初始化q->Sentinel且您未初始化q->Sentinel->prev因此q->Sentinel->nextq->Sentinel->prev的值未定义。因此,您应该取消注释q->Sentinel->prev = q->Sentinel;行。

void _initCirListDeque (struct cirListDeque *q) 
{
    assert(q != 0);

    //allocate the sentinel
    q->Sentinel = malloc(sizeof(struct DLink));

    if( !q->Sentinel )
    {
         printf( "out of memory\n" );
         exit( -1 );
    }

    //the start point and end point are equal to each other
    q->Sentinel->prev = q->Sentinel->next = q->Sentinel;

    //set the size of the deque
    q->size = 0;
} 

_addLinkAfter中,您需要在执行任何操作之前保留next的当前lnk属性,然后您需要将链接插入现有的...

void _addLinkAfter(struct cirListDeque *q, struct DLink *lnk, struct DLink *newLnk)
{
    // preserve current linkage

    newLnk->prev = lnk;
    newLnk->next = lnk->next;

    // link in new record

    lnk->next = newLnk;
    newLnk->next->prev = newLnk;

    q->size++;
}

您可以优化addBackCirListDeque以使用现有的_addLinkAfter

void addBackCirListDeque(struct cirListDeque *q, TYPE val)
{
    _addLinkAfter( q, q->Sentinel->prev, _createLink(val) );
}

addFrontCirListDeque

相同
void addFrontCirListDeque(struct cirListDeque *q, TYPE val)
{
    _addLinkAfter( q, q->Sentinel, _createLink(val) );
}