两个链表的合并功能无效

时间:2015-11-28 04:37:40

标签: c linked-list

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

typedef struct listNode *listPointer;

struct listNode{
    int data;
    listPointer link;
};

int boolean_search(listPointer f, int q) {
    listPointer t = f;
    while(t){

        if(q == t->data){
            return 1;
        }         
       t = t ->link;
    }
    return 0;
}
listPointer elem_search(listPointer f, int q) {
    listPointer t = (listPointer) malloc(sizeof(listPointer));
    t->data = -1;
    t->link =f;
    while(t){

        if(q == t->data){
            //printf("Match Found");
            return t;
        }         
       t = t ->link;
    }
    return NULL;
}
void del_num(listPointer f, int q) {
    listPointer temp = elem_search(f, q), z;
    if(temp) {
    z=temp;
    temp = temp->link;
    free(z);
    }
}

void delete_trial(listPointer x,int num) {
    del_num(x, num);
}

listPointer create(int start, int finish)
{
    int i = 0, flag = 1;
    listPointer created = (listPointer) malloc(sizeof(listPointer)), st = NULL;

    for( i = start; i < finish; i++)
    {
        listPointer temp = (listPointer) malloc(sizeof(listPointer));
        int num = rand() % 50;
        //printf("%d",search(st, num));
        if(flag == 1 && num !=0) {
            temp->data = num;
            temp->link = NULL;
            created = temp;
            st = created;
            flag = 0;

        } else if(!boolean_search(st, num) && num !=0)
        {
            //printf("I am here");
            temp->data = num;
            temp->link = NULL;
            created->link = temp;
            created = temp;
        }
    }
    return st;
}

void display(listPointer start){
    listPointer temp = start;
    printf("\nContents of given pointer : ");
    while(temp){
        printf("%d ",temp->data);
        temp = temp->link;
    }
}

int count_list( listPointer x) {
    listPointer y =x;
    int count = 0;
    while(y) {
        count ++;
        y = y->link;
    }
    return count;
}
int count_non_zero(listPointer x) {
    listPointer y =x;
    int count = 0;
    while(y) {
        if(y->data != 0 )count ++;
        y = y->link;
    }
    return count;
}
int scan_least_no(listPointer x){
    int least = x->data, z;
    listPointer y = x;
    while(y)
    {
        z = y->data;
        if(( z < least) && z != 0){
            least = z;
        }
        y = y->link;
    }
    return least;
}
listPointer scan_least_ptr(listPointer x){
    int least = x->data, z;
    listPointer y = x, f = x;
    while(y)
    {
        z = y->data;
        if(( z < least) && z != 0){
            least = z;
            f = y;
        }
        y = y->link;
    }

    return f;
}

listPointer merge_asc(listPointer a, listPointer b) {
    listPointer result = (listPointer) malloc(sizeof(listPointer));
    result->data = -1;
    result ->link = NULL;

    int countA = count_non_zero(a), countB = count_non_zero(b), flag =0;//flag 0 for A, flag 1 for B
    int leastNum = 0, leastNumA = 0, leastNumB = 0; 

    listPointer result_start = result, copyA = a, copyB =b;

    printf("Count of listA : %d, listB : %d", countA, countB);
    //scanning least element
    //compare every element to existing ,the least one in connected to the link of that node


    while((countA + countB) != 0)
    {
        printf("Stuck in here");
        if(countA > 0)
        {
            //if least from here flag 0
            leastNumA = scan_least_no(copyA); 

        } else if(countB > 0)
        {
            //if least from here flag 1
            leastNumB = scan_least_no(copyA);
        }
        if(leastNumA < leastNumB)
        {
            flag = 0;
            leastNum = leastNumA;
        } else {
            flag =1;
            leastNum = leastNumB;
        }


        if(flag == 0)
        {
            result ->link = elem_search(copyA, leastNum);
            result = result ->link;
            delete_trial(a, leastNum); 
        }else if(flag == 1){
            result ->link = elem_search(copyB, leastNum);
            result = result ->link;
            delete_trial(b, leastNum);
        }
        countA = count_non_zero(copyA);
        countB = count_non_zero(copyB);
    }

    printf("\nMerged Pointer : ");
    display(result_start);
    return result_start;
}


int main()
{
    listPointer a = create(10,20), b = create(1, 30), c;
    display(a);
    display(b);
    c = merge_asc(a, b);
    display(c);
    return 0;
}

此程序采用两个链接列表,并从现有链接列表中创建一个新的链接列表。 约束:元素应按升序排列,新的链表应使用现有节点

问:“让x = x1,x2,x3,xn和y = y1,y2,y3,yn是两个链接列表。编写一个程序将两个列表合并在一起形成一个新的链表 z 其中节点按升序排列。在合并x之后,y不作为单独的列表存在。最初在x ad y中的每个节点现在都在z“中。

我无法弄清楚我的 merge_asc 功能有什么问题,因为输出卡住“给定指针的内容:33 36 27 15 43 35 42 49 21”
我在想,在删除功能中,由于自由功能,我的程序中没有考虑到这一点。

任何人都可以告诉我什么是错的或者解决方案是什么以及在这些情况下我应该采取什么方法?

我测试过所有其他功能,但它们运行正常。 我使用的是ubuntu 14.04和gcc4.8.4

1 个答案:

答案 0 :(得分:0)

给出两个未排序的列表

2 -> 7 -> 1
5 -> 3 -> 4

如果输入列表已排序,那么您将使用合并排序,并且可以在线性时间内完成,但由于这些是未排序的列表,因此您需要至少使用NlogN时间。我建议首先对其中一个输入列表进行排序,然后使用另一个列表的元素进行插入排序。

所以首先对第一个列表进行排序以获得

1 -> 2 -> 7

然后使用其他列表运行插入排序以获取

1 -> 2 -> 5 -> 7
1 -> 2 -> 3 -> 5 -> 7
1 -> 2 -> 3 -> 4 -> 5 -> 7