使用C语言删除链表中的重复项

时间:2014-04-15 15:50:15

标签: c linked-list

我正在尝试创建一个removeDuplicates函数,该函数在链表中查找重复值,调用并将索引中的这些重复值传递到removeNode函数中(这将删除这些重复值)。 removeDuplicates函数还返回已删除的重复值的计数。

但是我的代码中有一些错误,在我选择选项3之后必须强制停止程序,这是调用removeDuplicates函数的选项。

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

typedef struct _listnode
{
    int item;
    struct _listnode *next;
} ListNode;

typedef struct _linkedlist 
{
    int size;
    ListNode *head;
    ListNode *tail;
} LinkedList;

// FUNCTION PROTOTYPES
void createLinkedList(LinkedList *ll);
void printList(LinkedList *ll);
ListNode * findNode(LinkedList *ll, int index);
int insertNode(LinkedList *ll, int index, int value);
int insertSorted (LinkedList *ll, int value);
int removeDuplicates(LinkedList *ll);
int removeNode(LinkedList *ll, int index);

int main()
{
    int choice, value = 0;
    LinkedList l;
    l.head = 0;
    l.size = 0;

    printf("\n1: createLinkedList\n");
    printf("2: insertSorted\n");
    printf("3: removeDuplicates\n");
    printf("4: quit\n");

    do
    {
        printf("\nChoose an option: ");
        scanf("%d", &choice);
        fflush(stdin);

        switch (choice)
        {

            case 1:
                      createLinkedList(&l);
                      printList(&l);
                      break;
            case 2:
                      insertSorted(&l, value);
                      break;

            case 3:
                      printf("%d numbers were removed from the list", removeDuplicates(&l));
                      break;
        }
    } while (choice < 4);
    return 0;
}

.
.
.
(Other functions)
.
.
.

int removeDuplicates(LinkedList *ll)
{
    int index = 0;
    int count = 0;
    ListNode *pre, *cur;
    ListNode *temp = ll->head;

    if (temp == NULL)
        return;

    pre = ll->head;
    cur = pre->next;

    while (temp != NULL)
    {
        if ((pre->item == cur->item) && index < ll->size)
        {
            count++;
        }

        pre = cur->next;
        index++;

        if ((pre->item == cur->item) && index < ll->size)
        {
            count++;
        }

        cur = pre->next;
        index++;

        removeNode(&ll, index);
    } 
    printList(ll);
    return count;
}

int removeNode(LinkedList *ll, int index)
{

    ListNode *pre, *cur;

    // Highest index we can remove is size-1
    if (ll == NULL || index < 0 || index >= ll->size)
        return -1;

    // If removing first node, need to update head pointer
    if (index == 0)
    {
        cur = ll->head->next;  
        free(ll->head);        
        ll->head = cur;        
        ll->size--;            

        if (ll->size == 0)     
            ll->tail = 0;

        return 0;
    }

    // Find the nodes before and after the target position
    // Free the target node and reconnect the links
    if ((pre = findNode(ll, index - 1)) != NULL)
    {   

        // Removing the last node, update the tail pointer
        if (index == ll->size - 1)
        {
            ll->tail = pre;     
            free(pre->next);    
            pre->next = NULL;   

        else      
        {
            cur = pre->next->next;   
            free(pre->next);         
            pre->next = cur;         
        }
        ll->size--;      
        return 0;
    }

    return -1;
}

4 个答案:

答案 0 :(得分:0)

在removeDuplicates函数中看到这个while循环,

 while (temp != NULL)
    {
        if ((pre->item == cur->item) && index < ll->size)
        {
            count++;
        }

        pre = cur->next;
        index++;

        if ((pre->item == cur->item) && index < ll->size)
        {
            count++;
        }

        cur = pre->next;
        index++;

        removeNode(&ll, index);
    } 

这个循环永远不会结束,因为你没有修改temp的值。所以代码可以正确地结束循环。

答案 1 :(得分:0)

考虑

将元素复制到数组中。

对数组进行排序。

迭代数组,挑选非重复数据并使用它们构建新列表。

删除旧列表中的元素。

将旧列表的头部指向新列表。

答案 2 :(得分:0)

遵循以下简单步骤:

  1. 将所有值复制到数组中。
  2. 对数组进行排序(qsort)。
  3. 将所有唯一值写回列表中(如果之前的值相同,则只需跳过)。
  4. 删除所有未覆盖的节点。

答案 3 :(得分:0)

    void removeDuplicates ( )
{
    Node *current, *prev, *next, *ptp;
    ptp = current = prev = next = root;
    while ( current != NULL)
    {
        ptp = prev = next = current;
        next = next -> link;
        while ( next != NULL)
        {
            if ( next -> data == current -> data )
            {
                prev = next;
                next = next -> link;
                free (prev);`enter code here`
                prev = ptp;
                ptp -> link = next;
            } else
            {
                prev = next;
                ptp = next;
                next = next -> link;
            }
        }
        current = current -> link;
    }
}