List Object Class

Val=9  Val=8  Val=7  Val=6  Val=5  Val=4  Val=3  Val=2  Val=1
Val=1  Val=2  Val=3  Val=4  Val=5  Val=6  Val=7  Val=8  Val=9

C# で List Object Class を作成します。

前田稔(Maeda Minoru)の超初心者のプログラム入門

プログラムの説明

  1. フォルダーに次のファイルを格納して下さい。
    /*************************************/
    /*★ List Object Class     前田 稔 ★*/
    /*************************************/
    using System;
    
    class console
    {
        public static void Main()
        {   List    pt = new List();
            List    wp;
    
            for(int i=1; i<10; i++) pt.Push(i);
            for(wp=pt.End; wp!=null; wp=pt.Back(wp))
                Console.Write("Val={0}  ",wp.val);
            Console.WriteLine("");
            for (wp=pt.Begin; wp!=null; wp=pt.Next(wp))
                Console.Write("Val={0}  ", wp.val);
            System.Console.ReadLine();
        }
    }
    
    class List
    {
        public  int     val;    //セルの値
        public  List    ptr;    //セルのリンク
        public  List    top;    //List の先頭(最後に Push されたセル)
    
        //Constructor
        public List()
        {   ptr = null;
            top = null;
        }
        //最初に登録されたセル
        public List Begin
        {
            get
            {
                List wk;
                for(wk=top; wk.ptr!=null; wk=wk.ptr);
                return wk;
            }
        }
        //最後に登録されたセル
        public List End
        {
            get
            {
                return top;
            }
        }
        //前のセル
        public List Back(List pt)
        {
            if (pt==null)   return null;
            return pt.ptr;
        }
        //次のセル
        public List Next(List pt)
        {
            if (pt==null)   return null;
            return find_pt(top,pt);
        }
        //List の先頭に追加
        public List Push(int v)
        {   List    wk;
    
            wk = new List();
            wk.val = v;
            wk.ptr = top;
            top = wk;
            return wk;
        }
        //List の先頭(最後に Push された値)から印字
        public void BPrint()
        {   List    wk;
    
            for(wk=top; wk!=null; wk= wk.ptr)
                Console.Write("val= {0}  ",wk.val);
        }
        //List の後部(登録された順)から印字
        public void Print()
        {
            if (top!=null)   pnt(top);
        }
    
        //★private method
        //pt が定義されているセルを探す
        List find_pt(List top, List pt)
        {
            if (top==null)  return null;
            if (top.ptr == pt) return top;
            return find_pt(top.ptr, pt);
        }
    
        void pnt(List pt)
        {
            if (pt==null)   return;
            pnt(pt.ptr);
            Console.Write("val= {0}  ",pt.val);
            return;
        }
    }
    
  2. List 構造とはセルをポインタで連鎖したデータ構造です。
    セルは次のセルに連鎖するためのポインタとデータ領域で構成されます。
    セルをポインタで連鎖した List 構造の概念図です。
    次のセル データ1
        ↓
    次のセル データ2
        ↓
        ・・・
    次のセル データn-1
        ↓
    null データn
  3. List 構造を操作するメソッドを定義して、基本的な List Object Class を作成してみましょう。
    List のプログラムは再起処理が多く、初心者にはわかり難いかも知れません。
    私は List 処理のプログラムも組め無いようでは、プログラマとして一人前とは認められないと思っています。 (^_^;)
  4. Main 関数の説明です。
    最初に new List(); で List Object Class を生成します。
    1~9の値を pt.Push 関数で List に登録します。
    pt.Push で連鎖されたセルは、最後に登録されたセル(top)を頭にして、一方向に連鎖されています。
        public static void Main()
        {   List    pt = new List();
            List    wp;
    
            for(int i=1; i<10; i++) pt.Push(i);
        
  5. データの登録が終わると、最後に登録したデータから連鎖をたどって印字します。
    pt.End は最後に登録されたセル(top)を取得するアクセッサです。
    アクセッサの説明は Set,Get アクセッサ を参照して下さい。
    pt.Back は登録した順序と逆方向に連鎖をたどる関数で、wp が null になるまで繰り返します。
    wp が指すセルのデータ(val)を Console.Write で印字します。
            for(wp=pt.End; wp!=null; wp=pt.Back(wp))
                Console.Write("Val={0}  ",wp.val);
        
  6. 次にデータを登録した順に印字します。
    リスト構造は連鎖されている順にたどるのは簡単ですが、連鎖を逆にたどるのは一苦労します。
    pt.Begin は最初に登録されたセルを取得するアクセッサです。
    pt.Next で連鎖を逆にたどりながら wp が null になるまで繰り返します。
            Console.WriteLine("");
            for (wp=pt.Begin; wp!=null; wp=pt.Next(wp))
                Console.Write("Val={0}  ", wp.val);
            System.Console.ReadLine();
        }
        
  7. pt.End は最後に登録されたセル(top)を取得するアクセッサです。
    End は top の値なので簡単です。
        //最後に登録されたセル
        public List End
        {
            get
            {
                return top;
            }
        }
        
  8. pt.Begin は最初に登録されたセルを取得するアクセッサです。
    実は記録されているのは最後に登録されたセル(top) とその連鎖だけです。
    そこで top から連鎖をたどり、最初に登録されたセル(ptr==null のセル)を探し出します。
        //最初に登録されたセル
        public List Begin
        {
            get
            {
                List wk;
                for(wk=top; wk.ptr!=null; wk=wk.ptr);
                return wk;
            }
        }
        
  9. pt.Back は現在のセルから「前のセル」を取得する関数です。
    top から連鎖されている「前のセル」はすぐ取得できます。
        //前のセル
        public List Back(List pt)
        {
            if (pt==null)   return null;
            return pt.ptr;
        }
        
  10. pt.Next は現在のセルから「次のセル」を取得する関数です。
    「次のセル」を取得するには top から連鎖をたどって pt をポイントしているセルを探し出しさなければなりません。
    それを行う関数が find_pt(top,pt) です。
        //次のセル
        public List Next(List pt)
        {
            if (pt==null)   return null;
            return find_pt(top,pt);
        }
        
  11. top から連鎖をたどり pt にポイントしているセルを探し出します。
    find_pt から find_pt を呼び出していることに注目して下さい。
        //pt が定義されているセルを探す
        List find_pt(List top, List pt)
        {
            if (top==null)  return null;
            if (top.ptr == pt) return top;
            return find_pt(top.ptr, pt);
        }
        
  12. List の先頭にデータを追加する Push 関数です。
    new で新しいセルを割り当てて top から連鎖します。
        //List の先頭に追加
        public List Push(int v)
        {   List    wk;
    
            wk = new List();
            wk.val = v;
            wk.ptr = top;
            top = wk;
            return wk;
        }
        
  13. List の先頭(最後に Push された値)から印字する関数と、逆順に印字する関数です。
    説明は List を正順(逆順)で印字 を参照して下さい。
        //List の先頭(最後に Push された値)から印字
        public void BPrint()
        {   List    wk;
    
            for(wk=top; wk!=null; wk= wk.ptr)
                Console.Write("val= {0}  ",wk.val);
        }
        //List の後部(登録された順)から印字
        public void Print()
        {
            if (top!=null)   pnt(top);
        }
        

【演習】

  1. List の最後尾にデータを追加する関数を作成して下さい。
  2. 登録されたデータを検索する関数を作成して下さい。
  3. 検索で見つけ出したセルを削除する関数を作成して下さい。
  4. 指定したセルの次(前)に新しいセルを挿入する関数を作成して下さい。
  5. 連鎖を入れ替えて登録したデータをソートする関数を作成して下さい。
  6. ちょっと難しいかも知れませんが、これらの関数がスマートに作成出来たら一人前のプログラマとして認めましょう。 (^_^;)

超初心者のプログラム入門(C# Frame Work)