实现两个有序单链表的合并。要求:随机创建两个单链表,实现单链表的排序,再对两个有序单链表进行合并。

来源:互联网 发布:英语网络热词怎么来的 编辑:程序博客网 时间:2024/05/18 00:42

实现两个有序单链表的合并。要求:随机创建两个单链表,实现单链表的排序,再对两个有序单链表进行合并。

=================================


源代码

#include <iostream>

using namespace std;

template <typename T>

class node

{

   public:

      T nodeValue;      // data held by the node

      node<T> *next;    // next node in the list

      node() : next(NULL) {};

      node(const T& item, node<T> *nextNode =  NULL) :  nodeValue(item), next(nextNode){};

};

 

#include "node.h"

#define size 10        //宏定义size10

 

#include<stdio.h>       //随机数

#include<stdlib.h>

#include<time.h>

#define random(x) (rand()%x)

 

node <int> *OrderList(node <int> *p,node <int> *&first);     //声明排序子函数,生成随机链表,排序后成为有序链表

node <int> *merge(node <int> *p1,node <int> *p2);       //声明合并子函数,实现2个有序链表合并成一个新的有序链表

void input(node <int> *p);                              //声明输出子函数,输出链表

 

int main(int argc, char* argv[])

{

node <int> *p1=NULL;

node <int> *first1=NULL;

node <int> *p2=NULL;

node <int> *first2=NULL;

node <int> *p3=NULL;

 

srand(time(0));

cout<<"第一个有序单链表:"<<endl;

p1=OrderList(p1,first1);                   

cout<<"第二个有序单链表:"<<endl;

p2=OrderList(p2,first2);

cout<<"合并两个有序链表:"<<endl;

p3=merge(p1,p2);

input(p3);

cout<<endl;

return 0;

}

 

node <int> *OrderList(node <int> *p,node <int> *&first){

void InsertSort(node <int> *pre,node <int> *curr,node <int> *p,node <int> *&first);//声明插入排序子函数,链表插入排序,实现递增

int x;

node <int> *pre=NULL;     //声明前驱指针,指向当前节点前一个节点

node <int> *curr=NULL;    //声明当前指针,指向当前所指向的节点

x=random(100);

    first=new node <int> (x);     //生成第一个节点

InsertSort(pre,curr,p,first);   //链表进行插入递增排序,调用插入排序子函数

p=first;   

input(p);    //输出有序链表

p=first;

return p;         

}

 

void InsertSort(node <int> *pre,node <int> *curr,node <int> *p,node <int> *&first){   //插入排序子函数

int x;

for(int i=2;i<=size;i++){

p=NULL;      //p指针为插入指针,每次生成一个节点,与链表中各个节点比较,然后插入链表

curr=first;    //当前指针初始化,为每次遍历比较作准备

pre=first;     //前驱指针初始化,为每次遍历比较作准备

x=random(100);

p=new node <int> (x);    //生成一个新节点,p->next=NULL

if((p->nodeValue) <= (first->nodeValue)){    //新插入的节点需要和头节点比较

p->next=first;    //比头节点小,插在头结点之前

first=p;          //插入节点变成头节点

}else{

while(1){   //循环遍历来比较已生成的链表

if((p->nodeValue>= curr->nodeValue) && (curr->next==NULL)){ //当前节点是链表最后节点

curr->next=p;                                           //并且新插入节点也比当前节点大,插入链表最后

break;       //结束循环

}else if((p->nodeValue >= pre->nodeValue) &&   //插入节点比前驱节点大,比当前节点小

(p->nodeValue <= curr->nodeValue)){

p->next=pre->next;   //新插入节点插入前驱节点后,即当前节点之前

pre->next=p;         

break;      

}

pre=curr;    //前驱指针和当前指针交替前进

curr=curr->next;

}

}

}

}

 

node <int> * merge(node <int> *p1,node <int> *p2){   //实现2个有序链表合并成一个新的有序链表

    node <int> *p3=NULL;     //

    if(p1 == NULL){          //若第一个链表全部合并完,即p1已经指向链表最后

        return (p2);         //返回p2,即直接输出p2此时指向节点,遍历输出第二个链表余下部分

}

else if(p2 == NULL){

        return (p1);  

}

    if(p1->nodeValue <= p2->nodeValue)  //判断p1指向节点值小于p2指向节点值

    {  

        p3 = new node <int> (p1->nodeValue);   //p3生成一个节点,节点值为此时p1所指向节点值

        p3->next = merge(p1->next, p2);        //p3后继为p1->nextp2,需要递归判断

    }  

    else  

    {  

        p3 = new node <int> (p2->nodeValue);  

        p3->next = merge(p1, p2->next);  

    }  

    return (p3);       //返回p3 

 

void input(node <int> *p){

while (p!=NULL){        //输出链表

cout<<p->nodeValue<<" ";

p=p->next;

}

cout<<endl<<endl;

}


 

宏定义size10

生成p1,first1指针来指向第一条链表,将p1,first1作为实参传给OrderList子函数,在OrderList子函数中,首先声明插入排序子函数,链表插入排序,实现递增。在OrderList函数中声明前驱指针,指向当前节点前一个节点声明当前指针,指向当前所指向的节点。之后随即生成头节点,first指向链表第一个节点。调用InsertSort子函数进行插入排序,将pre,curr,p,first这4个指针作为实参传递过去。然后将p指向头指针,调用输出函数输出有序链表。第二条链表同理可得,不予累述。

在插入排序子函数InsertSort()中,一开始利用for循环循环size-1次,插入size-1个节点。循环中随即生成插入节点,而p指针为插入指针,每次生成一个节点,与链表中各个节点比较,然后插入链表,当前指针curr和前驱指针pre初始化指向头指针,为每次遍历比较作准备。一开始if判断与头节点相比较,小于头节点,p->next指向头指针,p变成头指针first。之后进入while(1)循环遍历链表让插入指针p所指向节点值与各个进行节点比较。若当前节点是链表最后节点,并且新插入节点也比当前节点大,插入链表最后,curr->next=p,

break结束循环,或者插入节点比前驱节点大,比当前节点小,新插入节点插入前驱节点后,即当前节点之前(p->next=pre->next; pre->next=p;),之后结束循环。而在while(1)循环中前驱指针pre和当前指针curr交替前进,以此实现在链表中间插入节点。

将传递回来的2个指针p1p2(已经指向各自链表头结点),p3=merge(p1,p2),作为实参传递给merge子函数,在merge函数中node <int> *p3=NULL,生成一个指向合并新链表的指针p3。一开始if(p1 == NULL){ return (p2); }else if(p2 == NULL){return (p1); }通过这个if-else来判断若其中一个链表全部归并给新链表,则直接返回另一个指针,在主函数按顺序输出(这2个是有序链表,所以顺序输出也是递增的)。之后的if-else来判断当p1指向节点值小于p2指向节点值,则p3生成一个节点,节点值为此时p1所指向节点值,p3后继为p1->nextp2,需要递归该merge函数进行判断。当p2指向节点值小于p1指向节点值情况同理,不予累述。之后返回指针p3,也就是在这个函数中,当p1p2一开始比较是,新链表一生成一个节点,就返回此时p3,在主函数调用input(p3)函数输出,利用正向递归,p3->next一直指下去,一直输出每一个节点,直到其中p1p2分别指向的链表其中之一先全部归并给新链表,则立刻返回另一个指针p,在主函数调用输出函数输出这个指针指向节点开始之后的节点值。

0 0
原创粉丝点击