List のセルを削除する

val= 9  val= 8  val= 7  val= 6  val= 5  val= 4  val= 3  val= 2  val= 1
------------
val= 9  val= 8  val= 7  val= 6  val= 4  val= 3  val= 2  val= 1
------------
val= 9  val= 8  val= 7  val= 6  val= 4  val= 3  val= 2
------------
val= 8  val= 7  val= 6  val= 4  val= 3  val= 2
------------

List に登録されているセルを削除します。

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

プログラムの説明

  1. 次のファイルを格納して下さい。
    /***********************************************/
    /*★ List に登録されたセルを削除     前田 稔 ★*/
    /***********************************************/
    using System;
    
    class console
    {
        public static void Main()
        {   List    pt = new List();
            List    wp;
    
            for(int i=1; i<10; i++) pt.Push(i);
            pt.BPrint();
            Console.WriteLine("\n------------");
    
            wp= pt.Search(5);
            if (pt.Del(wp)==false)  Console.WriteLine("Delete Error 5");
            pt.BPrint();
            Console.WriteLine("\n------------");
    
            wp = pt.Search(1);
            if (pt.Del(wp)==false)  Console.WriteLine("Delete Error 1");
            pt.BPrint();
            Console.WriteLine("\n------------");
    
            wp = pt.Search(9);
            if (pt.Del(wp)==false)  Console.WriteLine("Delete Error 9");
            pt.BPrint();
            Console.WriteLine("\n------------");
        }
    }
    
    class List
    {
        public  int     val;    //セルの値
        public  List    ptr;    //セルのリンク
        public  List    top;    //List の先頭(最後に Push されたセル)
    
        //Constructor
        public List()
        {   ptr = null;
            top = null;
        }
        //List の先頭に追加
        public List Push(int v)
        {   List    wk;
    
            wk = new List();
            wk.val = v;
            wk.ptr = top;
            top = wk;
            return wk;
        }
        //Top(登録順とは逆)から印字
        public void BPrint()
        {   List    wk;
    
            for(wk=top; wk!=null; wk= wk.ptr)
                Console.Write("val= {0}  ",wk.val);
        }
        //List を検索
        public List Search(int v)
        {   List    wk;
    
            for(wk=top; wk!=null && wk.val!=v; wk= wk.ptr);
            return wk;
        }
        //Sell を削除
        public bool Del(List pt)
        {   List    wk;
    
            if (top==pt)
            {   top = top.ptr;
                return true;
            }
            wk = find_pt(top, pt);
            if (wk==null)   return false;
            wk.ptr= wk.ptr.ptr;
            return true;
        }
    
        //★ private method
        //pt が定義されている(pt にリンクしている)セルを探す
        List find_pt(List top, List pt)
        {
            if (top==null)  return null;
            if (top==pt)
            {   Console.WriteLine("セルは top からリンクされています");
                return null;
            }
            if (top.ptr == pt) return top;
            return find_pt(top.ptr, pt);
        }
    }
    
  2. 連鎖されている List から特定のセルを削除するのは、簡単なように見えて、結構難しいのです。
    下記の状態から「データ2」を削除することを考えてみます。
    セルをポインタで連鎖した List 構造の概念図です。
    次のセル データ1
        ↓
    次のセル データ2
        ↓
    次のセル データ3
        ↓
        ・・・
    null データn
    削除の手順です。
    1. 「データ2」を削除することを考えます。
    2. 「データ2」から連鎖している「データ3」へのポインタを保存します。
    3. 「データ2」に連鎖している「データ1」のセルを探します。
    4. 「データ1」の ptr(連鎖)に、保存したポインタを格納します。
    5. 「データ2」のセルを解放します。
      C# では自動的に開放してくれるので、この処理は不要かも知れません。
  3. Search() 関数で 5 が格納されているセルを見つけて Del(wp) 関数で削除します。
    (セルには 1,2,3,4,5, ... ,10 が格納されている)
    削除した List を BPrint() 関数で表示します。
        wp= pt.Search(5);
        if (pt.Del(wp)==false)  Console.WriteLine("Delete Error 5");
        pt.BPrint();
        
  4. Search(int v) 関数は v が格納されているセルを検索する関数です。
    見つからないときは null がリターンされます。
        public List Search(int v)
        {   List    wk;
    
            for(wk=top; wk!=null && wk.val!=v; wk= wk.ptr);
            return wk;
        }
        
  5. Del(List pt) 関数は pt の指すセルを削除する関数です。
    find_pt(top, pt) で、top から pt に連鎖するセルを検索します。
    見つからないときは false をリターンします。
    見つかったときは wk.ptr= wk.ptr.ptr; で一個のセルを外します。
        //Sell を削除
        public bool Del(List pt)
        {   List    wk;
    
            if (top==pt)
            {   top = top.ptr;
                return true;
            }
            wk = find_pt(top, pt);
            if (wk==null)   return false;
            wk.ptr= wk.ptr.ptr;
            return true;
        }
        
  6. find_pt() 関数は pt にリンクしているセルを探す関数です。
    見つからないときは null をリターンします。
        //pt が定義されている(pt にリンクしている)セルを探す
        List find_pt(List top, List pt)
        {
            if (top==null)  return null;
            if (top==pt)
            {   Console.WriteLine("セルは top からリンクされています");
                return null;
            }
            if (top.ptr == pt) return top;
            return find_pt(top.ptr, pt);
        }
        

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