2008年10月8日水曜日

C#2005/2008 マネージ 線形リスト クラス

C#2005/2008 マネージ 線形リスト クラス

マネージで線形リストが扱えるクラス(List.cs)を作りました。マネージでは new の代わりに gcnew を使用するため、関数のスコープが外れたときでも gcnew で確保した内容が消えないようにしなければなりません。
以下は、線形リストで追加と削除ができるクラスです。先入れ先出のみの対応で、リストの真ん中に対して挿入・削除は対応しておりません。

**** Form1.cs ****

private void button3_Click(object sender, EventArgs e)
{
List list = new List();

ListType input = new ListType(256);
input.buff[0] = 1;
input.buff[1] = 2;
list.addlist(input); // リストへ追加 1
input.Clear();
input.buff[0] = 3;
input.buff[1] = 4;
list.addlist(input); // リストへ追加 2

ListType getd = new ListType(256);
getd = list.deletelist(); // リスト取得後削除 1
getd = list.deletelist(); // リスト取得後削除 2
getd = list.deletelist(); // リスト取得後削除 (nullを返す)
}

**** List.cs ****

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TestTest
{
/// <summary>
/// リストタイプ クラス
/// </summary>
class ListType
{
///------------------------------------------------
/// テーブル宣言
///------------------------------------------------
public Int32 no; // リスト番号
public uint[] buff; // 格納データ
public Int32 len; // 文字数
public ListType next; // 次の要素へのポインタ
/// <summary>
/// コンストラクタ
/// </summary>
/// <param name="length"></param>
public ListType( Int32 length )
{
buff = new uint[length];
len = length;
next = null;
Clear(); // バッファクリア
}
public void Clear()
{
for (Int32 ii = 0; ii < len; ii++)
{
buff[ii] = 0;
}
}
}
///--------------------------------------------------------
/// <summary>
/// リスト クラス
/// </summary>
class List
{
///------------------------------------------------
/// テーブル宣言
///------------------------------------------------
public ListType head;
public ListType p;
public ListType q;
public ListType newcell;
public ListType output;
public Int32 No;
/// <summary>
/// コンストラクタ
/// </summary>
public List()
{
head = new ListType(1); // リストヘッダー宣言
No = 0;
}
/// <summary>
/// リスト追加
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public bool addlist( ListType input )
{
p = head.next; // 先頭要素の次のアドレス
q = head; // 先頭のアドレス
while( p != null )
{
q = p; // 追加位置の直前の要素nextを後で設定するため
p = p.next; // 次の要素へ進む
}

newcell = new ListType(input.len);
if( newcell == null )
{
return false; // メモリ不足
}

input.no = ++No;
for (Int32 ii = 0; ii < (input.len); ii++)
{
newcell.buff[ii] = input.buff[ii]; // 新しい要素を設定
}
newcell.len = input.len; // 文字数設定
newcell.next = p; // 新しい要素の次の要素へのアドレス設定
q.next = newcell; // 新しい要素の直前の要素のnextに新しい要素アドレス設定
return true;
}
/// <summary>
/// リスト削除
/// </summary>
/// <returns></returns>
public ListType deletelist()
{
p = head.next; // 先頭要素の次の要素アドレス
q = head; // 先頭要素アドレス

if( p == null )
{
return null;
}
else
{
output = new ListType(p.len); // 取出領域確保
output.no = --No;
for(Int32 ii=0; ii<(p.len); ii++)
{
output.buff[ii] = p.buff[ii];
}
output.len = p.len;
q.next = p.next; // 削除する要素の直前の要素のnextポインタを再設定
p = null;
}
return output;
}
}
}