链表的排序1


已知两个链表head1和head2各自有序,请把它们合并成一个链表仍然有序,要求用递归 方法实现。

#include <iostream.h>

#include <string.h>

 

struct Node

{

   int num;

   Node *next;

};

 

Node *Merge(Node *head1,Node *head2)

{

   if(head1==NULL)

       return head2;

   if(head2==NULL)

       return head1;

   Node *head=NULL;

   if(head1->num<head2->num)

    {

       head=head1;

       head->next=Merge(head1->next,head2);

    }

   else

    {

       head=head2;

       head->next=Merge(head1,head2->next);

    }

   return head;

}

 

 

2、递增有序的2个单链表合并成一个递增有序的单链表,不用任何库函数调用

/*
题目描述: 2个递增有序的单链表,请你把它两个合并成一个有序
的单链表,分普通和不能用任何库函数2种方法
作者: iaocui
时间: 2007.11.4
版本: v1.0
*/

/* 说明: 如果采用一般的做法,直接申请新的空间,组成一个新的
单链表,直接进行归并就可以得到整体的有序序列,这个相对比较简单。

如果不能用任何库函数,也就是不能利用malloc分配内存,就是要利用
现有的2个链表,进行元素交换得到最后有序的链表。

*/

#include <iostream>
using namespace std;

/* 单链表节点 */
struct node
{
int value;
node* next;
};

/* 给单链表添加节点 */
void insertNode(node* head, int value)
{
node* p = head->next;
if ( p == NULL )
{
   p = new node;
   p->value = value;
   p->next = NULL;
   head->next = p;
   return;
}

while ( p->next != NULL )
{
   p = p->next;
}
node* tmp = new node;
tmp->value = value;
tmp->next = NULL;
p->next = tmp;
}

/* 遍历输出链表节点 */
void print(node* head)
{
node* p = head->next;
while ( p != NULL )
{
   cout << p->value << " ";
   p = p->next;
}
cout << endl;
}

/* 利用一般的方法进行合并,形成整体递增有序*/
node* formalMerge(node* headA, node* headB)
{
node* head = new node;
head->next = NULL;

node* p = headA->next;
node* q = headB->next;
if ( p == NULL )
{
   return headB;
}
if ( q == NULL )
{
   return headA;
}

while ( (p != NULL) && (q != NULL) )
{
   if ( p->value == q->value )
   {
    insertNode(head, p->value);
    insertNode(head, q->value);
    p = p->next;
    q = q->next;
   }
   else if ( p->value < q->value )
   {
    insertNode(head, p->value);
    p = p->next;
   }
   else if ( p->value > q->value )
   {
    insertNode(head, q->value);
    q = q->next;
   }
}
while ( p != NULL )
{
   insertNode(head, p->value);
   p = p->next;
}
while ( q != NULL )
{
   insertNode(head, q->value);
   q = q->next;
}

return head;
}

/* 下面实现不使用任何库函数, 利用交换的方法在原空间实现整体有序。 方法是先确定哪一个链表
的第一个节点的值小,把这个链表的头结点作为合并后链表的头结点,然后比较2个有序链表的当前节点
的值,如果代表最后合并链表的值小,则不用交换,否则把两个值交换,最后合并链表始终保持两个值中
的小值。另一个链表由于交换了一个元素,当前元素可能影响该链表的有序递增,对其进行调整使其保持
递增有序,然后重复上述动作,直到一个链表遍历结束,然后把剩余的链表连接起来就行。*/

/* 调整链表的第一个节点,使其变成递增有序*/
void chg2sort(node* head, node* &p)
{
if (head->next == NULL ) //没有节点,直接返回
{
   return;
}

node* s = head;
while ( s->next != p ) //s指向p的前一个节点
{
   s = s->next;
}

//下面的一段找到第一个大于p节点值的节点
node* q = p;
node* r = q;
while ( q != NULL )
{
   if ( q->value <= p->value )
   {
    r = q; //r始终指向q的前一个节点
    q = q->next;
   }
   else
   {
    break;
   }
}

//下面调整指针,其实可以统一写出来,为了阅读清晰把q为NULL和非NULL分开写出来

if ( q == NULL )
{
   r->next = p;
   s->next = p->next;
   p->next = NULL;
}
else if ( q != NULL )
{
   s->next = p->next;
   r->next = p;
   p->next = q;
}

//由于链表进行了调换,当前链表指针也需要改变
p = s->next;
}

/* 两个有序链表进行合并 */
node* merge(node* head1, node* head2)
{
node* head; //合并后的头指针
node* p = head1->next;
node* q = head2->next;

//有一个链表为空的情况,直接返回另一个链表
if ( p == NULL )
{
   head = head2;
   return head;
}
else if ( q == NULL )
{
   head = head1;
   return head;
}

//两个都不为空,先确定哪个链表作为合并后的链表
if ( (p != NULL) && (q != NULL) )
{
   if ( p->value < q->value )
   {
    head = head1;
   }
   else
   {
    head = head2;
   }
}

node* p_prior; //始终指向p节点的前一个节点
node* q_prior;

while ( (p != NULL) && (q != NULL))
{
   if ( p ->value < q->value )
   {
    if ( head == head1 )
    {
     p_prior = p;
     p = p->next;
    }
    else if ( head == head2 )
    {
     //进行当前节点值的交换
     int tmp = p->value;
     p->value = q->value;
     q->value = tmp;
     chg2sort(head1, p); //交换元素后的调整
     q_prior = q;
     q = q->next;
    }
   }
   else if ( p->value == q->value )
   {
    p_prior = p;
    p = p->next;
    q_prior = q;
    q = q->next;
   }
   else if ( p->value > q->value )
   {
    if ( head == head1 )
    {
     int tmp = p->value;
     p->value = q->value;
     q->value = tmp;
     chg2sort(head2, q);
     p_prior = p;
     p = p->next;
    }
    else if ( head == head2 )
    {
     q_prior = q;
     q = q->next;
    }
   }
}

if ( p != NULL )
{
   q_prior->next = p;
}

if ( q != NULL )
{
   p_prior->next = q;
}

return head;
}

int main()
{
/* 建立有序链表A */
int a[5] = {1, 5, 8, 10, 20};
node* headA = new node;
headA->next = NULL;
for (int i = 0; i < 5; ++i)
{
   insertNode(headA, a[i]);
}
print(headA);

/* 建立有序链表B */
int b[3] = {3, 4, 9};
node* headB = new node;
headB->next = NULL;
for (int i = 0; i < 3; ++i)
{
   insertNode(headB, b[i]);
}
print(headB);

/* 利用简单合并的方法合并成整体有序 */
node* head = formalMerge(headA, headB);
print(head);

int c[3] = {5, 4, 9};
node* headC = new node;
headC->next = NULL;
for (int i = 0; i < 3; ++i)
{
   insertNode(headC, c[i]);
}
print(headC);

//test chg2sort
chg2sort(headC, headC->next);
print(headC);

head = merge(headA, headB);
print(head);

return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值