সি # তে গাছের ডেটা কাঠামো


248

আমি সি # তে একটি বৃক্ষ বা গ্রাফের ডেটা কাঠামো খুঁজছিলাম তবে আমি অনুমান করি যে সেখানে কোনও সরবরাহ করা হয়নি। সি # 2.0 ব্যবহার করে ডেটা স্ট্রাকচারগুলির একটি বিস্তৃত পরীক্ষা কেন তা সম্পর্কে কিছুটা ব্যাখ্যা করে explains এমন কোনও সুবিধাজনক লাইব্রেরি রয়েছে যা সাধারণত এই কার্যকারিতাটি সরবরাহ করতে ব্যবহৃত হয়? সম্ভবত নিবন্ধে উপস্থাপিত সমস্যাগুলি সমাধানের কৌশল কৌশল দ্বারা।

আমি নিজের গাছটিকে বাস্তবায়ন করতে কিছুটা নির্বোধ বোধ করি, ঠিক যেমন আমি নিজের অ্যারেলিস্টটি প্রয়োগ করি।

আমি কেবল একটি জেনেরিক গাছ চাই যা ভারসাম্যহীন হতে পারে। ডিরেক্টরি গাছের কথা ভাবুন। সি 5 টি নিফটির দেখায় তবে তাদের গাছের কাঠামোটি নোডের শ্রেণিবিন্যাসের প্রতিনিধিত্বের চেয়ে অনুসন্ধানের জন্য সুষম লাল-কালো গাছ হিসাবে কার্যকর হিসাবে প্রয়োগ করা হয়েছে বলে মনে হয়।


2
বিট আরও চরম গাছ: stackoverflow.com/questions/196294/… ;-)
Tuomas Hietanen

প্রকল্পের মধ্যে একটি ট্রিভিউউজ অন্তর্ভুক্ত করে এটি ব্যবহার না করার কোনও কারণ আছে কি? এটি ব্যবহারকারীর কাছে আসলে দেখানোর কোনও কারণ নেই। অবশ্যই বিভিন্ন ধরণের প্রকল্প রয়েছে যখন এটি কোনও বিকল্প নয়। কেউ সর্বদা নতুন ক্লাস তৈরি করতে পারেন যা ট্রিনড থেকে উত্তরাধিকার সূত্রে উত্তীর্ণ হয় যদি বিশেষ জটিলতার প্রয়োজন হয়?
সহজভাবে জি।

9
আমি খুব সাধারণ গাছের জন্য একটি সম্পূর্ণ ইউআই লাইব্রেরি আমদানি করাকে খারাপ ধারণা বলে বিবেচনা করব।
উত্তেজিত করে

1
আপনি কি অনুপ্রেরণা দিতে পারেন? এটি সত্যিকারের হার্ডড্রাইভ জায়গার প্রয়োজনের মতো নয় এখন আর কোনও সমস্যা? কদাকার? যেমনটি আমি আগেই উল্লেখ করেছি, আমি বুঝতে পারি যে এটি কোনও বিশেষায়িত সফ্টওয়্যার বা বিদ্যমান ব্যবহারকারীর ইন্টারফেস ছাড়া কোনও কিছুর সমাধান নয়। আমি একটি অলস প্রোগ্রামার, যদি আমি কোনও কাঠামোগুলি বিনামূল্যে এটি পেতে পারি তবে এটি ভাল। এবং একটি বিদ্যমান গ্রন্থাগারটিতে অনেকগুলি নিখরচায় রয়েছে, যে কোনও ব্যক্তি প্রচুর পরিমাণে এটি ব্যবহার করে এমন লোকদের কাছ থেকে প্রচুর কোড পাওয়া যায়।
সহজভাবে জি।

আমি তর্ক করছি না, আমি কেবল আপনার যুক্তি জানতে চাই।
সহজভাবে জি।

উত্তর:


155

আমার সর্বোত্তম পরামর্শটি হ'ল কোনও স্ট্যান্ডার্ড ট্রি ডেটা কাঠামো নেই কারণ আপনি এটি প্রয়োগ করতে পারেন এমন অনেকগুলি উপায় রয়েছে যে একটি সমাধান দিয়ে সমস্ত ঘাঁটি আবরণ করা অসম্ভব। সমাধান যত বেশি সুনির্দিষ্ট হবে, প্রদত্ত যে কোনও সমস্যার ক্ষেত্রে এটি তত কম প্রযোজ্য। আমি লিংকডলিস্টে বিরক্তও হয়েছি - আমি যদি একটি বিজ্ঞপ্তিযুক্ত লিঙ্ক তালিকা চাই?

আপনার প্রয়োগ করতে হবে এমন প্রাথমিক কাঠামোটি নোডের সংগ্রহ হবে এবং আপনাকে শুরু করার জন্য এখানে কয়েকটি বিকল্প রয়েছে। চলুন ধরে নেওয়া যাক ক্লোজ নোড হ'ল সম্পূর্ণ সমাধানের বেস ক্লাস।

আপনার যদি কেবল গাছের নীচে নেভিগেট করতে হয় তবে নোড শ্রেণীর জন্য বাচ্চাদের একটি তালিকা প্রয়োজন।

আপনার যদি গাছটি উপরে চলাচল করতে হয়, তবে নোড শ্রেণীর জন্য তার পিতামাতার নোডের একটি লিঙ্ক প্রয়োজন।

এই অ্যাডচিल्ड পদ্ধতিটি তৈরি করুন যা এই দুটি পয়েন্টের সমস্ত সংক্ষিপ্তসার এবং অন্য যে কোনও ব্যবসায়িক যুক্তি যা অবশ্যই প্রয়োগ করা উচিত (সন্তানের সীমাবদ্ধকরণ, বাচ্চাদের বাছাই করা ইত্যাদি) যত্ন করে Build


5
ব্যক্তিগতভাবে আমি কোনও ধরণের স্ব-ভারসাম্য বাইনারি ট্রি লাইব্রেরিতে যুক্ত করার জন্য কিছু মনে করব না কারণ এটি কেবল সংলগ্ন তালিকা ব্যবহারের চেয়ে কিছু অতিরিক্ত কাজ।
জে কে।

8
@ জে কে আমি বিশ্বাস করি যে সাজানো ডিকোরিয়ালিটি এবং সাজানোসেট লাল / কালো গাছের উপরে নির্মিত, তাই এগুলি ব্যবহার করে কাজ করা উচিত।
jonp

যৌগিক প্যাটার্নটি একবার দেখুন ;-) ঠিক আপনি কী খুঁজছেন
নিকোলাস ভোরন

119
delegate void TreeVisitor<T>(T nodeData);

class NTree<T>
{
    private T data;
    private LinkedList<NTree<T>> children;

    public NTree(T data)
    {
         this.data = data;
        children = new LinkedList<NTree<T>>();
    }

    public void AddChild(T data)
    {
        children.AddFirst(new NTree<T>(data));
    }

    public NTree<T> GetChild(int i)
    {
        foreach (NTree<T> n in children)
            if (--i == 0)
                return n;
        return null;
    }

    public void Traverse(NTree<T> node, TreeVisitor<T> visitor)
    {
        visitor(node.data);
        foreach (NTree<T> kid in node.children)
            Traverse(kid, visitor);
    }
}

সাধারণ পুনরাবৃত্তিমূলক বাস্তবায়ন ... কোডের ৪০ টি লাইন ... আপনার কেবল শ্রেণির বাইরে গাছের গোড়ায় একটি রেফারেন্স রাখতে হবে, বা অন্য কোনও ক্লাসে আবদ্ধ করতে হবে, সম্ভবত ট্রিউনডের নামকরণ করতে হবে ??


22
এই ক্ষেত্রে, C # যাহাই হউক না কেন, আপনি আপনার নিজের প্রতিনিধি লেখার এড়াতে এবং প্রাক তৈরি ব্যবহার করতে পারে Action<T>প্রতিনিধি: public void traverse(NTree<T> node, Action<T> visitor)। অ্যাকশন <> 'র স্বাক্ষর হল: void Action<T>( T obj )। 0 থেকে 4 টি বিভিন্ন পরামিতিগুলির সংস্করণও রয়েছে। ডেকে আনা ফাংশনগুলির জন্য একটি উপমা প্রতিনিধিও রয়েছে Func<>
বেনি জোবিগান

2
আমি এই প্রতিনিধিকে কীভাবে ডাকব?
freakishly

3
ট্র্যাভার্স পদ্ধতিটি স্থিতিশীল হিসাবে পরিবর্তন করা বা পুনরাবৃত্ত প্রকৃতিটি লুকানোর জন্য সম্ভবত এটি মোড়ানো একটি ভাল ধারণা হবে তবে এটি ট্র্যাভার করা সহজ: ডেলিগেটের স্বাক্ষর সহ একটি পদ্ধতি তৈরি করুন অর্থাত্ ইনস গাছের জন্য: অকার্যকর my_visitor_impl (int datum) - আপনার যদি প্রয়োজন হয় তবে এটি অচল করুন, একটি ডেলগেট ইনস্ট্যান্ট করুন: ট্রিভিজিটার <মিন্ট> মাই_ভিসিটার = মাই_ভিসিটার_আইপিএল; এবং তারপরে রুট নোড বা এনটি ট্রি ক্লাসে প্রার্থনা করুন যদি আপনি এটিকে স্থির করেন: এনটি্রি <মিন্ট> ট্র্যাভারস (মাই_ট্রি, মাই_ভিসিটার)
অ্যারন গেজ

10
অ্যাডচাইল্ড () তৈরি করে এনটিআরটি এটি যুক্ত করে যা এটি যুক্ত করে এটি একটি গাছে ডেটা যুক্ত করার জন্য আরও সুন্দর করে তোলে। (যতক্ষণ না আমি এই সাথে একটি গাছ তৈরির একটি চাতুরিক উপায় মিস করছি না, যদি না একটি নতুন যুক্ত হওয়া শিশু == getChild (1)?) প্রয়োগের বিশদটির উপর নির্ভর না করে
ররি

1
আমি মনে করি এই বিবৃতিটি --i == 0কেবল একক ক্ষেত্রে কার্যকর হবে? এটা কি সত্য. এটি আমাকে বিভ্রান্ত করেছে
ওয়াসিম আহমেদ না

57

এটি আমার, যা অ্যারোন গেজের সাথে খুব মিল আমার মতে আরও কিছুটা প্রচলিত। আমার উদ্দেশ্যগুলির জন্য, আমি কোনও পারফরম্যান্স সম্পর্কিত সমস্যা নিয়ে যাইনি List<T>। প্রয়োজনে লিংকডলিস্টে স্যুইচ করা যথেষ্ট সহজ হবে।


namespace Overby.Collections
{
    public class TreeNode<T>
    {
        private readonly T _value;
        private readonly List<TreeNode<T>> _children = new List<TreeNode<T>>();

        public TreeNode(T value)
        {
            _value = value;
        }

        public TreeNode<T> this[int i]
        {
            get { return _children[i]; }
        }

        public TreeNode<T> Parent { get; private set; }

        public T Value { get { return _value; } }

        public ReadOnlyCollection<TreeNode<T>> Children
        {
            get { return _children.AsReadOnly(); }
        }

        public TreeNode<T> AddChild(T value)
        {
            var node = new TreeNode<T>(value) {Parent = this};
            _children.Add(node);
            return node;
        }

        public TreeNode<T>[] AddChildren(params T[] values)
        {
            return values.Select(AddChild).ToArray();
        }

        public bool RemoveChild(TreeNode<T> node)
        {
            return _children.Remove(node);
        }

        public void Traverse(Action<T> action)
        {
            action(Value);
            foreach (var child in _children)
                child.Traverse(action);
        }

        public IEnumerable<T> Flatten()
        {
            return new[] {Value}.Concat(_children.SelectMany(x => x.Flatten()));
        }
    }
}

আপনি যখন কনস্ট্রাক্টরে সেট করছেন তখন আপনার মূল্য সম্পত্তি কেন উন্মুক্ত? আপনি এটি ইতিমধ্যে নির্মাতার মাধ্যমে সেট করে রেখেছেন তারপরে এটি হেরফের জন্য উন্মুক্ত করে দেয়? ব্যক্তিগত সেট করা উচিত?
PositiveGuy

অবশ্যই, কেন এটি অপরিবর্তনীয় নয়? সম্পাদনা করা হয়েছে।
রনি ওভারবি

ধন্যবাদ! আমার নিজের নিজের লেখা না ভাল লাগলো। (এখনও বিশ্বাস করতে পারি না যে এটি স্থানীয়ভাবে বিদ্যমান কোনও জিনিস নয় I আমি সবসময় ভাবতাম। নেট, বা কমপক্ষে নেট 4.0.০, সবকিছু ছিল ।)
নিমিনেম

3
আমি এই সমাধানটি পছন্দ করেছি। আমি সন্নিবেশ করার প্রয়োজনও পেয়েছি, এটি করার জন্য আমি নিম্নলিখিত পদ্ধতিটি যুক্ত করেছি। public TreeNode<T> InsertChild(TreeNode<T> parent, T value) { var node = new TreeNode<T>(value) { Parent = parent }; parent._children.Add(node); return node; } var five = myTree.AddChild(5); myTree.InsertChild(five, 55);
জ্যাবারওয়কিডেকম্পেলার

48

তবুও অন্য গাছের কাঠামো:

public class TreeNode<T> : IEnumerable<TreeNode<T>>
{

    public T Data { get; set; }
    public TreeNode<T> Parent { get; set; }
    public ICollection<TreeNode<T>> Children { get; set; }

    public TreeNode(T data)
    {
        this.Data = data;
        this.Children = new LinkedList<TreeNode<T>>();
    }

    public TreeNode<T> AddChild(T child)
    {
        TreeNode<T> childNode = new TreeNode<T>(child) { Parent = this };
        this.Children.Add(childNode);
        return childNode;
    }

    ... // for iterator details see below link
}

নমুনা ব্যবহার:

TreeNode<string> root = new TreeNode<string>("root");
{
    TreeNode<string> node0 = root.AddChild("node0");
    TreeNode<string> node1 = root.AddChild("node1");
    TreeNode<string> node2 = root.AddChild("node2");
    {
        TreeNode<string> node20 = node2.AddChild(null);
        TreeNode<string> node21 = node2.AddChild("node21");
        {
            TreeNode<string> node210 = node21.AddChild("node210");
            TreeNode<string> node211 = node21.AddChild("node211");
        }
    }
    TreeNode<string> node3 = root.AddChild("node3");
    {
        TreeNode<string> node30 = node3.AddChild("node30");
    }
}

বোনাস এর সাথে
সম্পূর্ণ সজ্জিত গাছ দেখুন:

  • পুনরুক্তিকারীর
  • অনুসন্ধান
  • জাভা / সি #

https://github.com/gt4dev/yet-another-tree-structure


আমি কীভাবে আপনার কোড উদাহরণটিতে অনুসন্ধানটি ব্যবহার করব? কোথা nodeথেকে আসে? এর অর্থ কি অনুসন্ধান কোডটি ব্যবহার করার জন্য আমাকে গাছের উপর দিয়ে পুনরাবৃত্তি করতে হবে?
ব্যাডমিন্টনকিট

@ গ্রজেগোর্জদেভ হতে পারে -1 কারণ এটি সমস্ত IEnumerable<>সদস্যকে বাস্তবায়িত করে না , তাই এটি সংকলন করে না।
উওয়ে কেইম

1
@উইকিউইম গুড জব, পরের বার কোডটি ব্যবহার করে প্রকৃত ব্যবহারের চেষ্টা করুন।
szab.kel

আমি যে সমস্যাটি দেখতে পাচ্ছি তা হ'ল এটি জেনসন কনভার্টের সাথে যথাযথভাবে সিরিয়ালায়িত হবে না কারণ এটি কার্যকর হয় <>
রাকিয়ায়

22

সাধারনত দুর্দান্ত সি 5 জেনেরিক সংগ্রহ লাইব্রেরিতে সেট, ব্যাগ এবং অভিধান সহ বিভিন্ন গাছ ভিত্তিক ডেটা স্ট্রাকচার রয়েছে। আপনি যদি তাদের প্রয়োগের বিশদটি অধ্যয়ন করতে চান তবে উত্স কোড উপলব্ধ। (আমি প্রোডাকশন কোডে সি 5 সংগ্রহগুলি ভাল ফলাফল সহ ব্যবহার করেছি, যদিও আমি নির্দিষ্টভাবে গাছের কোনও কাঠামো ব্যবহার করি নি।)


7
জিনিসগুলি পরিবর্তিত হয়েছে কিনা তা জানেন না তবে এই মুহূর্তে বইটি সি 5 সাইট থেকে পিডিএফ হিসাবে ডাউনলোড করার জন্য অবাধে উপলব্ধ।
অস্কার

4
লাইব্রেরির পরিপূরক ২ 27২ পৃষ্ঠার দীর্ঘ পিডিএফ হ'ল ডকুমেন্টেশনের অভাব এখন আর উদ্বেগের বিষয় নয় ... কোডের মান নিয়ে মন্তব্য করতে পারছি না, তবে ডক মানের থেকে বিচার করে, আমি আজকের রাতেই সত্যই এই খননের অপেক্ষায় রয়েছি!
ফ্লোরিয়ান ডায়ন

2
আমি যা বুঝতে পারি তা থেকে, এই সি 5 লাইব্রেরিতে মোটেও গাছ নেই তবে কেবল কয়েকটি গাছ থেকে প্রাপ্ত ডেটা স্ট্রাকচার রয়েছে।
রোম করুন

10

দেখা Http://quickographic.codeplex.com/

কুইকগ্রাফ। নেট 2.0 এবং উচ্চতর জন্য জেনেরিক পরিচালিত / পুনর্নির্দেশিত গ্রাফ ডেটাস্ট্রাকচার এবং অ্যালগরিদম সরবরাহ করে। কুইগ্রাগ্রাফ আলগরিদমগুলির সাথে আসে যেমন গভীরতা প্রথম সমুদ্র সৈকত, শ্বাসের প্রথম অনুসন্ধান, একটি * অনুসন্ধান, সংক্ষিপ্ততম পথ, কে-সংক্ষিপ্ততম পথ, সর্বাধিক প্রবাহ, ন্যূনতম স্প্যানিং ট্রি, কমপক্ষে সাধারণ পূর্বপুরুষ ইত্যাদি ... কুইকগ্রাফ এমএসএজিএল, গ্লি এবং গ্রাফভিজকে সমর্থন করে গ্রাফগুলি, সিরিয়ালকরণ গ্রাফএমএল ইত্যাদি রেন্ডার করুন ...


8

আপনি যদি নিজের লেখা লিখতে চান, আপনি সি # ২.০ ডেটা স্ট্রাকচারের কার্যকর ব্যবহার এবং কীভাবে সি # তে আপনার ডেটা স্ট্রাকচারের বাস্তবায়ন বিশ্লেষণ করবেন সে সম্পর্কে বিশদভাবে এই ছয় অংশের নথির সাহায্যে শুরু করতে পারেন। প্রতিটি নিবন্ধে উদাহরণ এবং একটি ইনস্টলার রয়েছে যাতে আপনি অনুসরণ করতে পারেন নমুনা with

স্কট মিচেল "সি # 2.0 ব্যবহার করে ডেটা স্ট্রাকচারগুলির একটি বিস্তৃত পরীক্ষা"


7

সমাধানগুলিতে আমার একটু এক্সটেনশন আছে।

একটি পুনরাবৃত্ত জেনেরিক ঘোষণা এবং একটি ডেরাইভিং সাবক্লাস ব্যবহার করে আপনি আপনার প্রকৃত লক্ষ্যটিতে আরও ভাল মনোনিবেশ করতে পারেন।

লক্ষ্য করুন, এটি জেনারিক বাস্তবায়ন থেকে আলাদা, আপনার 'নোড ওয়ার্কার'-এ' নোড 'দেওয়ার দরকার নেই।

এখানে আমার উদাহরণ:

public class GenericTree<T> where T : GenericTree<T> // recursive constraint  
{
  // no specific data declaration  

  protected List<T> children;

  public GenericTree()
  {
    this.children = new List<T>();
  }

  public virtual void AddChild(T newChild)
  {
    this.children.Add(newChild);
  }

  public void Traverse(Action<int, T> visitor)
  {
    this.traverse(0, visitor);
  }

  protected virtual void traverse(int depth, Action<int, T> visitor)
  {
    visitor(depth, (T)this);
    foreach (T child in this.children)
      child.traverse(depth + 1, visitor);
  }
}

public class GenericTreeNext : GenericTree<GenericTreeNext> // concrete derivation
{
  public string Name {get; set;} // user-data example

  public GenericTreeNext(string name)
  {
    this.Name = name;
  }
}

static void Main(string[] args)  
{  
  GenericTreeNext tree = new GenericTreeNext("Main-Harry");  
  tree.AddChild(new GenericTreeNext("Main-Sub-Willy"));  
  GenericTreeNext inter = new GenericTreeNext("Main-Inter-Willy");  
  inter.AddChild(new GenericTreeNext("Inter-Sub-Tom"));  
  inter.AddChild(new GenericTreeNext("Inter-Sub-Magda"));  
  tree.AddChild(inter);  
  tree.AddChild(new GenericTreeNext("Main-Sub-Chantal"));  
  tree.Traverse(NodeWorker);  
}  

static void NodeWorker(int depth, GenericTreeNext node)  
{                                // a little one-line string-concatenation (n-times)
  Console.WriteLine("{0}{1}: {2}", String.Join("   ", new string[depth + 1]), depth, node.Name);  
}  

গভীরতা কী এবং কোথা থেকে এবং কীভাবে আপনি এটি থেকে পান?
PositiveGuy

@ WeDoTDD.com তার শ্রেণীর দিকে তাকিয়ে দেখেন ট্র্যাভার্স এটিকে মূল নোড থেকে শুরু করার জন্য 0 হিসাবে ঘোষণা করে, তারপরে প্রতিটি পুনরাবৃত্তিকে যুক্ত করে ট্র্যাভার্স পদ্ধতিটি ব্যবহার করে।
এডওয়ার্ড

এএ নির্দিষ্ট নোডের জন্য আপনি কীভাবে পুরো গাছটি অনুসন্ধান করবেন?
mattpm

6

এখানে আমার নিজস্ব:

class Program
{
    static void Main(string[] args)
    {
        var tree = new Tree<string>()
            .Begin("Fastfood")
                .Begin("Pizza")
                    .Add("Margherita")
                    .Add("Marinara")
                .End()
                .Begin("Burger")
                    .Add("Cheese burger")
                    .Add("Chili burger")
                    .Add("Rice burger")
                .End()
            .End();

        tree.Nodes.ForEach(p => PrintNode(p, 0));
        Console.ReadKey();
    }

    static void PrintNode<T>(TreeNode<T> node, int level)
    {
        Console.WriteLine("{0}{1}", new string(' ', level * 3), node.Value);
        level++;
        node.Children.ForEach(p => PrintNode(p, level));
    }
}

public class Tree<T>
{
    private Stack<TreeNode<T>> m_Stack = new Stack<TreeNode<T>>();

    public List<TreeNode<T>> Nodes { get; } = new List<TreeNode<T>>();

    public Tree<T> Begin(T val)
    {
        if (m_Stack.Count == 0)
        {
            var node = new TreeNode<T>(val, null);
            Nodes.Add(node);
            m_Stack.Push(node);
        }
        else
        {
            var node = m_Stack.Peek().Add(val);
            m_Stack.Push(node);
        }

        return this;
    }

    public Tree<T> Add(T val)
    {
        m_Stack.Peek().Add(val);
        return this;
    }

    public Tree<T> End()
    {
        m_Stack.Pop();
        return this;
    }
}

public class TreeNode<T>
{
    public T Value { get; }
    public TreeNode<T> Parent { get; }
    public List<TreeNode<T>> Children { get; }

    public TreeNode(T val, TreeNode<T> parent)
    {
        Value = val;
        Parent = parent;
        Children = new List<TreeNode<T>>();
    }

    public TreeNode<T> Add(T val)
    {
        var node = new TreeNode<T>(val, this);
        Children.Add(node);
        return node;
    }
}

আউটপুট:

Fastfood
   Pizza
      Margherita
      Marinara
   Burger
      Cheese burger
      Chili burger
      Rice burger

4

এই সহজ নমুনা চেষ্টা করুন।

public class TreeNode<TValue>
{
    #region Properties
    public TValue Value { get; set; }
    public List<TreeNode<TValue>> Children { get; private set; }
    public bool HasChild { get { return Children.Any(); } }
    #endregion
    #region Constructor
    public TreeNode()
    {
        this.Children = new List<TreeNode<TValue>>();
    }
    public TreeNode(TValue value)
        : this()
    {
        this.Value = value;
    }
    #endregion
    #region Methods
    public void AddChild(TreeNode<TValue> treeNode)
    {
        Children.Add(treeNode);
    }
    public void AddChild(TValue value)
    {
        var treeNode = new TreeNode<TValue>(value);
        AddChild(treeNode);
    }
    #endregion
}

2

আমি একটি নোড শ্রেণি তৈরি করেছি যা অন্য মানুষের জন্য সহায়ক হতে পারে। শ্রেণীর মতো বৈশিষ্ট্য রয়েছে:

  • শিশু
  • পূর্বপুরুষ
  • উত্তরপুরূষ
  • ভাইবোন
  • নোডের স্তর
  • মাতা
  • মূল
  • প্রভৃতি

আইডি এবং প্যারেন্টআইডের সাহায্যে আইটেমের ফ্ল্যাট তালিকাটিকে একটি গাছে রূপান্তর করারও সম্ভাবনা রয়েছে। নোডগুলি শিশু এবং পিতামাতার উভয়েরই জন্য একটি রেফারেন্স ধারণ করে, যাতে পুনরাবৃত্ত নোডগুলি বেশ দ্রুত তৈরি হয়।


2

কারণ এটি উল্লেখ করা হয়নি, আমি চাই আপনি এখন প্রকাশিত। নেট কোড-বেস: বিশেষত একটিটির জন্য কোড attention SortedSet একটি লাল-কালো-বৃক্ষ প্রয়োগকারী :

https://github.com/Microsoft/referencesource/blob/master/System/compmod/system/collections/generic/sortedset.cs

এটি অবশ্য একটি সুষম গাছের কাঠামো। সুতরাং আমার উত্তরটি আমি বিশ্বাস করি তার আরও বেশি রেফারেন্স। নেট কোর লাইব্রেরির একমাত্র নেটিভ ট্রি-স্ট্রাকচার।


2

@ বেরেজ যে কোডটি ভাগ করেছেন তা আমি পূরণ করেছি।

  public class TreeNode<T> : IEnumerable<TreeNode<T>>
    {

        public T Data { get; set; }
        public TreeNode<T> Parent { get; set; }
        public ICollection<TreeNode<T>> Children { get; set; }

        public TreeNode(T data)
        {
            this.Data = data;
            this.Children = new LinkedList<TreeNode<T>>();
        }

        public TreeNode<T> AddChild(T child)
        {
            TreeNode<T> childNode = new TreeNode<T>(child) { Parent = this };
            this.Children.Add(childNode);
            return childNode;
        }

        public IEnumerator<TreeNode<T>> GetEnumerator()
        {
            throw new NotImplementedException();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return (IEnumerator)GetEnumerator();
        }
    }
    public class TreeNodeEnum<T> : IEnumerator<TreeNode<T>>
    {

        int position = -1;
        public List<TreeNode<T>> Nodes { get; set; }

        public TreeNode<T> Current
        {
            get
            {
                try
                {
                    return Nodes[position];
                }
                catch (IndexOutOfRangeException)
                {
                    throw new InvalidOperationException();
                }
            }
        }


        object IEnumerator.Current
        {
            get
            {
                return Current;
            }
        }


        public TreeNodeEnum(List<TreeNode<T>> nodes)
        {
            Nodes = nodes;
        }

        public void Dispose()
        {
        }

        public bool MoveNext()
        {
            position++;
            return (position < Nodes.Count);
        }

        public void Reset()
        {
            position = -1;
        }
    }

ভাল নকশা. তবে আমি নিশ্চিত নোড তার শিশু নোডের অনুক্রম 'কিনা' তা নিশ্চিত না। আমি নিম্নলিখিতগুলি বিবেচনা করব: একটি নোডের 'শূন্য বা আরও বেশি শিশু নোড রয়েছে, তাই কোনও নোড চাইল্ড নোডের ক্রম থেকে উদ্ভূত হয় না, তবে এটি তার শিশু নোডের একটি সমন্বয় (রচনা?)
হ্যারাল্ড কোপপুলিস

2

এখানে একটি গাছ

public class Tree<T> : List<Tree<T>>
{
    public  T Data { get; private set; }

    public Tree(T data)
    {
        this.Data = data;
    }

    public Tree<T> Add(T data)
    {
        var node = new Tree<T>(data);
        this.Add(node);
        return node;
    }
}

আপনি এমনকি প্রাথমিক ব্যবহার করতে পারেন:

    var tree = new Tree<string>("root")
    {
        new Tree<string>("sample")
        {
            "console1"
        }
    };

1

আপনার প্রক্রিয়াকরণ করা ডেটা দ্বারা বেশিরভাগ গাছ গঠিত।

বলুন যে আপনার একটি personক্লাস রয়েছে যার মধ্যে কারও বিবরণ রয়েছে parents, আপনি কি আপনার "ডোমেন ক্লাস" এর অংশ হিসাবে গাছের কাঠামোটি যুক্ত করবেন বা আপনার পৃথক বস্তুর সাথে লিঙ্কযুক্ত একটি পৃথক ট্রি ক্লাস ব্যবহার করবেন? সব পেয়ে মত সরল অপারেশন সম্পর্কে চিন্তা করুন grandchildrenএকটি এর person, এই কোড থাকা উচিত person বর্গ, বা ব্যবহারকারী উচিত personবর্গ একটি পৃথক গাছ বর্গ সম্পর্কে জানতে আছে?

অন্য উদাহরণটি একটি সংকলকের পার্স গাছ ...

এই দুটি উদাহরণই যা দেখায় তা হ'ল গাছের ধারণাটি ডেটা ডোমেনের অংশ এবং একটি পৃথক সাধারণ উদ্দেশ্য গাছ ব্যবহার করে তৈরি করা বস্তুর সংখ্যা কমপক্ষে দ্বিগুণ করে পাশাপাশি প্রোগ্রামটিকে আরও শক্ত করে তুলতে।

আমরা যা চাই তা হ'ল স্ট্যান্ডার্ড ট্রি ক্রিয়াকলাপগুলি পুনরায় ব্যবহার করার উপায়, সমস্ত গাছের জন্য এগুলি পুনরায় প্রয়োগ না করে একই সময়ে, কোনও স্ট্যান্ডার্ড ট্রি ক্লাস ব্যবহার না করে। বুস্ট এই ধরণের সমস্যাটি সি +++ এর জন্য সমাধান করার চেষ্টা করেছে, তবে এখনও .NET অভিযোজিত হওয়ার জন্য আমি কোনও প্রভাব দেখতে পাই না।


@ পুচাকস, দুঃখিত আমি সি ++ এর ডেটা ছাড়িয়ে 15 বছর বয়সী, বুস্ট এবং টেম্পলেটগুলির দিকে একবার নজর রেখেছি, অল্প কিছু অধ্যয়নের পরে আপনি সেগুলি বুঝতে পারেন। পাওয়ার উচ্চ শিক্ষার ব্যয় হয় !!
ইয়ান রিংরোজ

1

আমি উপরের এনটি্রি ক্লাস ব্যবহার করে সম্পূর্ণ সমাধান এবং উদাহরণ যুক্ত করেছি, "অ্যাডচিল্ড" পদ্ধতিও যুক্ত করেছি ...

    public class NTree<T>
    {
        public T data;
        public LinkedList<NTree<T>> children;

        public NTree(T data)
        {
            this.data = data;
            children = new LinkedList<NTree<T>>();
        }

        public void AddChild(T data)
        {
            var node = new NTree<T>(data) { Parent = this };
            children.AddFirst(node);
        }

        public NTree<T> Parent { get; private set; }

        public NTree<T> GetChild(int i)
        {
            foreach (NTree<T> n in children)
                if (--i == 0)
                    return n;
            return null;
        }

        public void Traverse(NTree<T> node, TreeVisitor<T> visitor, string t, ref NTree<T> r)
        {
            visitor(node.data, node, t, ref r);
            foreach (NTree<T> kid in node.children)
                Traverse(kid, visitor, t, ref r);
        }
    }
    public static void DelegateMethod(KeyValuePair<string, string> data, NTree<KeyValuePair<string, string>> node, string t, ref NTree<KeyValuePair<string, string>> r)
    {
        string a = string.Empty;
        if (node.data.Key == t)
        {
            r = node;
            return;
        }
    }

ব্যবহার

 NTree<KeyValuePair<string, string>> ret = null;
 tree.Traverse(tree, DelegateMethod, node["categoryId"].InnerText, ref ret);

ট্র্যাভার্স সম্ভবত স্ট্যাটিক পদ্ধতি হওয়া উচিত? উদাহরণস্বরূপ পদ্ধতিটি নিজের মধ্যে চলে যাওয়ার হিসাবে এটি অত্যন্ত বিশ্রী বলে মনে হচ্ছে
সিনেটেস্ট্যাটিক

0

এখানে আমার বিএসটি বাস্তবায়ন

class BST
{
    public class Node
    {
        public Node Left { get; set; }
        public object Data { get; set; }
        public Node Right { get; set; }

        public Node()
        {
            Data = null;
        }

        public Node(int Data)
        {
            this.Data = (object)Data;
        }

        public void Insert(int Data)
        {
            if (this.Data == null)
            {
                this.Data = (object)Data;
                return;
            }
            if (Data > (int)this.Data)
            {
                if (this.Right == null)
                {
                    this.Right = new Node(Data);
                }
                else
                {
                    this.Right.Insert(Data);
                }
            }
            if (Data <= (int)this.Data)
            {
                if (this.Left == null)
                {
                    this.Left = new Node(Data);
                }
                else
                {
                    this.Left.Insert(Data);
                }
            }
        }

        public void TraverseInOrder()
        {
            if(this.Left != null)
                this.Left.TraverseInOrder();
            Console.Write("{0} ", this.Data);
            if (this.Right != null)
                this.Right.TraverseInOrder();
        }
    }

    public Node Root { get; set; }
    public BST()
    {
        Root = new Node();
    }
}

0

আপনি যদি এই গাছটি জিইউআইতে প্রদর্শন করতে চলেছেন তবে আপনি ট্রিভিউ এবং ট্রিউনোড ব্যবহার করতে পারেন । (আমি মনে করি প্রযুক্তিগতভাবে আপনি একটি জিইউআইতে না রেখে আপনি একটি ট্রিনোড তৈরি করতে পারেন, তবে এটি একটি সাধারণ হোমগ্রাউন টিউনোড প্রয়োগের চেয়ে বেশি ওভারহেড রাখে))


-4

আপনার যদি কোনও শিকড়যুক্ত গাছের ডেটা কাঠামোর প্রয়োগের প্রয়োজন হয় যা কম স্মৃতি ব্যবহার করে তবে আপনি নিজের নোড শ্রেণিটি নিম্নরূপে লিখতে পারেন (সি ++ বাস্তবায়ন):

class Node {
       Node* parent;
       int item; // depending on your needs

       Node* firstChild; //pointer to left most child of node
       Node* nextSibling; //pointer to the sibling to the right
}

12
বিশেষত সি # এর জন্য একটি প্রশ্নে সি ++ কোড পোস্ট করা সেরা ধারণা নয়, জ্যাক। বিশেষত একটি যা পয়েন্টার অন্তর্ভুক্ত। আপনি কি জানেন যে পয়েন্টারগুলি সি # তে নির্দয়ভাবে শিকার করা হচ্ছে, তাই না? : পি
থান্ডারগ্রি

2
পছন্দ করুন সি # তে উত্তর দেওয়া ভাল হত তবে সেই সি ++ পয়েন্টারগুলি সি # স্পিকারের দ্বারা রেফারেন্স হিসাবে বুঝতে পারে (তারা কম সুরক্ষিত, ঠিক আছে)। ডেভিড বোইক, অ্যারন গেজ, রনি ওভারবি, গ্রজেগোর্জ দেব, বেরেজ এবং এরিক নাগেল সবার পরে কেবলমাত্র মত প্রকাশের ক্ষেত্রে সামান্য পার্থক্যের সাথে একইভাবে ডেটা স্ট্রাকচারকে বাড়িয়ে তোলেন, জ্যাক যুক্ত লিস্টের তালিকাকে ভেঙে ফেলে কেবলমাত্র এক ধরণের নোডের সাথে একটি সহজ কাঠামো উপস্থাপন করেন এবং ভাইবোন নাব্যতা। গঠনমূলক উত্তর ডাউন ভোট দিয়ে সি ++ এর অপছন্দ প্রকাশ করবেন না।

3
@ মিগল আমি উত্তরটি কমিয়ে দেখিনি (কোনওটি উত্থাপনও করেনি)। এবং আমি সি ++ অপছন্দ করি না। আমি দেখেছি যে কেন এবং কীভাবে তার উত্তর উন্নত করবে সে সম্পর্কে কেউ জ্যাককে কোনও পরামর্শ না দিয়েই উত্তরটি হ্রাস পেয়েছে। এটি "ভাল হওয়া" সম্পর্কে নয়। প্রশ্নটি কেবল সি # এর জন্য ট্যাগ করা আছে। ট্যাগের চেয়ে অন্য ভাষায় উত্তর পোস্ট করার প্রস্তাব দেওয়া হয় না এবং কিছু লোক নীচে নামবে।
থান্ডারগ্রি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.