DSのブログ仕事01-リニアテーブル

0.PTAスコアスクリーンショット

1.1リニアテーブル学習の概要

1.リニアフォームの基本的な考え方

線形リストは同一の特性を有するn個の有限シーケンスである、すべての要素が同じデータタイプに属します。論理単純な直線状の構造、及び操作を容易にする、使用の広い範囲。シーケンステーブルとリンクリスト:ストレージに分けることができます。

2.受注テーブル

データが順次物理的空間の連続したブロックに格納され、ノード間の各メモリセルのアドレスが連続しています。

構造が定義されています

typedef struct node{
    ElemType data[MAX];
    int length;//保存线性表的长度,或者也可以定义int型变量last用于保存线性表中最后一个数据所在的位置下标。
}Node,*NodeList;

基本操作

  • 挿入配列表は:基本的に、最初からモバイルアレイトラバースを動作位置にインサートを見つけ、アレイは、端側比較アレイから移動挿入位置、直接挿入を見つけることながら、移動または開始します。

    • 擬似コード:
    void InserList(NODE & list,int x)
    {
      判断顺序表是否满了,如果满了就return
      for i=list.length to 0  //从末尾开始一个一个把数据右移,直到找到x的插入位置停止。
          if  x>list.data[i-1]  //找到插入位置,退出循环;
              break;
          else
              list.data[i]=list.data[i-1];//数据进行右移;
          end if
      end for
      list.length++;//一定要记得修改顺序表的长度!
      list.data[i]=x;//插入数据;
    }
    • 具体的なコードと結果を実現:
  • 削除順序テーブルは:モバイルデータアレイは、一般的に用いられる方法は、再構成シーケンステーブルである、実質的にあります。

    • 擬似コード:
    void DeleteData(NODE &list, int x)
    {
     定义变量i来遍历顺序表;
     定义变量j并初始化为0;
     定义变量flag用于判断删除是否成功,初始化为0;
    
     for i=0 to list.length
        if(list.data[i]!=x)//不是删除的数据x就存入顺序表中;
            list.data[j++]=list.data[i];
        else 
            flag=1;
        end if
     end for
     list.length=j;
     判断是否删除成功。
    }
    • 具体的なコードとその結果:

3.単独リンクリスト

物理的空間に格納されたデータを分散させ、各ノード間のメモリセルのアドレスは、データを保存するためのチェーン・ポインタを確立することにより、次の論理的な関係ポインタ増加をされており、必ずしも連続的ではありません。

構造が定義されています

typedef struct node
{
    Elemtype data;
    struct node* next;
}Node,*ListNode;

基本操作

  • 第1の補間法は、単一のチェーンを作成する:ノードリストの順序と反対の論理的順序に。
    • 擬似コード:
    void GreatList(ListNode&head,int n)
    {
      head=new Node;//为list申请空间;
      head->next=NULL;
      定义结构体指针ptr来保存每一个结点;
    
      for i=0 to n
          ptr=new Node;//为ptr申请空间;  
          输入数据赋给ptr->data;
          ptr->next保存头结点head的下一个结点;
          head->next保存ptr;
      end for
    }
    • 具体的なコードと結果を実現:
  • 補間尾確立チェーン:ジャンクション配列、および論理的にリンクされたリストと同じ配列。

    • 擬似コード:
    void GreatList(ListNode& head,int n)//尾插法
    {
     定义结构体指针ptr保存每个结点;
     定义结构体指针tail指向链表尾部;
     /*初始化链表*/
     head=new Node;
     head->next=NULL;
     tail=head;//尾指针先指向头结点;
    
     for i=0 to n
        ptr = new Node;
        输入数据赋给ptr->data;
        ptr->next=NULL;
        tail->next=ptr;//先连接;
        tail=ptr;//再移动tail;
      end for
    }
    • 具体的なコードと結果を実現:
  • チェーンが挿入され
    、我々は挿入位置を見つけたときにデータを挿入するとき、我々は、我々は、事前ポインタ挿入位置を保持するために、前駆体の前駆体を定義する必要があり、ポインタ位置の先行および後続ポインタを変更する必要があり、我々は非常に便利修飾しました

    • 擬似コード:
    void InserData(ListNode& list)
    {
     定义结构体指针pre用来保存前驱指针;
     定义结构体指针ptr保存插入的数据;
     初始化ptr;
    
     输入数据赋给ptr;
     while(pre->next && 未满足插入条件)
           pre = pre->next;
     end while
     ptr->next=pre->next;//先保存后继指针;
     pre->next=ptr;//再修改前驱指针;
    }
    • 具体的なコードと結果を実現:
  • 削除リスト
    リンクリストなどとインサートは、また、前任者と後継者の削除位置を変更する必要があり、それはまた、ここでは、前駆体を設定し保存するために正の前駆体を事前に言及。
    • 擬似コード:
    void DeletData(ListNode& list)
    {
     定义结构体指针pre保存删除位置的前驱;
     定义结构体指针ptr保存删除的结点;
     输入需要删除的数据赋给x;
    
     while(pre->next && 未找到删除的数据)
        pre=pre->next;
     end while
     if  pre->next == NULL //说明没有找到删除的数据
        输出删除失败;
     else //找到了删除的数据;
        ptr=pre->next;//ptr保存需要删除的结点;
        pre->next=ptr->next;//连接删除结点的前驱和后继;
     end if       
    }
    • 具体的なコードと結果を実現:
  • 単鎖反転が
    単一リンクリストのノード反転をもたらす、本質的に、第1の補間方法の使用では、必要が後継ポインタ後者バック修飾されていないデータを格納するための元の単一のリンクリスト、上で直接変更することができます。
    • 擬似コード:
void ReverseList(ListNode& L)
{
   定义结构体指针ptr保存当前结点;
   定义结构体指针latter保存原链表中ptr的后继结点;
   latter=L->next;
   L->next=NULL;//重构链表;
   while(latter!=NULL)//遍历原链表;
        ptr=latter;
        latter=latter->next;//保存ptr的后继结点;
        /*头插法*/
        ptr->next=L->next;
        L->next=ptr;
   end while   
}
  • 具体的なコードと結果を実現:

  • リストセグメンテーション:本質は、削除ノードとヘッドの補間への応用です。

    • 擬似コード:
    void SplitList(ListNode& L, ListNode& L1, ListNode& L2)
    {
     定义结构体指针ptr1来遍历链表L1;
     定义结构体指针ptr2来保存属于链表L2的结点;
     /*初始化链表L2*/
     L2-next=NULL;
     L1=L;//L1和L共享结点;
     ptr1=L1->next;
    
     while(ptr1!=NULL && ptr1->next!=NULL)//判断是否遍历结束
          ptr2=ptr1->next;//ptr2保存要插入L2的结点;
          /*L1做删除结点操作*/
          ptr1->next=ptr2->next;
          ptr1=ptr2->next;
          /*ptr2保存的结点用头插法编入L2中*/
          ptr2->next=L2->next;
          L2->next=ptr2;
      end while
    }
    • 具体的な動作や結果を実現:

4.順序付きリスト

これは、特殊リニアテーブルで、昇順または降順内のすべての要素を命じました。
基本操作

  • 順序付きリストを作成:ユーザーが入力した番号を保存するために、構造体のポインタptrをした後、プラグイン可能な位置を見つけるために、リストをトラバース。
    • 擬似コード:
    void SortList(ListNode& list,int n)
    {
      定义结构体指针ptr保存新结点;
      定义结构体指针listPtr遍历链表list;
      /*初始化链表list*/
      list = new Node;
      list->next=NULL;
    
       for i=0 to n
            ptr=new Node;
            输入数据赋给ptr->data;
            listPtr=list;//开始遍历链表list;
            while(listPtr->next && 未找到插入位置)
                 listPtr = listPtr->next;
            end while
        ptr->next=list->next;//开始进行插入;
        listPtr->next=ptr;
        end for
    }
    • 具体的なコードと結果を実現:
  • 単鎖の順序付けられた挿入:上記参照は、単一のリスト内に挿入されます
  • 削除間隔データ-デリートデータへの単一リンクリスト順序付き
    6-3 JMU-DS-リストセクションを削除します
    • 擬似コード:
    void DelList(ListNode& L, int min, int max)
    {
    定义结构体指针pre,用pre->next来遍历链表;
    pre=L;
    while(pre->next!=NULL)
        if(pre->next->data <= max && pre->next->data >= min)
              p = pre->next;
              pre->next = p->next;//改变pre的后继结点;   
              delete p;
        else if(pre->next->data>max)//因为是有序链表,所以如果数据大于删除区间的最大值就已经完成了删除。
              break;
        else //pre->next->data < min的情景。
              pre=pre->next;//要继续往下遍历;
        end if
     end while  
    }
    • 具体的なコードと結果を実現:
  • 合わせたソート済リンクリストは各L2本質的にノードがL1に対応する位置に挿入され、L1はデータが残っ注文その結果挿入されています。

    • 擬似コード:
void MergeList(ListNode& L1, ListNode L2)//合并链表,使结果呈递增排序
{
   定义结构体指针ptr1和ptr2分别用来遍历L1和L2;
   定义结构体指针temp;
   ptr1=L1;
   ptr2=L2->next;
   
   while(ptr2!=NULL)
        if (ptr1->next->data > ptr2->data)//找到L1中可插入的位置
              temp = ptr2;//用于保存L2中需要插入的结点;
              ptr2 = ptr2->next;//继续遍历L2;
              /*把temp插入L1中*/
              temp->next=ptr1->next;
              ptr1->next=temp;
        else if (ptr1->next->data==ptr->data)//用于删除重复的数据
               ptr2=ptr2->next;//跳过重复数据;
        end if
        ptr1=ptr1->next;
        if(ptr1->next==NULL && ptr2!=NULL)//链表L1遍历完毕L2没有遍历完
               ptr1->next=ptr2;//直接L2中剩余的结点连接到当前ptr1指向结点的后面   
               break;
        end if
}
  • 具体的なコードと結果を実現:

二重リンクリスト


構造が定義されています

struct Node
{
    ElemType data;
    struct Node *prior;//指向前驱结点;
    struct Node *next;//指向后继结点;
};

機能

  • いずれかのノードから開始するノードの先行および後続ノードを見つけることができます。
  • かかわらず、あなたが他のノードにアクセスできるノードから開始点の、ノードは、ノードの背後にある単一のリストにのみアクセスすることができます。
  • 実行挿入および欠失は、ポインタ前駆体を定義する必要はありません場合は、リストへの前駆体の二重リンクリストのポインタが挿入され、削除することができます。

6.循環リスト

  • 一本鎖ループ:ノードのタイプと同じ非環状単鎖は、ヘッダノードに向けエンドノードドメインの単鎖の円形テーブルポインタは、リスト全体が環を形成することを除いて。したがって、リスト内のいずれかのノードが任意の時点で開始見つけることができます。
  • 円形の二重連結リスト:ことを除いて、ノードタイプと非円形の二重連結リスト、ヘッダ前駆ポインタ点に表後継ポインタテイルノードにおける円形の二重リンクリスト、エンドノードへの後続のポインタに前駆ヘッダポインタポイント。

直線状の理解と学習経験の1.2ペア

ポイント線形多くの知識のリスト、および非常に柔軟。少しぎくしゃくを学ぶために始めて、それは使用しません。すでにリニアテーブルを学ぶの2週間後、私たちは大まかなアウトラインを持っています。被写体がまだあるときには、通常は間違って行くためのプログラムを引き起こして、詳細の一部を逃しません。リストを構築するとき、例えば、私は多くの場合、無限ループ出力にクラッシュするプログラムを引き起こし、NULLに私の尾の接合点を取得することを忘れ。私は理解している、または多くの細部が失われることがあるでしょう場合でも、私はそれは私がいない熟練十分だ、または十分でないコードブラシのコードの隣に、ブラシ、そしてより多くの経験の概要を総括すべきだと思います問題と解決策。始まったばかりの直線形について学ぶ、学校感のスタックの次の章と少し接触が今だけ(おそらく毛皮は実際にはありません)、我々は多くのことを学ぶことができる多くのことを必要とする将来が多い直線状の表面を傷しているようですたくさんの。

2.PTAラボの割り当て

逆数の2.1メートルの数を一覧表示します

2.1.1コードのスクリーンショット

方法の一つ:

方法2:

2.1.2タイトルPTAは、命令のリストを提出します


この質問は、私は2つの方法で、異なる試験方法発生した別のエラーの上にしようとしました。
この方法の一つ:

Q:运行时错误
A:起初不知道运行时错误是什么意思,以为是网页有问题于是就多试了几下。后来发现是因为我没有让链表的尾结点指向NULL,因为在自己写代码的时候没有实现销毁链表这一函数,所以我的程序能运行成功并输出正确的答案。但是在过测试的时候,由于需要执行销毁链表,找不到尾结点,程序就无法结束导致运行错误;

方法2:

Q:部分正确
A:刚开移动q时,用的是for循环,循环变量i是从1开始,当q指向第m个数退出循环时,i等于m+1,不等于m,而我下面用i==m时来判定位置合法,i!=m时位置无效,显然无论我输入的m是否合法,其结果都是无效;
Q:部分错误
A:我没有发现上面那个错误,修改了判断位置是否有效的条件,导致原本位置应该无效的变成有效的,最后对空指针进行取值导致位置无效的测试点段错误。
Q:部分错误
A:判断位置是否有效的条件少了一个等号;
Q:编译错误
A:复制代码时没有把最后的大括号复制进来;

2.2単変量多項式の乗算と加算演算

2.2.1コードのスクリーンショット










2.2.2タイトルPTAは、命令のリストを提出します

Q:部分错误
A:没有考虑到同项需要再进行相加减;
Q:部分错误
A:同项相消时为0,输出时,要舍去不输出,我全部都输出了。
Q:部分错误
A:当结果为零多项式时,我没有输出,因为为0的全部都跳过输出了。于是我设置了变量flag,只要有输出就改变flag的值,如果flag的值没有改变,则表结果为零多项式,需要输出0 0

2.3操作シーケンステーブル

2.3.1コードのスクリーンショット



2.3.2タイトルPTAは、命令のリストを提出します

Q:编译错误
A:我编程时用的是C++的语法,而题目规定用c语言
Q:答案错误
A:题目理解错误,我以为读顺序表的插入只能插入数组的最后一位数后面。
Q:答案错误
A:删除数据的函数中,判断位置是否合法的条件错误,非法的应该是小于0或者大于last,我写的是大于MaxSize或者小于last。
Q:部分错误
A:不小心将自己为了方便在vs中调试而设置的输出代码一起复制进来。

3.読み取ったコード

3.1は、2つの数値を追加します

  • タイトル
  • コード
class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode sum = l1;
        while(l1.next!=null&&l2.next!=null){
            l1.val += l2.val;
            l1 = l1.next;
            l2 = l2.next;
        }
        l1.val += l2.val;
        if(l1.next==null&&l2.next!=null){
            l1.next = l2.next;
        }
        l1 = sum;
        while(l1.next!=null){
            if(l1.val>9){
                l1.val -= 10;
                l1.next.val++;
            }
            l1 = l1.next;
        }
        if(l1.val>9){
            l1.val -= 10;
            l1.next = new ListNode(1);
        }
        return sum;
    }
}

作者:lhpyxjn75x
链接:https://leetcode-cn.com/problems/add-two-numbers/solution/2liang-shu-xiang-jia-jian-dan-bao-li-2ms-by-lhpyxj/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

3.1.1デザインのアイデア

二つのリストを追加する最初のスタートから、結果が全てL1に直接保存され、その後、ここで注意すべきキャリー問題を検討し始めているときのキャリー、L1を追加することにより、ニーズのリストリストL1とL2における最後の番号の数私たちは、新しい番号を保存するための新しい領域を開発する必要があります。

提供されるmビットは、L1、L2のnビット保存の保存します。

  • Oの時間複雑度(M + N)の最初のループは、MAX(M、N)倍、Oの時間複雑度(M + Nを介して第2のwhileループ分(M、N)回横断しながら)。
  • 宇宙複雑性O(1):一緒に加えたときに宇宙の複雑さはO(ですので、結果の各桁の合計は、L1、保存するためのスペースを開くために和キャリーニーズの最後の桁に保存されているので1)。

3.1.2擬似コード

定义一个结构体指针sum来保存l1的头指针;
while(l1->next!=NULL && l2->next!=NULL)//把两个数每一位都先进行相加;
     l1->val += l2->val;
     l1 = l1->next;
     l2 = l2->next;
end while
l1->val += l2.val;//循环遍历到l1和l2中有一个后继结点为NULL时停止,退出循环时当前的位上的数还未相加
if(l1->next == NULL && l2->next!=NULL)//l2的位数比l1多直接把l2后面的数连接到l1后面
     l1->next=l2->next;//直接把l2后面的数连接到l1后面  
end if
l1=sum;//指向头指针;
while (l1->next!=NULL)//开始处理进位问题;
     if(l1->val>9)
         l1->val-=10;
         l1->next->val++; 
     end if
     l1=l1->next;
end while
if(l1->val>9)//遍历到最后一位数时,如果需要进位,必须要开辟新的空间
     l1->val-=10;
     l1->next=new ListNode(1);
end if
return sum;

3.1.3業績


問題解決のトピックでの利点と問題点の分析3.1.4

長所:この質問は、私たちのいつもの思考に合わせて最小数2の位置から計算され、2つの番号を見つけるために私たちを必要とし、質問が逆順にデータ入力とても親切で、実質的に私たちの書き込みを減らしますコードの負担は、我々はそれだけで小学校コードの完成に合わせて知識を結合する必要があります。
難易度:我々はあなたがいない元の文言に従い、思考のビットを必要とするとき、ヘッドノード、書き込みテスト・コードを含むリストに使用されているためにリストを作成したり、ループの外かどうかを判断するためにヘッドノードを持っています。そして、あなたは、マージ、すべての場合には、これら二つの場所に特別な注意を払って、二つの場所は、コード内で循環に合併し、まだ実行のために選抜されるように見えるコードの作者から見ることができます循環には、null値とNULLポインタ誤操作にL1ポインタポイントを行います。

3.2二十から二スイッチングノードリンクリスト

  • トピック:
  • コード:
class Solution {
    public ListNode swapPairs(ListNode head) {
        if(head == null || head.next == null){
            return head;
        }
        ListNode next = head.next;
        head.next = swapPairs(next.next);
        next.next = head;
        return next;
    }
}

作者:guanpengchn
链接:https://leetcode-cn.com/problems/swap-nodes-in-pairs/solution/hua-jie-suan-fa-24-liang-liang-jiao-huan-lian-biao/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

3.2.1デザインのアイデア

全体として第一鎖に2つのノードを先頭から2つのノードのそれぞれは、変形後に、本来最初のノードは、常に次の整数第2のノードに接続されている(交換機全体を交換します)最初のノードで、全体として、我々は再帰アルゴリズム、第1のプログレッシブまたは番号の最後の2つの数値を設け、交換後に返さ交換データへ後者開始し、一方に完了する。データ後の裏面全体における現在の接続の最初のノードは、最初のノードの前に第二に、次いで全体現在のノードの移動を交換されました。

リストには、nノードが提供されます。

  • Oの時間複雑度(N)回再帰N / 2の数は、各時間を操作する再帰必要数は4回であった、時間複雑度は、T(N)= 4 *(N / 2)+ 1 = O(Nであります);
  • 空間複雑度はO(n):回数再帰N / 2は、各再帰スペースを占有する占有空間の複雑さは、T(N)= N / 2 = O(N)です。

3.2.2擬似コード

if head == NULL || head->next==NULL //结束标志,不管head为NULL还是为最后一个节点,都不影响,一位递归回去的指针总是当前整体中的第一个结点;
      return head;
end if
ListNode next=head->next;//next指向当前整体中的第二个结点;
head->next = swapPairs(next->next);//当前整体中的第一个结点先连接上已经交换过结点后的下一个整体中的第一个结点(就是原来该整体的第二个结点)
next->next=head;//将该整体的第一个结点移动到第二个结点后面;
return next;//原本的第二个结点现在变成这个整体中的第一个结点,返回到上一级函数。 

3.2.3業績

問題解決のトピックでの利点と問題点の分析3.2.4

長所:この質問非再帰的アルゴリズムは問題ではありませんが、例えば、格納されたデータを交換するための新しいリストを開く、アイデアは比較的単純な、再帰的なアルゴリズムの時間の複雑さと同じですが、スペースの複雑さが0(1)である再帰よりこのアルゴリズムでも、再帰的なアルゴリズムを考えることはできません、小さくなるように、非再帰的なアルゴリズムを使用することは、実装することは比較的容易でもあり、
難易度:私は(魔法の無知だったとき、私はこれを、コードを見たときと、この問題の難しさは、再帰的なアルゴリズムを使用することだと思います)。全体的な思考再帰アルゴリズムはちょうど私が夜の時間を費やし、このコードを理解し、非常に巧妙かつ柔軟です。再帰的アルゴリズムはまだ文盲本当に見ものを見る(ダークサークルが警告!)、描画する必要があります。

おすすめ

転載: www.cnblogs.com/xianerbian/p/12361091.html