算法之树形结构

上班了,太忙了,标题一天一算法也去了,实在没那个时间和精力,但是算法和数据结构一定要学下去,这次说下C#实现的树形结构。树的遍历使用的先序遍历,两个类,一个是节点结构,一个是管理节点的树。采用链式存储。直接上代码。

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
/// <summary>
/// 文件夹树目录的节点基类,这应该写成接口的,类似树节点已经集成其他基类的结构可以实现这个接口,便于ListTree类对节点实现多态
/// </summary>
public class ListTreeNode <T> {
    public ListTreeNode <T> parent;                                     //父节点
    public List<ListTreeNode <T>> children;                             //子节点集合
	public T data;														//存放信息
	public ListTreeNode () {

	}
	public ListTreeNode (T data) {
		this.data = data;
        this.children = new List<ListTreeNode<T>>();
	}
	public ListTreeNode (T data, List <ListTreeNode <T>> list) {
		this.data = data;
		this.children = list;
	}
	public ListTreeNode (T data, List <ListTreeNode <T>> list, ListTreeNode <T> parent) {
		this.data = data;
		this.children = list;
		this.parent = parent;
	} 
}

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
/// <summary>
/// 存放ListTreeNode的容器基类,对于节点的操作节点一定要从树中取得,我没有封装在一起,这写的不好
/// </summary>
public class ListTree <T> {
	#region 变量
	private ListTreeNode <T> mRoot;							//树的头节点
	#endregion
	#region 属性
	public ListTreeNode <T> Root {
		get {
			return mRoot;
		}
		set {
			mRoot = value;
		}
	}
	#endregion
	#region 构造方法
	public ListTree () {
		
	}
	public ListTree (ListTreeNode <T> root) {
		mRoot = root;
	}
	#endregion
	#region 方法
	//判断树是否为空
	public bool IsEmpty () {
		return null == mRoot ? true : false;
	}
	//获取节点,使用树的非递归先序遍历
	public ListTreeNode <T> GetNode (T nodeData) {
		if (null == mRoot) {
			return null;
		}
		ListTreeNode <T> temp = null;
		Stack <ListTreeNode <T>> stack = new Stack<ListTreeNode <T>> ();
		stack.Push (mRoot);
		while (stack.Count != 0) {
			temp = stack.Pop ();
			if (nodeData.Equals (temp.data)) {
				return temp;
			}
			for (int i = temp.children.Count - 1; i >= 0; i--) {
				stack.Push (temp.children [i]);
			}
		}
		return null;
	}
    //获取节点的路径信息集合
    public List<T> GetNodeDataArray(ListTreeNode <T> node) {
        List<T> list = new List<T>();
        Stack<T> stack = new Stack<T>();
        while (node.parent != null) {
            stack.Push(node.data);
            node = node.parent;
        }
        stack.Push(mRoot.data);
        while (stack.Count != 0) {
            list.Add(stack.Pop ());
        }
        return list;
    }
    //获取节点路径上的所有节点集合
    public List<ListTreeNode<T>> GetNodeArray(ListTreeNode <T> node) {
        List<ListTreeNode<T>> list = new List<ListTreeNode<T>>();
        Stack<ListTreeNode <T>> stack = new Stack<ListTreeNode<T>>();
        while (node.parent != null)
        {
            stack.Push(node);
            node = node.parent;
        }
        stack.Push(mRoot);
        while (stack.Count != 0)
        {
            list.Add(stack.Pop());
        }
        return list;
    }
	//判断一个节点是否存在
	public bool HaveNode (T nodeData) {
		ListTreeNode <T> temp = null;
		Stack <ListTreeNode <T>> stack = new Stack<ListTreeNode <T>> ();
		stack.Push (mRoot);
		while (stack.Count != 0) {
			temp = stack.Pop ();
			if (nodeData.Equals (temp.data)) {
				return true;
			}
			for (int i = temp.children.Count - 1; i >= 0; i--) {
				stack.Push (temp.children [i]);
			}
		}
		return false;
	}
	//插入节点,注意节点要通过GetNode方法从树中获取(用于插入一层结构)
	public bool InsertNode (ListTreeNode <T> parent, T nodeData) {
		if (null == parent) {
			return false;
		}
		ListTreeNode <T> node = new ListTreeNode<T> (nodeData);
		node.children = parent.children;
		node.parent = parent;
		parent.children.Add (node);
		return true;
	}
	//删除节点,注意节点要通过GetNode方法从树中获取
	public bool DeleteNode (ListTreeNode <T> parent, T nodeData) {
		if (null == parent) {
			return false;;
		}
		for (int i = 0; i < parent.children.Count; i++) {
			if (nodeData.Equals (parent.children [i].data)) {
				parent.children.RemoveAt (i);
			}
		}
		return true;
	}
	//添加叶子节点。注意节点要通过GetNode方法从树中获取,若返回值为假说明传入的父亲节点是空或者该父节点下的孩子节点存在此信息的节点
	public bool AddLeave (ListTreeNode <T> parent, T nodeData) {
		if (null == parent) {
			return false;
		}
		for (int i = 0; i < parent.children.Count; i++) {
			if (parent.children [i].data.Equals (nodeData)) {
				return false;
			}
		}
		ListTreeNode <T> node = new ListTreeNode<T> (nodeData);
		parent.children.Add (node);
		return true;
	}
    //添加叶子节点,并可回调该叶子节点
    public bool AddLeave(ListTreeNode<T> parent, T nodeData, out ListTreeNode <T> node)
    {
        node = new ListTreeNode<T>(nodeData);
        if (null == parent)
        {
            return false;
        }
        for (int i = 0; i < parent.children.Count; i++)
        {
            if (parent.children[i].data.Equals(nodeData))
            {
                node = parent.children[i];
                return false;
            }
        }
        parent.children.Add(node);
        node.parent = parent;
        return true;
    }
    //判断一个节点是否为叶子节点,注意节点要通过GetNode方法从树中获取
    public bool IsLeave (ListTreeNode <T> node) {
		return node.children.Count == 0 ? true : false;
	}
	#endregion
}
这次就到这了~

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值