合并链表

来源:互联网 发布:java字符串数组 \0 编辑:程序博客网 时间:2024/06/06 23:52

//多种情况的时候,把每一种情况处理好了,再把它们合并起来。                                                                                                                                                  


#include <stdio.h>

#include <stdlib.h>

typedef struct_node {

               intkey;

               struct_node * next;

}node;



node * build_linked_list(void);

void print(node * );

nodemerge(node *,node * );


int main(void)

{

  //建立链表,并返回头指针                                                                                                                                                                                  

  node * head_of_linked_list1=build_linked_list();

  //打印链表                                                                                                                                                                                                

  print(head_of_linked_list1);

  node * head_of_linked_list2=build_linked_list();

  print(head_of_linked_list2);


  //合并两个已经排列好顺序的链表,并返回这个新链表的头指针                                                                                                                                                  

  nodenew_head= merge(head_of_linked_list1,head_of_linked_list2);

  print(new_head);

}



//建立链表                                                                                                                                                                                                  

/*建立链表的时候要维护两个节点                                                                                                                                                                              

    1. 当前节点和                                                                                                                                                                                           

    2.当前节点的前一个节点                                                                                                                                                                                  

 */

node * build_linked_list(void)

{ puts("Enter the key in ascending order (q to quit) ");

  node * head=NULL;

  node * prev;

  node *current;

  int key;

  char ch;

  while(scanf("%d",&key)==1)

    { current=(node * )malloc(sizeof(node));

      current->next=NULL;

      current->key=key;

      if (head==NULL)

        head=current;

      else

        prev->next=current;

      prev=current;

  }

  //读取缓存里面的字符,并抛掉                                                                                                                                                                              

  while(getchar()!='\n')

    continue;

  return head;

}

void print(node *head)

{ puts("The linked list:\n");

  while (head!=NULL)

    {  printf("%d ",head->key);

      head=head->next;

   }

  puts("\n");

}

/*   合并两个已经排好序(由大到小)的链表                                                                                                                                                                     

     #####################算法思想####################                                                                                                                                                      

        表一、表二的头指针分别问head1、和head2,如下所示                                                                                                                                                    

        head1->n1->n2->n3                                                                                                                                                                                   

        head2->N1->N2->n3                                                                                                                                                                                   

        1.假设把表2插入表1。循环表2,依次把表2的节点插入                                                                                                                                                    

        到表1的合适位置上。                                                                                                                                                                                 

        2. 在进行插入操作的时候有如下几种情况需要考虑:                                                                                                                                                     

           为了方便书写,只写出节点的key值。                                                                                                                                                                

           1.  表一:1  3  5   8                                                                                                                                                                            

               表二 :   2  4  6                                                                                                                                                                             

               Max(表1)>Max(表2) 并且 Min(表1)<Min(表2)                                                                                                                                                     

               这种情况表1的头指针不会该边表                                                                                                                                                                

           2.  表1:  1  3  5  8                                                                                                                                                                             

               表2: 0 2  4                                                                                                                                                                                  

               Max(表1)>Max(表2) 并且 Min(表1)>Min(表2)                                                                                                                                                     

               这种情况头指针需要改标                                                                                                                                                                       

           3.  表1:  1  3  5  8                                                                                                                                                                             

               表2:    2        9  10  11                                                                                                                                                                   

               Max(表1)<Max(表2) 并且 Min(表1)>Min(表2)                                                                                                                                                   \

               直接把key值为9(包括该节点)之后的所有节点都插入到表1的结尾                                                                                                                                   

                                                                                                                                                                                                            

     #######################代码实现################                                                                                                                                                        

     函数的输入值是两个待合并链表的头指针                             

   输出值是合并后的链表的头指针                                                                                                                                                                           

        head--随时保持指向合并链表的头                                                                                                                                                                      

        prev、head1-指向被插入链表的相邻两个节点                                                                                                                                                            

        head1指向正好大于待插入节点的被插入链表中的节点                                                                                                                                                     

        prev指向正好小于待插入节点的被插入链表中的节点                                                                                                                                                      

        temp-用来临时存储插入链表的头位置                                                                                                                                                                   

                                                                                                                                                                                                            

*/

node * merge(node *head1,node *head2)//把head2所指向的表插入到head1所指向的表里面                                                                                                                         

{ // puts("There");                                                                                                                                                                                         

  node *head=head1;//保存head1原始所指向的位置                                                                                                                                                             

   node *prev=head1;

   node *temp;

   //循环链表2的节点                                                                                                                                                                                        

   while(head2!=NULL)

     {  while(head1!=NULL && head1->key<head2->key)//如果head1所指向的位置不为空并且执行的元素小于待插入                                                                                                    

         { prev=head1;  // 保存下来此时head1的位置                                                                                                                                                          

           head1=head1->next;//head1指向链表的下一个节点                                                                                                                                                    


        }

       //这段代码专门用来处理情况二,相当于重新生产了两个新的链表,然后,再跳出循环,情况二现在转换成了情况1或者情况3。                                                                                     

       temp=head2->next; //首先保存下head2所指向链表的下一个元素的位置                                                                                                                                      

       // 处理情况3并返回                                                                                                                                                                                   

       if (head1==NULL)

         { prev->next=head2;

           return head;

         }


       if(head1==head)//如果出现情况2                                                                                                                                                                       

         {

            head2->next=head1;//head2的第一个节点的next链表1的头                                                                                                                                            

            head1=head2;//把header1指向增加了一个节点的❤新链表                                                                                                                                              

            head=head2;//修改head指针的值                                                                                                                                                                   

            head2=temp;//head2指向下一个节点                                                                                                                                                                

            continue;//继续下次循环                                                                                                                                                                         

        }


       //prev的next指向这个节点                                                                                                                                                                             

       // 并修改prev的值                                                                                                                                                                                    

      else

      {   prev->next=head2;

          prev=head2;

      }

       // 修改这个header指针,指向head1                                                                                                       

 head2->next=head1;

      //head2指向链表2的下一个元素                                                                                                                                                                          

      head2=temp;


    }

   //正常返回。                                                                                                                                                                                             

   return head;

}

##############################################测试####################################################


$ ./a.out

Enter the key in ascending order (q to quit) 

1 3 5 8 q

The linked list:


1 3 5 8 

表1

Enter the key in ascending order (q to quit) 

-1 0 4 6 7 10 11 q

The linked list:

表2

-1 0 4 6 7 10 11 


表1、表2合并后的结果

The linked list:


-1 0 1 3 4 5 6 7 8 10 11 




原创粉丝点击