Career Cup 2-1

来源:互联网 发布:excel软件下载 编辑:程序博客网 时间:2024/06/05 10:12
/*******************************************************

    2.1

    Write code to remove duplicates from an unsorted linked list
    FOLLOW UP
    How would you solve this problem if a temporary buffer is not allowed?

//  Note:  First sort the array using quicksort (or other nlogn sorting method??).
//    Then Traverse the list to see whether any adjacent identical pair exists.

//  Complexity: O(nlogn) ----if the order of elements can change.

    Bitmap- if buffer is allowed. O(n)
    rotationally insert the link list and every time do an insertion comparison. O(n^2).

  Mod Time: 5.3, 2012

  Copyright: Ben

  *******************************************************/

#include<stdio.h>
#include<malloc.h>

#define OK                    0
#define ERROR                -1

#define MYDEBUG                0

typedef int ElemType;

typedef int Status;

struct Node;
typedef Node ListNode;
typedef ListNode * Position;
typedef Position LinkList;

struct Node
{
    ElemType elem;    //this field of header should be NULL.
    Position next;
};

LinkList New_LinkList(void);
Status Print_LinkList(LinkList ll);
Status Append_LinkList(LinkList ll, ElemType val);
Status Destroy_LinkList(LinkList ll);
void RemoveDup(LinkList ll, ElemType val, int *pNumOfElem);
ElemType GetHeadElem(LinkList ll);
//void NewHead(LinkList ll, int NumOfElem);
ElemType DeleteNextNode(Position NodeTobeDel);

int main(void)
{
    int readInt;
    int NumOfElem = 0;    //counter of how many elements.
    int i, j;
    ElemType elem;
    Position TravNode, TempNode;
    LinkList list = New_LinkList();
    if(!list)
    {
        return ERROR;
    }
    
    freopen("array.txt", "r", stdin);

    /*
    while (1)
    {
        if  (fscanf(fin,"%d",&k) == EOF)
            break;
        NumOfElem++;   // 统计数据个数
    }
    */
    while(1)
    {
        if(scanf("%d", &readInt) == EOF)
        {
            break;
        }
        Append_LinkList(list, readInt);
        NumOfElem++;
    }

#if MYDEBUG
    printf("NumOfElem = %d\n", NumOfElem);
    //Print_LinkList(ll);
#endif

    //the link list is ready now.
    for(i = 0; i < NumOfElem; i++)
    {
        elem = GetHeadElem(list);
        RemoveDup(list, elem, &NumOfElem);
#if 0
        NewHead(list, NumOfElem);
#endif
        //make new head.
        TravNode = list;
        for(j = 0; j < NumOfElem - 1; j++)
        {
            TravNode = TravNode->next;
#if MYDEBUG
            printf("Traversing...Elem: %d\n", TravNode->elem);
#endif
        }
#if 0
        TempNode = TravNode->next;
        //originally this was NULL to indicate the end of the link list.
        //TravNode = list->next;    
        list->next = TempNode;
        TravNode->next = NULL;
#endif

#if MYDEBUG
            printf("Before Making new head...ListHead:Elem: %d\n", list->next->elem);
#endif

        //make new head.
        TempNode = list->next;
        list->next = TravNode->next;
        TravNode->next->next = TempNode;
        TravNode->next = NULL;

#if MYDEBUG
            printf("Making new head...ListHead:Elem: %d\n", list->next->elem);
#endif
    }
    
        //Sort_LinkList(list);
    Print_LinkList(list);

    fclose(stdin);

    Destroy_LinkList(list);

    return OK;
}

LinkList New_LinkList(void)
{
    LinkList ll = (LinkList)malloc(sizeof(ListNode));
    ll->elem = 0;
    ll->next = NULL;
    return ll;
}

Status Print_LinkList(LinkList ll)
{
    Position p = ll;

    if(!ll)    //trying to delete a linklist that does not exist
    {
        printf("trying to print a linklist that does not exist\n");
        return ERROR;
    }
    printf("The elements in link list: \n");
    while(p->next != NULL)
    {
        p = p->next;
        printf("%d\n", p->elem);
    }
    return OK;
}

Status Append_LinkList(LinkList ll, ElemType val)
{
    Position posi;
    if(!ll)    //trying to delete a linklist that does not exist
    {
        printf("trying to insert to a linklist that does not exist\n");
        return ERROR;
    }
    posi = ll;
    while(posi->next)
    {
        posi = posi->next;
    }

    posi->next = (Position)malloc(sizeof(ListNode));
    posi->next->next = NULL;
    posi->next->elem = val;

    return OK;
}

Status Destroy_LinkList(LinkList ll)
{
    Position posi, temp;
    if(!ll)    //trying to delete a linklist that does not exist
    {
        printf("trying to delete a linklist that does not exist\n");
        return ERROR;
    }
    
    posi = ll;
    ll->next = NULL;

    while(posi->next)
    {
        temp = posi->next;
        free(posi);
        posi = temp;
    }
    return OK;
}

void RemoveDup(LinkList ll, ElemType val, int *pNumOfElem)
{
    int j;
    Position p = ll->next;

    for(j = 1; j < *pNumOfElem; j++)
    {

#if MYDEBUG
        printf("val %d should be found.\n", val);
        printf("Remove Dup Find Elem: %d\n", p->elem);
#endif        
        if(p->next->elem == val)
        {
            DeleteNextNode(p);    //delete p->next
            (*pNumOfElem)--;        //The parenthesis is GOD D*** IMPORTANT!!!
        }
        else
        {
            p = p->next;
        }
    }
#if MYDEBUG
    printf("NumOfElem = %d\n", *pNumOfElem);
    //Print_LinkList(ll);
#endif
}

ElemType GetHeadElem(LinkList ll)
{
#if MYDEBUG
    printf("Head Elem: %d\n", ll->next->elem);
#endif
    return ll->next->elem;
}

#if 0
void NewHead(LinkList ll, int NumOfElem)
{
    int i;
    Position *TravNode = &ll;
    for(i = 0; i < NumOfElem; i++)
    {
        *TravNode = (*TravNode)->next;    
    }

    //originally this was NULL to indicate the end of the link list.
    (*TravNode)->next = ll->next;    
    ll->next = *TravNode;
    *TravNode = NULL;
}
#endif

//since NodeTobeDel needs to be changed, its pointer is used here as parameter.
ElemType DeleteNextNode(Position NodeTobeDel)
{
    Position TempNode = NodeTobeDel->next;
    ElemType val = NodeTobeDel->next->elem;

#if 0
    printf("NodeTobeDel: %d\n", NodeTobeDel->elem);
    printf("NodeTobeDel:add: %d\n", NodeTobeDel);
    printf("NodeTobeDel:next: %d\n", NodeTobeDel->next);
#endif

    NodeTobeDel->next = TempNode->next;

    free(TempNode);
    return val;
}