链表删除节点问题

biu__biu_biu 2017-09-07 08:31:13
delete函数不能删除第一个节点(fuck_1),出现段错误;请教各位大佬,错误在哪儿。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct person
{
char *labe;
struct person *pre;
struct person *next;
};

struct jack
{
struct person p;
char name[10];
char food[10];
};

struct fuck
{
struct person p;
char name[10];
char food[10];
};

void print_jack(struct person *curr)
{
struct jack *t = (struct jack *)curr;

printf("%s eat %s\n",t->name,t->food);
}

void print_fuck(struct person *curr)
{
struct fuck *t = (struct fuck *)curr;

printf("%s eat %s\n",t->name,t->food);
}

void head_list(struct person **head, struct person *n)
{
n->pre = NULL;
n->next = *head;
if(NULL != *head)
{
(*head)->pre = n;
}
*head = n;
}

void travers(struct person *head, void (*fp)(struct person *))
{
fp(head);
}


void show(struct person *head)
{
if(NULL == head)
{
return;
}
while(head)
{
if(0 == strcmp(head->labe, "jack"))
{
travers(head,print_jack);
}
else
{
travers(head,print_fuck);
}
head = head->next;
}
}


void delete(struct person *head,void *key)
{
int ret = 0;
struct person *past = head;
struct person *curr = past;

while(curr)
{
if(0 == strcmp(curr->labe,"jack"))
{
if(0 == strcmp(((struct jack *)curr)->name, (char *)key))
{
past->next = curr->next;
free(curr);
curr = NULL;
ret += 1;
}
}
else
if(0 == strcmp(curr->labe,"fuck"))
{
if(0 == strcmp(((struct fuck *)curr)->name, (char *)key))
{
past->next = curr->next;
free(curr);
curr = NULL;
ret += 1;
}
}
if(0 == ret)
{
past = curr;
curr = curr->next;
}
}
}

int main()
{
int i = 5;
char jack[5][10] = {"jack_1","jack_2","jack_3","jack_4","jack_5"};
char jfd[10] = {"orange"};
char fuck[5][10] = {"fuck_1","fuck_2","fuck_3","fuck_4","fuck_5"};
char ffd[10] = {"apple"};
struct person *head = NULL;

while(i--)
{
struct jack *j = (struct jack *)malloc(sizeof(struct jack));

strcpy(j->name,jack[i]);
strcpy(j->food,jfd);
j->p.labe = "jack";
head_list(&head,&j->p);

struct fuck *f = (struct fuck *)malloc(sizeof(struct fuck));

strcpy(f->name,fuck[i]);
strcpy(f->food,ffd);
f->p.labe = "fuck";
head_list(&head,&f->p);
}

printf("=============\n");
delete(head,"fuck_1");
show(head);
return 0;
}
...全文
437 3 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
自信男孩 2017-09-11
  • 打赏
  • 举报
回复
引用 2 楼 biu__biu_biu 的回复:
感谢,还要考虑最后一个的情况,加上
 while(curr)
    {
        if(0 == strcmp(curr->labe,"jack"))
        {
            if(0 == strcmp(((struct jack *)curr)->name, (char *)key))
            {
                if(curr == *head)
                {
                    (*head)->next->pre = (*head)->pre;
                    *head = (*head)->next;
                }
                if(curr->next == NULL)  //考虑最后一个
                {
                    curr->pre->next = NULL;
                }
                else
                {
                    curr->next->pre = past;
                    past->next = curr->next;
                }
                free(curr);
                curr = NULL;
                ret += 1;
            }
        }
不用考虑,因为你的是双向循环链表。所以没有指向NULL的节点,最后一个节点的next指向head
biu__biu_biu 2017-09-07
  • 打赏
  • 举报
回复
感谢,还要考虑最后一个的情况,加上
 while(curr)
    {
        if(0 == strcmp(curr->labe,"jack"))
        {
            if(0 == strcmp(((struct jack *)curr)->name, (char *)key))
            {
                if(curr == *head)
                {
                    (*head)->next->pre = (*head)->pre;
                    *head = (*head)->next;
                }
                if(curr->next == NULL)  //考虑最后一个
                {
                    curr->pre->next = NULL;
                }
                else
                {
                    curr->next->pre = past;
                    past->next = curr->next;
                }
                free(curr);
                curr = NULL;
                ret += 1;
            }
        }
自信男孩 2017-09-07
  • 打赏
  • 举报
回复
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct person
{
    char *labe;
    struct person *pre;
    struct person *next;
};

struct jack
{
    struct person p;
    char name[10];
    char food[10];
};

struct fuck
{
    struct person p;
    char name[10];
    char food[10];
};

void print_jack(struct person *curr)
{
    struct jack *t = (struct jack *)curr;

    printf("%s eat %s\n",t->name,t->food);
}

void print_fuck(struct person *curr)
{
    struct fuck *t = (struct fuck *)curr;

    printf("%s eat %s\n",t->name,t->food);
}

void head_list(struct person **head, struct person *n)
{
    n->pre = NULL;
    n->next = *head;
    if(NULL != *head)
    {
        (*head)->pre = n;
    }
    *head = n;
}

void travers(struct person *head, void (*fp)(struct person *))
{
    fp(head);
}


void show(struct person *head)
{
    if(NULL == head)
    {
        return;
    }
    while(head)
    {
        if(0 == strcmp(head->labe, "jack"))
        {
            travers(head,print_jack);
        }
        else
        {
            travers(head,print_fuck);
        }
        head = head->next;
    }
}


void delete(struct person **head,void *key)
{
    int ret = 0;
    struct person *past = *head;
    struct person *curr = past;

    while(curr)
    {
        if(0 == strcmp(curr->labe,"jack"))
        {
            if(0 == strcmp(((struct jack *)curr)->name, (char *)key))
            {
                if (curr == *head) {
                    (*head)->next->pre = (*head)->pre;
                    (*head) = (*head)->next;
                } else {
                    curr->next->pre = past;
                    past->next = curr->next;
                }
                free(curr);
                curr = NULL;
                ret += 1;
            }
        }
        else if(0 == strcmp(curr->labe,"fuck")) {
            if(0 == strcmp(((struct fuck *)curr)->name, (char *)key))
            {
                if (curr == *head) {
                    (*head)->next->pre = (*head)->pre;
                    (*head) = (*head)->next;
                } else {
                    curr->next->pre = past;
                    past->next = curr->next;
                }
                //past->next = curr->next;
                //curr->next->pre = past;
                free(curr);
                curr = NULL;
                ret += 1;
            }
        }
        if(0 == ret)
        {
            past = curr;
            curr = curr->next;
        }
        printf("helloworld!\n");
    }
}


void del_person(struct person **head,void *key)
{
    int ret = 0;
    struct person *past = *head;
    struct person *curr = past;

    while(curr)
    {

        if( (0 == strcmp(curr->labe,"jack") && 0 == strcmp(((struct jack *)curr)->name, (char *)key))
               || (0 == strcmp(curr->labe,"fuck") && 0 == strcmp(((struct fuck *)curr)->name, (char *)key))) {
                if (curr == *head) {
                    (*head)->next->pre = (*head)->pre;
                    (*head) = (*head)->next;
                } else {
                    curr->next->pre = past;
                    past->next = curr->next;
                }
                free(curr);
                curr = NULL;
                ret += 1;
        }
        if(0 == ret)
        {
            past = curr;
            curr = curr->next;
        }
    }
}

int main(void)
{
    int i = 5;
    char jack[5][10] = {"jack_1","jack_2","jack_3","jack_4","jack_5"};
    char jfd[10] = {"orange"};
    char fuck[5][10] = {"fuck_1","fuck_2","fuck_3","fuck_4","fuck_5"};
    char ffd[10] = {"apple"};
    struct person *head = NULL;

    while(i--)
    {
        struct jack *jk = (struct jack *)malloc(sizeof(struct jack));

        strcpy(jk->name,jack[i]);
        strcpy(jk->food,jfd);
        jk->p.labe = "jack";
        head_list(&head,&jk->p);

        struct fuck *fk = (struct fuck *)malloc(sizeof(struct fuck));

        strcpy(fk->name,fuck[i]);
        strcpy(fk->food, ffd);
        fk->p.labe = "fuck";
        head_list(&head, &fk->p);
    }

    printf("Show list: \n");
    show(head);
    printf("=============\n");
    delete(&head, "fuck_1");
    //del_person(&head, "fuck_1");
    printf("Show list(After delete fuck_1): \n");
    show(head);
    return 0;
}
参考一下吧。delete函数逻辑是有问题的,上面是已经改过的。 另外,考虑你的delete函数代码逻辑有冗余,所以用del_person函数重写了你的这个功能。建议多测试删除的情况,这是删除头,试着删除中间节点和尾节点,都试试看看有没有问题。 看你的这个链表数据结构设计比较独特,看着像内核的链表结构设计。

33,321

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧