浙大版「データ構造(第2版)」テーマ集-練習問題2.5両の秩序チェーンの連結(15点)

15598 ワード

本題は一つの関数を実現して、二つのチェーンが表しているインクリメントされた整数系列を一つのインクリメントされていない整数系列にマージします.
関数インターフェースの定義:
List Merge( List L1, List L2 );
List構造の定義は以下の通りである.
typedef struct Node *PtrToNode;
struct Node {
    ElementType Data; /*        */
    PtrToNode   Next; /*            */
};
typedef PtrToNode List; /*         */
L 1およびL 2は、所定の先頭ノードの単一チェーンテーブルであり、そのノードに格納されているデータは、インクリメント順序である.関数Mergeは、L 1とL 2をインクリメントしない整数系列に結合します.元のシーケンスの結点を直接使用して、帰結後の先頭結点のチェーンポインタを返します.
審判試験手順の例:
#include 
#include 

typedef int ElementType;
typedef struct Node *PtrToNode;
struct Node {
    ElementType Data;
    PtrToNode   Next;
};
typedef PtrToNode List;

List Read(); /*        */
void Print( List L ); /*       ;      NULL */

List Merge( List L1, List L2 );

int main()
{
    List L1, L2, L;
    L1 = Read();
    L2 = Read();
    L = Merge(L1, L2);
    Print(L);
    Print(L1);
    Print(L2);
    return 0;
}

/*            */
入力サンプル:
3 1 3 5 5 2 4 6 8 10
出力例:
1 2 3 4 5 6 8 NULL NULL
参照コード:
List Merge( List L1, List L2 )
{
    List head,tail,p,l1=L1,l2=L2;  //l1,l2        
    p=(List)malloc(sizeof(struct Node));  //   
    p->Next=NULL;
    head=tail=p;
    l1=l1->Next;     //   L1        
    l2=l2->Next;     //   L2        
    while(l1&&l2)
    {
        if(l1->Data<=l2->Data)
        {
            tail->Next=l1;
            tail=tail->Next;
            l1=l1->Next;
        }
        else
        {
            tail->Next=l2;
            tail=tail->Next;
            l2=l2->Next;
        }
    }
    for(;l1;l1=l1->Next)
    {
        tail->Next=l1;
        tail=tail->Next;
    }
    for(;l2;l2=l2->Next)
    {
        tail->Next=l2;
        tail=tail->Next;
    }
    tail->Next=NULL;
    L1->Next=NULL;
    L2->Next=NULL;
    return head;
}
他の2つの関数コード:
List Read()
{
    List head,tail,p;
    int i,n;
    scanf("%d",&n);
    for(i=0;i<=n;i++)
    {
        p=(List)malloc(sizeof(struct Node));
        p->Next=NULL;
        if(i==0)
        {
            head=tail=p;
        }
        else
        {
            scanf("%d",&p->Data);
            tail->Next=p;
            tail=p;
        }
    }
    return head;
}

void Print( List L )
{
    List t=L;
    if(t->Next==NULL)
    {
        printf("NULL
"
); } else { while(t->Next) { printf("%d ",t->Next->Data); t=t->Next; } printf("
"
); } }
考え方:
まず注意しなければならないのは三つのチェーンが率先して接合されていることです.この考え方は実は慕課の中で浙江大学のデータの構造の言う多項式の足し算の計算の構想ととても似ていて、その問題より更に簡単です.まず、二つのチェーンテーブルの中の最初のノードの数を比較します.誰が新しいチェーンテーブルに接続されているかを比較した後、続いてポインタが後の接合点(もう一つのチェーンゲージが動かない)を指し、一つのチェーンテーブルのすべての要素が処理されるまで比較を続けます.この時、私たちはもう一つのチェーンの残りの接合点をチェーンに接続した後(対応コードの中のforサイクル).最後にL 1、L 2チェーンを空にします.