c - 从排序链表中一次性删除 "2 duplicated"个元素

标签 c data-structures linked-list

void del_duplicated(struct node *first) {
    struct node *current = listfirst, *prev = listfirst, *tmp;
    if (current == NULL)
        printf("Nothing to delete !\n");
    while (current != NULL) {
        /* Keeping traverse the list to find the duplicated elements. */
        prev = current;
        current = current->next;

        /* for the first and second duplicated node such as 1 1 2 3 5 */
        if (prev->data == listfirst->data && current->data == listfirst->data) {
            listfirst = current->next;
            printf("LIST FIRST NOW AT %d", listfirst->data);
        }
        /* The rest requirement such as 1 2 4 4 5 convert to 1 2 5 */
        else if ((prev->next)->data == (current->next)->data) {
            (prev->next) = (current->next)->next;  /*this is point 2 to 5*/
            tmp = current;                 /*delete the node*/
            free(tmp);
            tmp = current->next;
            free(tmp);
        }
    }
}

我有一个链表问题,需要我从列表中删除“2 个重复节点”。 就像 1 1 2 3 5 转换为 2 3 5 一样。 并且 1 2 4 4 5 将转换为 1 2 5

但是我的程序崩溃了,因为指针指向一个奇怪的地方,我不知道为什么。 (.exe 已停止工作) 我认为我的移动指针逻辑是好的,但是...... error like this 我的逻辑附在我的源代码的注释中。

我是一名刚在台湾学习编程和计算机科学的学生。 请原谅我糟糕的英语。

1小时后编辑

我在两个判断语句中添加了 BREAK,效果很好。 但我不知道为什么。

void del_duplicated(struct node *first) {
    struct node *current = listfirst, *prev = listfirst, *tmp, *tmp2;
    if (current == NULL)
        printf("Nothing to delete !\n");
    while (current != NULL) {
        /* Keeping traverse the list to find the duplicated elements. */
        prev = current;
        current = current->next;
        //printf("prev %d,current %d\n", prev->data, current->data);
        //system("pause");
        /* for the first and second duplicated node such as 1 1 2 3 5 */
        if (prev->data == listfirst->data && current->data == listfirst->data) {
            listfirst = current->next;
            system("pause");
            break;
        }
        /* The rest requirement such as 1 2 4 4 5 convert to 1 2 5 */
        else if (current->data == (current->next)->data) {
            (prev->next) = (current->next)->next;  /* this is point 2 to 5 */
            tmp = current->next;
            tmp2 = current;                 /* delete the node */
            current = (current->next)->next;
            free(tmp);
            free(tmp2);
            break;
        }
    }
}

最佳答案

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

typedef struct node NODE;
struct node{
    int         data;
    NODE        *next;
    NODE        *prev;
};


NODE * find_node( NODE *first, int value){
    while( first ){
        if( first->data == value )
            return first;
        first = first->next;
    }
    return NULL;
}

NODE* delete_node( NODE  **pnd ){

    NODE *tmp, *nd;

    if(!pnd || !*pnd)
        return  NULL;

    nd  =      *pnd;
    tmp =      nd->next;



    if(nd->next)
        nd->next->prev =    nd->prev;

    if(nd->prev)
        nd->prev->next =    nd->next;

   free( nd );

   *pnd=NULL;

   return tmp;
}


void del_duplicated( NODE **first ) {
    NODE    *tmp,
            *dup,
            *current=*first;
    int val;
    while( current ){

        dup =   find_node(tmp,current->data);   // find in next nodes
        tmp =   current->next;
        val=    current->data;
        while(1){
            dup=find_node(tmp,val);
            if(!dup) break;

            while(dup){                         // delete all occurences
                if(dup == tmp)
                    tmp = dup->next;
                delete_node(&dup);
                dup=find_node(tmp,val);
            }
            delete_node(&current);              // delete current one aswell
       }     
       current=tmp;                                 

    }
}


NODE *new_node(NODE *parent,int value){

    NODE *nd =  malloc( sizeof( NODE ) );
    nd->prev =  parent;

    if( parent ){
        nd->next =      parent->next;
        if(parent->next)
            parent->next->prev =    nd;

        parent->next =  nd;
    }else
        nd->next =      NULL;

    nd->data =          value;

    return nd;

}



void free_nodes(NODE *root){
    NODE    *tmp;

    if(root && root->prev){
        root->prev->next =  NULL;
    }
    while(root){
        tmp =               root;
        root =              root->next;
        free( tmp );
    }
}

void print_nodes( NODE *root, char *text){

    if(text)
        printf("%s:\n", text);

    while( root ){
        printf("%d ", root->data );
        root =  root->next;
    }
    printf("\n");
}

int main( void ){
    NODE        *root;
    root =      new_node(NULL,10);

    new_node( root, 25);
    new_node( root, 25);
    new_node( root, 25);
    new_node( root, 20);
    new_node( root, 15);
    new_node( root, 16);
    new_node( root, 16);
    new_node( root, 5);

    print_nodes( root ,"\nWith duplicated items");
    del_duplicated(&root);
    print_nodes( root ,"\nDuplicated items removed");

    free_nodes(root);
    return 0;
}

关于c - 从排序链表中一次性删除 "2 duplicated"个元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34691083/

相关文章:

c# - 交换单个链表上的节点

c - 从 v-usb 项目了解 usbjoy 库中的数据结构

c - 仅磁盘写入,但 iotop 也显示读取

java - 对象在没有该对象引用的情况下得到更新?

具有侵入式链表的 C++ 循环依赖

java - 如何在 Java 中的链表上使用两个不同的迭代器?

c - C99:fscanf()设置eof早于fgetc()的标准做法吗?

c - 为什么 bits/libc-header-start.h 文件夹包含在 stdio.h header 中

java - 在 Java 中复制复杂的数据结构

java - 支持重复键的高效有序数据结构