データ構造とアルゴリズムの基礎 (Wang Zhuo) (8): 線形テーブルの応用 (和集合: 順序や繰り返しは不要)

目次

共用体セット: 線形テーブルのマージ (順序なし、繰り返しなし)

線形テーブル:

リンクされたリスト:


PPT: 第 2 章 P173;


共用体セット: 線形テーブルのマージ (順序なし、繰り返しなし)

線形テーブル:

Status Union(Sqlist& A, Sqlist& B)//并集
{
    int len_A = A.length;
    int len_B = B.length;
    for (int i = 1; i <= len_B; i++)
    {
        Poly e=*A.elem;
        //这里只是给我们设定的元素e赋一个任意初值
        //只要保证e在初始化时由初值不为空即可
        //至于该e元素的内容是什么其实并没有什么所谓
        //因为后面我们总归是会改的
        GetElem(B, i, e);
        if (LocateElem(A, e))
            return ERROR;
        else
            ListInsert(A, ++len_A, e);
        //注意插入函数中输入的是位序,不是数组下标
    }
    return true;
}

アルゴリズムの時間計算量: O(ListLenth(La) * ListLength(Lb))

最後のテーブル A は合併後の新しいテーブルです


リンクされたリスト:

Status Union(Lnode& A, Lnode& B)
{
    for (int i = 1; i <= 求表长(&B); i++)
    {
        int len_A = 求表长(&A);
        Elemtype e;
        取第i个元素(&A, i, e);
        if (!LocateELem(&B, e))
            Listlnsert(&A, ++len_A, e);
    }
    return true;
}

結果: ( (7) のデフォルト: 概要:リンク リストと線形リストの定義と操作における事前設定された事前ステートメントに基づいて実行されます) 

この結果の理由は、前述のステートメントで挿入関数を定義したステートメントに関連しています。

Status Listlnsert(LinkList& L, int i, Elemtype e)

より正確に言うと、この問題は、指定した「&A」のタイプが定義内の「LinkList& L」のタイプと一致しないという事実から生じています。

ここでは、LinkList & A とその他の形式について体系的にまとめます。

 &Aは何の略ですか? ?

Sqlist A: 線形テーブルノードタイプの変数A


Sqlist &A: 線形テーブルのノード型の変数 A を表しますが、(単に) 値による参照渡しの方法を表します。


LinkList A: 対象オブジェクトが線形リストのノード型であるポインタ変数 A

LinkList &A: ターゲット オブジェクトが線形リスト ノード タイプであることを示すポインター変数 A です。

これは、
アドレスが参照値による方法を使用して伝達(配信)されることを意味します。 


プログラムを正常に実行したい場合、プログラムを変更する方法は 2 つあります。

1:

<insert> 関数の関数本体を変更します (現時点では、<merge> 関数を変更する必要はありません)。

マージされた関数の「宣言」部分 (関数本体の外側) を次のように変更します。

Status Listlnsert(LinkList L, int i, Elemtype e)

この時点で、マージ関数に必要な前提条件 (最も単純なバージョン) は次のとおりです。

//链表的定义及其基础操作
#include<iostream>
using namespace std;
#include<stdlib.h>//存放exit

#define TRUE        1
#define FALSE       0
#define OK          1
#define ERROR       0
#define INFEASIBLE  -1
#define OVERFLOW   -2   

#define MAXlength 100  //初始大小为100,可按需修改

typedef int Status;         //函数调用状态

struct K
{
    float a;
    int b;
    string c;
    bool operator==(K& t)
    {
        return t.a == a && t.b == b;
        //&& t.c = c;
    }
    bool operator!=(K& t)
    {
        return t.a != a || t.b != b;
        //|| t.c = c;
    }
};
typedef K Elemtype;         //函数调用状态

struct Lnode
    //node:结; 结点;
{
    Elemtype data;
    Lnode* next;
};
typedef Lnode* LinkList;

Status 链表是否为空(LinkList L)
{
    if (L->next)
        return true;
    else
        return false;
}
Status 求表长(LinkList L)
{
    if (链表是否为空(L))
        cerr << "链表为空" << endl;
    LinkList p = L->next;
    //特别注意:因为这里从首元结点开始算起(计算)
    //所以:L->next;
    int i = 0;
    while (p)//不要写成if
    {
        p = p->next;
        i++;
    }
    //cout << "表长为:  " << i << endl;
    return i;
}

Status 取第i个元素(LinkList L, int i, Elemtype e)
{// GetElem“i”
    LinkList p;
    p = L->next;
    int j = 1;
    while (p && i > j)
    {
        p = p->next;
        j++;
    }
    if (i < 0 || i < j || !p)
        return false;
    e = p->data;
    return true;
}

Status LocateELem(LinkList L, Elemtype e)
{
    //在线性表L中查找值为e的数据元素
    //找到,则返回L中值为e的数据元素的地址,查找失败返回NULL
    auto p = L->next; int i = 1;
    while (p && p->data != e)
    {
        i++;
        if (e == p->data)
        {
            cout << "地址为:  " << p << ";" << endl;
            cout << "位置序号为:  " << i << ";" << endl;
        }
        p = p->next;
    }
    if (p == NULL)
        return NULL;
    return true;
}

Status Listlnsert(LinkList L, int i, Elemtype e)
{//插入(把元素e插到第i个位置结点上)
    auto p = L; int j = 0;
    while (p && j < i - 1)
    {
        p = p->next; ++j;
    }
    if (!p || j > i - 1)
        return false;
    auto s = new Lnode;
    s->data = e;
    s->next = p->next;
    p->next = s;
    return true;
}//Listlnsert_L


2:
<merge> 関数の関数本体を変更します: (前のステートメントが変更されず、変更する必要がない場合)

Status Union(Lnode& A, Lnode& B)
{
    for (int i = 1; i <= 求表长(&B); i++)
    {
        int len_A = 求表长(&A);
        Elemtype e;
        LinkList p = &A;
        取第i个元素(&A, i, e);
        if (!LocateELem(&B, e))
            Listlnsert(p, ++len_A, e);
    }
    return true;
}

そしてこの時、興味深い(とても奇妙な)現象(状況)が私に起こりました。

質問:

先頭の「&A」と定義中の「LinkList&L」の種類が一致しないのはなぜですか

ただし、このタイプの新しい変数に「&A」を入力する限り、情報はプログラム内で変数の形式で実行されます。

それは明らかに同じもの (&A) で入力されたものですが、実際にプログラムが実行できるのはなぜ (どのように) できるのでしょうか? ? ?

おすすめ

転載: blog.csdn.net/Zz_zzzzzzz__/article/details/128471897