class MyList<T> where T : IComparable<T>
{
public T t;
public static int comp(MyList<T> obj1, MyList<T> obj2)
{
return obj1.t.CompareTo(obj2.t);
}
}
Обобщенная реализация(Generic)
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication3
{
class Node<T> // реализация структуры элемента списка
{
public T Data;// хранимое в списке целое число
public Node<T> Next;// "указатель" на следующий элемент списка
public Node<T> Previous;// "указатель" на предыдущий элемент списка
}
/*==============================================================================================*/
class DoubleLinkedList<T>// реализация класса двусвязного списка
{
private int count;//количество элементов в списке
private readonly Node<T> RightBound;//правая граница списка
private readonly Node<T> LeftBound;//левая граница списка
/*=============================================================================================*/
public DoubleLinkedList()//конструктор сласса DoubleLinkedList
{
count = 0;
LeftBound = new Node<T>();//левая граница списка
RightBound = new Node<T>();// правая граница списка
LeftBound.Next = RightBound;
RightBound.Previous = LeftBound;
}
/*==============================================================================================*/
public void AddAfter(Node<T> node, T item)// добавляет узел в список после определенного узла
{
Node<T> newNode = new Node<T>();
newNode.Previous = node;
newNode.Next = node.Next;
newNode.Data = item;
node.Next.Previous = newNode;
node.Next = newNode;
count++;
}
/*=============================================================================================*/
public void Add(T item)// добавляет узел в список
{
AddAfter(LeftBound, item);
}
/*==============================================================================================*/
public bool IsEmpty()
{
if (count == 0)
return true;
else
return false;
}
/*==============================================================================================*/
public int Count()// возвращает количество элементов в списке
{
return count;
}
/*==============================================================================================*/
public int GetNumberOfElements(T num)// возвращает количество элементов в списке с заданным значением
{
int k = 0;
Node<T> CurrentNode = new Node<T>();
CurrentNode = LeftBound.Next;
for (int index = 1; index <= count; index++)
{
if (CurrentNode.Data.Equals(num))
k++;
CurrentNode = CurrentNode.Next;
}
return k;
}
/*==============================================================================================*/
public int[] GetEnumerators(T value)// возвращает все номера элементов списка со значением value, если они есть
{
int[] numerators = new int[GetNumberOfElements(value)];
int k = 0;
Node<T> CurrentNode = new Node<T>();
if (this.GetNumberOfElements(value) == 0)
{
Console.WriteLine("There are no elements with such value in the list");
return numerators;
}
CurrentNode = LeftBound.Next;
for (int index = 1; index <= count; index++)
{
if (CurrentNode.Data.Equals(value))
{
numerators[k] = index;
k++;
}
CurrentNode = CurrentNode.Next;
}
return numerators;
}
/*==============================================================================================*/
public void ListPrinting()//выводит список на экран
{
Node<T> CurrentNode = new Node<T>();
CurrentNode = RightBound.Previous;
for (int i = count; i >= 1; i--)
{
Console.Write(CurrentNode.Data + " ");
CurrentNode = CurrentNode.Previous;
}
Console.WriteLine("\n");
}
/*==============================================================================================*/
public void EraseOne(T value)//Удаляет еллемент списка со значением value
{
Node<T> CurrentNode = new Node<T>();
CurrentNode = LeftBound.Next;
if (count >= 1)
{
for (int i = 1; i <= count; i++)
{
if (CurrentNode.Data.Equals(value))
{
CurrentNode.Previous.Next = CurrentNode.Next;
CurrentNode.Next.Previous = CurrentNode.Previous;
count--;
return;
}
CurrentNode = CurrentNode.Next;
}
Console.WriteLine("Trere are no elements with the value " + value);
}
else
Console.WriteLine("The operation can't be done: list is empty ");
}
/*==============================================================================================*/
public void EraseAllOf(T value)//удаляет все элементы списка с заданным значением
{
if (GetNumberOfElements(value) == 0)
Console.WriteLine("\nThere aren't such elements in the list");
while (GetNumberOfElements(value) > 0)
EraseOne(value);
}
/*==============================================================================================*/
public void CopyTo(DoubleLinkedList<T> List2)//Копируем содержимое исходного списка в List2
{
Node<T> CurrentNode = new Node<T>();
CurrentNode = RightBound.Previous;
for (int i = count; i >= 1; i--)
{
List2.Add(CurrentNode.Data);
CurrentNode = CurrentNode.Previous;
}
}
}
Цитата:
как тогда определить операцию сравнения например... через интерфеысы? вот в этом что-то и проблема. Подскажите как это все делается.. вот все что написал
сделай требование, чтобы T реализовывало стандартный интерфейс IComparable(T): http://msdn.microsoft.com/ru-ru/library/4d7sx9hd(VS.90).aspx
сделать это можно так:
Код:
метод comp - пример использования интерфейса.
пример собственного класса реализующего IComparable(T):
Код:
class MyObj : IComparable<MyObj>
{
public string str;
public int CompareTo(MyObj other)
{
return str.CompareTo(other.str);
}
}
{
public string str;
public int CompareTo(MyObj other)
{
return str.CompareTo(other.str);
}
}
ну и всё вместе:
Код:
static void Main(string[] args)
{
var l1 = new MyList<int> { t = 1 };
var l2 = new MyList<int> { t = 3 };
if (MyList<int>.comp(l1, l2) > 0)
Console.WriteLine("l1 > l2");
else
Console.WriteLine("l1 <= l2");
var s1 = new MyList<MyObj>() { t = new MyObj { str = "str" } };
var s2 = new MyList<MyObj>() { t = new MyObj { str = "str" } };
if(MyList<MyObj>.comp(s1,s2) == 0)
Console.WriteLine("s1 = s2");
else
Console.WriteLine("s1 <> s2");
Console.ReadLine();
}
{
var l1 = new MyList<int> { t = 1 };
var l2 = new MyList<int> { t = 3 };
if (MyList<int>.comp(l1, l2) > 0)
Console.WriteLine("l1 > l2");
else
Console.WriteLine("l1 <= l2");
var s1 = new MyList<MyObj>() { t = new MyObj { str = "str" } };
var s2 = new MyList<MyObj>() { t = new MyObj { str = "str" } };
if(MyList<MyObj>.comp(s1,s2) == 0)
Console.WriteLine("s1 = s2");
else
Console.WriteLine("s1 <> s2");
Console.ReadLine();
}
дальше думаю сам разберёшься, как это у себя использовать.
П.С. на будущее - используй теги CODE для оформления своего кода, иначе в твой код не будут смотреть.
Спасибо, все получилось! А насчет тегов кода учту!:)
Цитата: Ringo1
а если мы заранее не знаем что за тип данных (ну например если есть экземпляр созданного нами классса)... как тогда определить операцию сравнения например... через интерфеысы? вот в этом что-то и проблема. Подскажите как это все делается.. вот все что написал
Для операций сравнения типов все очень просто.
В NET есть механизм автоидентификации механизмов compare и equate.
Код:
protected static IComparer<T> TComarer = Comparer<T>.Default;
protected static IEqualityComparer<T> TEComarer = EqualityComparer<T>.Default;
protected static IEqualityComparer<T> TEComarer = EqualityComparer<T>.Default;
Среда выполнения Runtime определит подходящий механизм сравнения.
Поместить его в статическую переменную - и затем использовать внутри класса.
Пример обобщенной реализации:
Код:
public class MyList<T>
{
protected static IComparer<T> TComarer = Comparer<T>.Default;
// ... Поля мои поля ... //
protected T[] _items;
// ... Конструктор ... //
public MyList(params T[] items)
{
this._items = items.Clone() as T[];
}
// ... Функции ... //
public T Max()
{
if (this._items.Length == 0) throw new IndexOutOfRangeException();
else
{
T max = this._items[0];
for (int i = 1; i < this._items.Length; i++)
if (TComarer.Compare(this._items, max) == 1)
max = this._items;
return max;
}
}
}
{
protected static IComparer<T> TComarer = Comparer<T>.Default;
// ... Поля мои поля ... //
protected T[] _items;
// ... Конструктор ... //
public MyList(params T[] items)
{
this._items = items.Clone() as T[];
}
// ... Функции ... //
public T Max()
{
if (this._items.Length == 0) throw new IndexOutOfRangeException();
else
{
T max = this._items[0];
for (int i = 1; i < this._items.Length; i++)
if (TComarer.Compare(this._items, max) == 1)
max = this._items;
return max;
}
}
}
А вот для арифметических операций +, - и т.д. универсальность не так проста:
1. В NET 4 - это dynamic типизация
2. B NET 2-3 - это reflection + шаманизм, как например http://depositfiles.com/files/ujobe1mio