求两个集合的合并运算链表法

又输出不了....目前觉得应该是ListInsert问题


```c
#include
#include
#include
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int ElemType;
typedef int Status;
struct LNode     /*结点定义*/
{
    ElemType data;
    struct LNode *next;
};
typedef struct LNode *LinkList;/*表的头指针类型*/
LinkList CreateList();
int ListLength(LinkList L);
Status GetElem(LinkList L,int i,ElemType *e);
Status LocateElem(LinkList L,ElemType e,int compare(ElemType x, ElemType y));
int compare(ElemType x,ElemType y);
void ListInsert(LinkList *L,ElemType i,ElemType e);
Status ListEmpty(LinkList L);
void Union(LinkList *La,LinkList Lb);
int main()
{
    LinkList q;
    LinkList La,Lb;
    La=CreateList();
    Lb=CreateList();
    if(!ListEmpty(La)&&!ListEmpty(Lb))
        Union(&La,Lb);
    q=La;
    while(q!=NULL)
    {
        printf("%d ",q->data);
        q=q->next;
    }
    return 0;
}



/*创建链表*/
LinkList CreateList()
{
    char ch;
    struct LNode *head=NULL,*p1,*p2;
    while(1)
    {
        p1=(LinkList)malloc(sizeof(LNode));
        p1->next=NULL;
        scanf("%d%c",&p1->data,&ch);
        if(head==NULL)
        {
            head=p1;
            p2=p1;
        }
        else
        {
            p2->next=p1;
            p2=p1;
        }
        if(ch=='\n')
            break;
    }
    return head;
}

/*单链表长度*/
int ListLength(LinkList L)
{
    int i=0;
    struct LNode *p;
    p=L;
    while(p)
    {
        p=p->next;
        i++;
    }
    return i;
}

/* *L为单链表的头指针。当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR*/
Status GetElem(LinkList L,int i,ElemType *e)
{
    int j=1;    /*j为计数器*/
    LinkList p=L;/* p指向第一个结点*/
    while(p&&j/*顺指针向后查找,直到p指向第i个元素或p为空*/
    {
        p=p->next;
        j++;
    }
    if(!p||j>i)
        return ERROR;
    *e=p->data;    /*取第i个元素*/
    return OK;
}



Status LocateElem(LinkList L,ElemType e,int compare(ElemType x, ElemType y))
{
    int i=1;
    LinkList p;
    p=L;
    for(i=0;i<ListLength(L);i++)
    {
        if(compare(p->data,e))
            return i;
        p=p->next;
    }
    return FALSE;
}

int compare(ElemType x,ElemType y)
{
    if(x==y)
        return TRUE;
    else
        return FALSE;
}



void ListInsert(LinkList *L,ElemType i,ElemType e)
{
    LinkList p,p1,p2;
    p1=*L;
    p2=*L;
    p->data=e;
    if(i==ListLength(*L))
    {
        while(p1!=NULL)
        {
            p2=p1;
            p1=p1->next;
        }
        p2->next=p;
        p->next=NULL;
    }
    else
    {
        if(i-1==0)
        {
            p->next=p1;
            *L=p;
        }
        else
        {
            if(i-1==0)
            {
                p->next=p1;
                *L=p;
            }
            else
            {
                p->next=p1;
                p2->next=p;
            }
        }
    }
}

/*若L为空表,则返回TRUE,否则返回FALSE*/
Status ListEmpty(LinkList L)
{
    if(L->next)
      return FALSE;
    else
      return TRUE;
}


void Union(LinkList *La,LinkList Lb)
{
    ElemType e;
    int La_len,Lb_len;
    int i;
    La_len=ListLength(*La);
    Lb_len=ListLength(Lb);
    for(i=1;i<=Lb_len;i++)
    {
        GetElem(Lb,i,&e);
        if(!LocateElem(*La,e,compare))
            ListInsert(La,++La_len,e);
    }
}




```

参考GPT和自己的思路:你的代码存在几个问题:

1.在ListInsert函数中,p指针没有被初始化,直接使用会出现不可预知的结果。应该先给p分配内存,例如:LinkList p=(LinkList)malloc(sizeof(LNode));

2.在ListInsert函数中,如果要在非末尾位置插入元素,需要分别记录p1和p2指针指向待插入位置前后的结点。你的代码中只有p1和p2都指向了头结点,无法正确处理非末尾位置的插入。

3.在调用Union函数时,应该先判断La和Lb是否为空,否则可能会出现不可预知的结果。

修正后的代码如下:

有序链表(非递减)序列合并的代码,供参考:

#include <stdio.h>
#include <stdlib.h>
typedef int ElementType;
typedef struct Node* PtrToNode;
struct Node {         //定义结点
    ElementType data;//结点数据域
    PtrToNode   Next;//结点指针域
};
typedef PtrToNode List;
 
void creatList(List* L)
{
    ElementType x;
    PtrToNode pt = NULL, pL = NULL ;
    while (1){
        scanf("%d", &x);
        if (x == -1)  break;        // 输入 -1 时,结束链表输入。
        pt = (List)malloc(sizeof(struct Node));
        pt->Next = NULL;
        pt->data = x;
        if (!(*L))
            (*L) = pt;
        else
            pL->Next = pt;
        pL = pt;
    }
}
void MergeList_L(List* L1, List* L2, List* L3)
{
    List  p1 = (*L1),  p2 = (*L2), p3 = (*L3);
    while (p1 && p2) {
        if (p1->data<= p2->data)
        {
            if (!(*L3))
                (*L3) = p1;
            else
                p3->Next = p1;
            p3 = p1;
            p1 = p1->Next;
        }
        else
        {
            if (!(*L3))
                (*L3) = p2;
            else
                p3->Next = p2;
            p3 = p2;
            p2 = p2->Next;
        }
    }
    if (!(*L3))
        (*L3) = p1 ? p1 : p2;
    else
        p3->Next = p1 ? p1 : p2;
    (*L1) = NULL;
    (*L2) = NULL;
}
 
void PrintList(List L)
{
    if (!L)
        printf("NULL");
    else{
        List p = L;
        while (p)
        {
            printf(p == L ? "%d" : " %d", p->data);
            p = p->Next;
        }
    }
}
int main()
{
    List La = NULL, Lb = NULL, Lc = NULL;
    creatList(&La);
    creatList(&Lb);
    MergeList_L(&La, &Lb, &Lc);
    PrintList(Lc);
 
    return 0;
}

运行结果:

img

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 这有个类似的问题, 你可以参考下: https://ask.csdn.net/questions/739493
  • 我还给你找了一篇非常好的博客,你可以看看是否有帮助,链接:程序的死锁及一些解决的关键办法
  • 除此之外, 这篇博客: 数据结构常用的算法中的 一、排序算法 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:

    本质上就是按照某种顺序将一组数排好,分多次重复进行,每次只负责把一个数字放到合适的位置上

    两种思路:

    ①先确定一个数字,然后根据数据找合适的位置

    ②先确定一个位置,根据位置找合适的数字

    1、冒泡排序算法(先确定位置,选最前面或者最后面)

    假设选择了最后面的位置,就是重复的把最大的数放到最后面,例如:

     代码实现:

     2、选择排序算法(只能选择最前面最后面的位置)

    那选择的位置向前或者向后依次与每一个数做顺序调整,例如:

     代码实现:

    3、插入排序

    先确定数字,假设前面的数已经排序好,把它们和相邻的后面的那个数字作为选定数字,把选定数字向前插入到合适的位置

     

    4、快速排序

     在数组中从头部或尾部选择一个数,然后进行排序,比如比它小的在左,比它大的在右,这个数就是枢轴,每次与枢轴进行比较进行顺序调整后的数,我们认为他们的相对位置已经固定,那么这个数就排出在外,不再处理。

    排好左右,左右两边分成两部分,在各自选定一个数再次进行这样的排序,注意只能从数组的两头选数,以此类推。

    这可以用递归函数来实现

     代码实现:

     


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^