链表的自底向上归并排序

链表的自底向上归并排序

 

应一网友编写了链表的自底向上归并排序程序如下:

#include <stdio.h>

#include <stdlib.h>

 

#define less(A,B)(A<B)

typedef int Item;

 

typedef struct _Qnode{

  Item item;

  struct _Qnode *next;

} Qnode, *link;

 

typedef struct

{

  link head;

  link tail;

} Queue;

 

void print_qnode(link a)

{

  while(a)

  {

    printf(" %d",a->item);

    a=a->next;

  }

  printf("/n");

}

 

void concatenate(Queue *q, Queue *p)

{

  if (q->head)

  {

    q->tail->next=p->head;

    q->tail=p->tail;

  }

  else

  {

    *q=*p;

  }

}

 

void merge(link a,link b, Queue *q)

{

  Qnode head;

  link c=&head;

  while((a!=NULL)&&(b!=NULL))

    if(less(a->item,b->item))

    {

      c->next=a;

      c=a;

      a=a->next;

    }

    else

    {

      c->next=b;

      c=b;

      b=b->next;

    }

  c->next=(a==NULL)?b:a;

  q->head=head.next;

  while(c)

  {

    q->tail=c;

    c=c->next;

  }

}

 

link mergesort(link head, int node_size)

{

  link a_head,b_head,a_tail,b_tail,remained_node;

  Queue p,q;

  int i,j;

  if(head==NULL || head->next==NULL) return head;

  remained_node=head;

  //i2的倍数增加

  for(i=1; i<node_size; i*=2)

  {

    q.head=NULL;

    do

    {

      a_head=a_tail=remained_node;

      b_tail=remained_node->next;

      //a_tailb_tail,使ab中各有i个节点。

      for (j=1; j<i; j++)

      {

        if (a_tail) a_tail=a_tail->next;

        if (b_tail) b_tail=b_tail->next;

        if (b_tail) b_tail=b_tail->next;

      }

      if (b_tail)

      {

        remained_node=b_tail->next;

        b_tail->next=NULL;//使b与原始链断开

      }

      else//b中不足i个节点

      {

        remained_node=NULL;

      }

      if (a_tail)

      {

        b_head=a_tail->next;

        a_tail->next=NULL;//使a与原始链断开

        merge(a_head,b_head,&p);//ab合并排序后存入p

        concatenate(&q,&p);//p与上次合并排序的结果相连

      }

      else//只有a没有b

      {

        merge(q.head,a_head,&p);

        q=p;

      }

    }while(remained_node);

    remained_node=q.head;

  }

  return q.head;

}

 

int main()

{

  int i;

  int node_size;

  Queue q;

  link a_head,b_head,a,b,c;

  a=(link)malloc(sizeof(Qnode));

  b=(link)malloc(sizeof(Qnode));

  a->item=10;

  b->item=30;

  a_head=a;

  b_head=b;

  node_size=0;

  for(i=0;i<10;i++)

  {

    a->next=(link)malloc(sizeof(Qnode));

    a->next->item=rand()%120;

    a=a->next;

    node_size++;

  }

  a->next=NULL;//清尾

  for(i=0;i<11;i++)

  {

    b->next=(link)malloc(sizeof(Qnode));

    b->next->item=rand()%200;

    b=b->next;

    node_size++;

  }

  b->next=NULL;//清尾

 

  print_qnode(a_head);

  print_qnode(b_head);

 

  merge(a_head,b_head,&q);

  c=q.head;

  print_qnode(c);

  printf("/n");

  c=mergesort(c, node_size);

  print_qnode(c);

  return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值