读书人

关于有序循环链表的归并解决方案

发布时间: 2012-02-05 12:07:14 作者: rapoo

关于有序循环链表的归并
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>


typedef struct NODE
{
int value; /*结点*/
struct NODE *next;
}Node;


void InsertBefore(Node *q1, Node *q2)//插入结点,引入结点p,可以让p插入到p2和p1之间
{
Node *p;

p = q1->next;
q1->next = q2;
q2->next = p;
}

Node *Del(Node *p1, Node *q)//删除结点q
{
p1->next = q->next;
return (q);


}



Node *Creat(int n)//创建链表
{
Node *cur, *p, *head;
int i;

head = (Node *)malloc(sizeof(Node)); //创建头结点
p = head;
printf("请输入结点 : ");
for(i = 0; i < n; i++)
{
cur = (Node *)malloc(sizeof(Node));

scanf("%d", &cur -> value);

p->next = cur;
p = cur;
}
p->next = head;
return head;
}


Node *Union(Node *head1, Node *head2)
{//合并链表
Node *p1, *p2, *ha, *hb;
ha = head1;
hb = head2;
p1 = ha->next;
p2 = hb->next;


while(p1!=head1 && p2!=head2)//链表都没结束
{
if(p1->value < p2->value)
{
ha = p1;
p1 = p1->next;//指针后移
}
else if(p1->value > p2->value)
{
if(p1 == head1->next) //p1指向头一个结点
{
Del(hb, p2);
head1->next = p2; //p2就要插入到头结点之后
p2->next = p1;
}
else
{
Del(hb, p2);
InsertBefore(ha, p2);//否则就插入到ha之后
}
p2=hb->next; //p2结点被删除,重新赋值
ha=ha->next; //ha之后多了一个结点要移到下一个结点
}
else //p1->value == p2->value
{
ha = p1;
p1 = p1->next; //p1向下移动一个结点
free(Del(hb, p2)); //p2要删除和释放,只取p1
p2=hb->next;
}
}
if(p2!=head2)//链表2没结束
{
ha->next = p2; //插入p2的剩余结点到ha中

}

free(head2);//释放
// head1=p1->next;
return head1;//返回头结点
}




void print(Node *head)//输出链表
{
Node *cur;//头结点
cur = head->next;

while(cur!= head)
{
printf("%d ", cur->value);
cur = cur->next;//指针后移
}
printf("\n");
}

void main()
{
Node *list1, *list2;//头结点
int num1, num2;

printf("请输入第一个结点数 : ");
scanf("%d", &num1);

list1 = Creat(num1);
printf("第一个链表的数据信息: \n");
print(list1);

printf("\n请输入第二个结点数 : ");
scanf("%d", &num2);

list2 = Creat(num2);
printf("第二个链表的数据信息: \n");
print(list2);

list1 = Union(list1, list2);


printf("\n合并后的数据信息 : \n");

print(list1);


}
归并有问题


[解决办法]
应该没必要做一个循环链表吧!!!
合并之后你没有把最后结点的next指向头结点,所以在调用print输出时,while(cur!= head)是无效的,会造成野指针的访问!
帮你修改了一下(假如循环链表你自己去修改一下合并函数):

C/C++ code
#include  <stdio.h > #include  <malloc.h > #include  <stdlib.h > typedef struct NODE {     int value;            /*结点*/     struct NODE *next; }Node; void InsertBefore(Node *q1, Node *q2)//插入结点,引入结点p,可以让p插入到p2和p1之间 {     Node *p;          p = q1->next;     q1->next = q2;     q2->next = p; } Node *Del(Node *p1, Node *q)//删除结点q {     p1->next = q->next;     return (q); } Node *Creat(int n)//创建链表 {     Node *cur, *p, *head;     int i;          head = (Node *)malloc(sizeof(Node)); //创建头结点     p = head;     printf("请输入结点 : ");     for(i = 0; i  < n; i++)     {         cur = (Node *)malloc(sizeof(Node));                scanf("%d", &cur -> value);                  p->next = cur;         p = cur;     }     p->next = NULL;     return head; } Node *Union(Node *head1, Node *head2) {//合并链表     Node *p1, *p2, *ha, *hb;     ha = head1;     hb = head2;     p1 = ha->next;      p2 = hb->next;              while(p1!=NULL && p2!=NULL)//链表都没结束     {         if(p1->value  < p2->value)          {             ha = p1;             p1 = p1->next;//指针后移         }         else if(p1->value  > p2->value)         {             if(p1 == head1->next)    //p1指向头一个结点             {                 Del(hb, p2);                 head1->next = p2;    //p2就要插入到头结点之后                 p2->next = p1;             }             else             {                 Del(hb, p2);                 InsertBefore(ha, p2);//否则就插入到ha之后             }             p2=hb->next;             //p2结点被删除,重新赋值             ha=ha->next;             //ha之后多了一个结点要移到下一个结点         }         else                         //p1- >value == p2- >value         {             ha = p1;             p1 = p1->next;           //p1向下移动一个结点             free(Del(hb, p2));       //p2要删除和释放,只取p1             p2=hb->next;         }     }     if(p2!=head2)//链表2没结束     {         ha->next = p2;               //插入p2的剩余结点到ha中     }     free(head2);//释放     //ha->next = head1;    return head1;//返回头结点 } void print(Node *head)//输出链表 {     Node *cur;//头结点     cur = head->next;          while(cur!= NULL)     {         printf("%d ", cur->value); ////////////        cur = cur->next;//指针后移     }     printf("\n"); }  void main() {     Node *list1, *list2;//头结点     int num1, num2;          printf("请输入第一个结点数 : ");     scanf("%d", &num1);          list1 = Creat(num1);     printf("第一个链表的数据信息: \n");     print(list1);          printf("\n请输入第二个结点数 : ");     scanf("%d", &num2);          list2 = Creat(num2);     printf("第二个链表的数据信息: \n");     print(list2);          list1 = Union(list1, list2);     printf("\n合并后的数据信息 : \n");     print(list1);   } 

读书人网 >C语言

热点推荐