首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

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

2012-02-05 
关于有序循环链表的归并#include stdio.h#include malloc.h#include stdlib.htypedef struct NODE{i

关于有序循环链表的归并
#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);   } 

热点排行