加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

理解C中双向链表中的双指针

发布时间:2020-12-16 10:38:33 所属栏目:百科 来源:网络整理
导读:我明天参加考试,我试图理解教师放在班级网站上的这个双重链接列表示例,但我很难理解它… 这是代码: #include stdio.h#include stdlib.htypedef struct dl { int key; float value; struct dl *next; struct dl *prev;} DL;DL *insert(int c,float f,DL *l)
我明天参加考试,我试图理解教师放在班级网站上的这个双重链接列表示例,但我很难理解它…

这是代码:

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

typedef struct dl {
    int key;
    float value;
    struct dl *next;
    struct dl *prev;
} DL;

DL *insert(int c,float f,DL *l) {
    DL *new = (DL*) malloc(sizeof(DL));
    if (new == NULL) exit(-1);
    new->key=c; new->value=f; 
    if (l==NULL) {
        new->next=NULL; new->prev=NULL;
    }
    else if (l->key < c) {
        while((l->next != NULL) && (l->next->key < c)) { l=l->next; }
        new->next=l->next; l->next=new; new->prev=l;
        if (new->next != NULL) {
            new->next->prev=new;
        }
    }
    else {
        while((l->prev != NULL) && (l->prev->key > c)) { l=l->prev; }
        new->prev=l->prev; l->prev=new; new->next=l;
        if(new->prev != NULL) {
            new->prev->next=new;
        }
    }
    return new;
}

int search(int c,float *f,DL **lptr) {
    if (*lptr == NULL) return 0;
    if (c < (*lptr)->key) {
        while(((*lptr)->prev!=NULL)&&((*lptr)->prev->key >= c)) {
            (*lptr)=(*lptr)->prev;
        }
    }
    else if (c > (*lptr)->key) {
                while(((*lptr)->next!=NULL)&&((*lptr)->next->key <= c)) {
                        (*lptr)=(*lptr)->next;
                }
    }
    if ((*lptr)->key == c) {
        *f = (*lptr)->value;
        return 1;
    }
    return 0;
}

void printList(DL *l) {
    if (l == NULL) return;
    while (l->prev != NULL) { l=l->prev; };
    while(l != NULL) {
        printf("%d,%fn",l->key,l->value);
        l=l->next;
    }
}

int main(void) {
    DL *list=NULL;
    float f;
    list=insert(3,5.6,list); list=insert(4,5.3,list);
    list=insert(7,3.6,list); list=insert(1,7.7,list);
    list=insert(9,2.3,list); list=insert(0,9.0,list);
    printList(list);
    if (search(3,&f,&list)) {
        printf("Found %f.n",f);
    }
    else {
        printf("Not found.n");
    }
    printList(list);
    return 0;
}

这是输出:

0,9.000000
1,7.700000
3,5.600000
4,5.300000
7,3.600000
9,2.300000
Found 5.600000.
0,2.300000

我没有得到的是“搜索”功能.传递的列表是指向DL的指针,对吧?我们正在寻找一个数字,因为我们一直在做(* lptr)=(* lptr) – > next(或prev)迭代整个列表.我没有得到的是为什么第二次调用printList()打印整个列表…在调用search()之后,“list”不应该只有我们查找的元素之后的元素吗?指针被更改了,当我们从search()返回时,指针是否恢复到第一个元素并打印整个列表?

这是我没有得到的原因如果我改变了search()函数并在第一行添加(* lptr)= NULL,第二次调用printList()将不会打印任何东西,导致指针被更改,它是现在为NULL,没有什么要打印的.为什么不(* lptr)=(* lptr) – > next有类似的效果?指针也被改为下一个,不应该第二个printList()调用只打印列表中的其余元素?

编辑:
每个答案似乎都是正确的,我会按“最老的”排序并接受“最快的”,不要生气,我需要有一些标准.我可以继续看看哪个回答提供了更好的洞察力,但这是无关紧要的,因为我已经知道所说的一切.我只是愚蠢到甚至没有查看printList()函数并假设它没问题,我还假设错误是在search()函数的某个地方.但我知道我是对的,我知道指针正在改变,列表无法打印所有内容,但我明白为什么现在……

解决方法

这行返回指针:

while (l->prev != NULL) { l=l->prev; };

那些做印刷:

while(l != NULL) {
    printf("%d,l->value);
    l=l->next;
}

并且有更好的方法可以做到这一点,只需添加额外的字段,或者甚至是两个总是指向列表开头和结尾的字段.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读