数据结构之广义表

源代码见:点击打开链接

1.定义

    广义表是对线性表的扩展,在线性表中,表中元素具有原子性,不可分解。如果允许表中的元素具有某种结构,这就引入了广义表的概念。广义表的定义如下:

    它是n(n>0)个数据元素a0,a1,……,an-1组成的有限序列,记为GList=(a0,a1,……,an-1),其中,ai(0<=i

    语法图如下:

    数据结构之广义表_第1张图片

    举个例子:

中国(北京,上海,江苏(南京,苏州),浙江(杭州))

    

2.数据结构

    结构:

                广义表节点(data数据域,child子表地址域,next后继结点地址域)

    举例:已知三个有名广义表

              L(a,b)

              T(c,L(a,b))

              G(d,L(a,b),T(c,L(a,b)))

G的存储结构如下:

数据结构之广义表_第2张图片

    

    为什么需要头节点?便于在表头增加删除结点。如果不要头结点,那么对广义表的表头添加删除,将可能影响其他广义表中元素。比如,上面G的存储结构改为不要头结点的方式。如下:

数据结构之广义表_第3张图片

    如果此时通过G访问子表L并删除L中的第一个结点a后,G中L结点的child指向原a结点的后继结点b。而这样的删除并没有影响到T表中的L结点的child域。如下:

数据结构之广义表_第4张图片

3.广义表的设计实现

    广义表的基本操作:遍历,求深度,插入元素,删除元素,查找元素,判读是否为空广义表。

uml图如下:

数据结构之广义表_第5张图片

说明:

head:广义表头结点

GenList():初始化广义表,也就是让head=new GenNode();

boolean depth():求广义表的深度

int insert(int i,T t):插入原子作为第i个元素,如果插入成功返回1,否则返回0

int insert(int i,GenList gl):插入子广义表作为第i个元素,如果插入成功返回1,否则返回0

int remove(int i):删除第i个元素,删除成功返回1,否则返回0

T getElement(int i):获取广义表第i个元素

T setElement(int i,T t):将广义表的第i个元素设置为t。设置成功返回1,否则返回0


data:元素数据域,是一个T类型的数据

child:地址域,指向子广义表

next:地址域,指向后继结点(其实next(GenNode)的类型可以和child(GenList)的类型一样,因为他们都有共同特征,可以作为广义表的元素。只不过作为GenNode类型的next没有作为GenList类型的child一些操作方法。这让我想起了java设计模式的组合模式,这提供了一种实现广义表的另一种方法)

GenNode():初始化data,child,next

GenNode(T t):通过t,让data=t;

GenNode(T t,GenList c,GenNode n):用t,c,n分别初始化data,child,next 


广义表的遍历(注意以下的广义表的遍历和求深度的方法都是针对再入表的,不适用于递归表,不信你试试!),采用的是递归的方法,其流程图如下:

数据结构之广义表_第6张图片

代码如下:

public String toString() {
		return this.toString("");
	}

	public String toString(String str) {
		str += "(";
		for (GenNode p = this.head.getNext(); p != null; p = p.getNext()) {
			if (p.getChild() == null) {
				str += p.getData().toString();
			} else {
				str += p.getChild().toString();
			}
			if (p.getNext() != null) {
				str += ",";
			}
		}
		return str + ")";
	}

测试代码:

GenList L=new GenList();
		L.insert(1);
		L.insert(2);
		GenList T=new GenList();
		T.insert(3);
		T.insert(L);
		GenList G=new GenList();
		G.insert(4);
		G.insert(L);
		G.insert(T);
		System.out.println(G.toString());

运行结果:


广义表求深度(针对再入表)的流程图如下:

数据结构之广义表_第7张图片

代码如下:

public int depth() {
		int temp = 0;
		int max = 0;
		GenNode p = this.head.getNext();
		for (; p != null; p = p.getNext(), temp = 0) {
			if (p.getChild() == null) {
				temp++;
			} else {
				temp = temp + 1 + (p.getChild()).depth();
			}

			if (max < temp) {
				max = temp;
			}

		}
		return max;
	}c

测试代码:

public class Main {

	/**
	 * @auther 冯利
	 * @version 创建时间:2018年5月25日  下午8:01:35
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		GenList L=new GenList();
		L.insert(1);
		L.insert(2);
		GenList T=new GenList();
		T.insert(3);
		T.insert(L);
		GenList G=new GenList();
		G.insert(4);
		G.insert(L);
		G.insert(T);
		//GenList Z=new GenList();
		//Z.insert(Z);
		//G.remove();
		System.out.println(G.toString());
		System.out.println(G.depth());
		System.out.println(L.toString());
		System.out.println(L.depth());
		System.out.println(T.toString());
		System.out.println(T.depth());
		//System.out.println(Z.toString());
		//System.out.println(Z.depth());
	}

运行结果:



GenList.java

package genList;

/**
 * 
 * @author 冯利
 * @version 创建时间:2018年5月24日 下午12:49:22
 * @param 
 *            原子结点类型
 */
public class GenList {
	// 头结点
	private GenNode head;

	// 表示广义表的大小(没有考虑深度)
	int count = 0;

	/**
	 * 初始化头结点
	 */
	public GenList() {
		head = new GenNode();
	}

	/**
	 * 判读广义表是否为空
	 * 
	 * @auther 冯利
	 * @version 创建时间:2018年5月24日 下午1:05:01
	 * @return
	 */
	boolean isEmpty() {
		if (head == null || head.next == null) {
			return true;
		}
		return false;
	}

	public int depth() {
		int temp = 0;
		int max = 0;
		GenNode p = this.head.getNext();
		for (; p != null; p = p.getNext(), temp = 0) {
			if (p.getChild() == null) {
				temp++;
			} else {
				temp = temp + 1 + (p.getChild()).depth();
			}

			if (max < temp) {
				max = temp;
			}

		}
		return max;
	}

	/**
	 * 求广义表的大小
	 * 
	 * @auther 冯利
	 * @version 创建时间:2018年5月24日 下午1:09:19
	 * @return
	 */
	int size() {
		return count;
	}

	/**
	 * 插入t作为广义表的第i个元素
	 * 
	 * @auther 冯利
	 * @version 创建时间:2018年5月24日 下午1:19:57
	 * @param i
	 * @param t
	 * @return
	 */
	int insert(int i, T t) {
		// 插入点位置大于广义表可插位置
		if (i > count) {
			return 0;
		}
		GenNode temp = head;
		for (int j = 0; j < i; ++j) {
			temp = temp.next;
		}
		GenNode n = new GenNode(t);
		n.setNext(temp.getNext());
		temp.setNext(n);
		++count;
		return 1;

	}

	public int insert(int i, GenList gl) {
		// 插入点位置大于广义表可插位置
		if (i > count) {
			return 0;
		}
		GenNode temp = head;
		for (int j = 0; j < i; ++j) {
			temp = temp.next;
		}
		GenNode n = new GenNode();
		n.setNext(temp.getNext());
		n.setChild(gl);
		temp.setNext(n);
		++count;
		return 1;

	}

	public void insert(GenList gl) {
		insert(count, gl);
	}

	public void insert(T t) {
		insert(count, t);
	}

	public String toString() {
		return this.toString("");
	}

	public String toString(String str) {
		str += "(";
		for (GenNode p = this.head.getNext(); p != null; p = p.getNext()) {
			if (p.getChild() == null) {
				str += p.getData().toString();
			} else {
				str += p.getChild().toString();
			}
			if (p.getNext() != null) {
				str += ",";
			}
		}
		return str + ")";
	}

	public int remove(int i) {
		// 插入点位置大于广义表可插位置
		if (i >= count) {
			return 0;
		}
		GenNode temp = head;
		for (int j = 0; j < i; ++j) {
			temp = temp.next;
		}
		temp.setNext(temp.getNext().getNext());
		--count;
		return 1;

	}

	public void remove() {
		remove(count - 1);
	}

	GenNode getElement(int i) {
		// 插入点位置大于广义表可插位置
		if (i >= count) {
			return null;
		}
		GenNode temp = head;
		for (int j = 0; j < i; ++j) {
			temp = temp.next;
		}
		return temp.getNext();

	}

	public void setElement(int i, T t) {
		// 插入点位置大于广义表可插位置
		if (i >= count) {
			return;
		}
		GenNode temp = head;
		for (int j = 0; j < i; ++j) {
			temp = temp.next;
		}
		GenNode n = new GenNode(t);
		n.setNext(temp.getNext().getNext());
		temp.setNext(n);
		return;

	}

	/**
	 * 
	 * @author 冯利
	 * @version 创建时间:2018年5月24日 下午12:49:37
	 * @param 
	 */
	class GenNode {
		private T data;
		private GenList child;
		private GenNode next;

		public GenNode() {
			data = null;
			child = null;
			next = null;
		}

		public GenNode(T t, GenList c, GenNode n) {
			data = t;
			child = c;
			next = n;
		}

		public GenNode(T t) {
			data = t;
			child = null;
			next = null;
		}

		public T getData() {
			return data;
		}

		public void setData(T data) {
			this.data = data;
		}

		public GenList getChild() {
			return child;
		}

		public void setChild(GenList child) {
			this.child = child;
		}

		public GenNode getNext() {
			return next;
		}

		public void setNext(GenNode next) {
			this.next = next;
		}

	}
}







你可能感兴趣的:(数据结构)