广义表的概念和基本实现(基于Java语言

广义表是一种复杂的数据结构,是线性表的拓展,可以表示树结构和图结构。广义表在文本处理,人工智能,计算机图形学中有着广泛的应用。

1.广义表的定义

广义表是n(n>=0)个数据元素a0, a1, a2, a3...an-1构成的有限序列。其中ai(0<=i<n)是原子或广义表,原子是不可分解的数据元素。广义表的元素个数n为广义表的长度。当n = 0,则该广义表为空表。广义表的深度为表中所含括号的层数。原子深度为0,长度为1.

2. 广义表的存储结构

广义表结点(tag标签域,data数据域, head表头域, tail表尾域)

Node(tag, data, head, tail)

其中表头,表尾的定义为:对于一个广义表(a0, a1, a2, ... an-1),其中a0(a0可能为原子或广义表),剩余的元素组成的子表为表尾。

3. 图例

(d,(a,b),(c,(a,b)))

4.代码

package testGenList;

import java.util.Stack;



public class GeneralizedTable<T> {

	public static final int TAG_ATOM = 0;//0表示原子结点
	public static final int TAG_TABLE = 1;//1表示子广义表结点
	
	private char LeftBracket = '(';
	private char RightBracket = ')';
	private Node<T> GenTable;

	public GeneralizedTable(){
		GenTable = new Node(Integer.valueOf(TAG_TABLE),null,null,null);
	}
	
	//使用广义表构造一个新的广义表
	public GeneralizedTable(GeneralizedTable src){
		if(src != null){
			GenTable = src.GenTable;
		}
	}
	
	//通过输入的字符串来构建广义表
	public GeneralizedTable(String genTable){
		if(genTable == null){
			throw new IllegalArgumentException("输入字符串不能为空");
		}
		initTable(genTable);
	}
	
	private void initTable(String genTable){
		String ts = genTable.replaceAll("\\s", "");
		//replaceAll方法的第一个参数是正则表达式,\\s表示去除字符串中的空格
		
		int len = ts.length();
		Stack<Character> BracketStack = new Stack<Character>();//存放字符串中的左右括号
		Stack<Node<T>> NodeStack = new Stack<Node<T>>();//存放新建的表结点
		
		initSymbolicCharacter(ts);//根据输入字符串的首字符确定括号类型
		GenTable = new Node<T>(TAG_TABLE,null,null,null);//构造广义表中的头结点,类型为表TAG_TABLE,初始值为空,两个指针为空
		
		Node<T> AtomNode = GenTable;
		Node<T> TableNode = GenTable;
		Node<T> tempNode = null;
		
		for(int i = 0;i<len;i++){
			if(ts.charAt(i) == LeftBracket){
				tempNode = new Node<T>(TAG_TABLE,null,null,null);//遇到一个左括号,就说明遇到一个广义表,需要新建一个结点起头。
				
				BracketStack.push(ts.charAt(i));
				
				if(BracketStack.size()>1){
					NodeStack.push(TableNode);//依次push header 之后所有的表结点
					TableNode.hp = tempNode;//下一层括号所代表的表结点定为tempNode,并将tempNode接在TableNode的尾指针上
					TableNode = TableNode.hp;
				}else{
					TableNode.tp = tempNode;//遇见第一个左括号,且括号栈内无其他左括号。则新建的TableNode为头结点,头结点的尾指针指向现在所处的结点tempNode
					TableNode = TableNode.tp;
				}
				
			}else if(ts.charAt(i)==RightBracket){
				if(BracketStack.isEmpty()){
					throw new IllegalArgumentException("括号栈中无左括号!");
				}
				if(BracketStack.size()>1){
					TableNode = NodeStack.pop();
				}
				BracketStack.pop();
			}else if(ts.charAt(i)==','){
				tempNode = new Node<T>(TAG_TABLE,null,null,null);
				TableNode.tp = tempNode;
				TableNode = TableNode.tp;
				
			}else{
				AtomNode = new Node(TAG_ATOM,ts.charAt(i),null,null);
				TableNode.hp = AtomNode;
			}
		}
		
	}
	
	private void initSymbolicCharacter(String ts){
		LeftBracket = ts.charAt(0);
		switch(LeftBracket){
		case '(':
			RightBracket = ')';
			break;
		case '{':
			RightBracket = '}';
			break;
		case '[':
			RightBracket = ']';
			break;
		default:
			throw new IllegalArgumentException("IllegalArgumentException----Bracket is not suitable");
		}
	}
	
	public void print(){
		print(GenTable);
	}
	
	private void print(Node<T> node){
		if(node == null){
			return;
		}
		if(node.tag == 0){
			System.out.print(node.data.toString()+"\t");
		}
		print(node.hp);
		print(node.tp);
	}
	
	public int depth(){
		if(GenTable == null){
			throw new NullPointerException("Generalized Table is null!");
		}else{
			return depth(GenTable);
		}
	}
	
	private int depth(Node<T> node){
		if(node == null || node.tag == TAG_ATOM){
			return 0;
		}
		int head = 0;//从第一个表头开始,向深处计数
		int tail = 0;//从第一个表尾开始,向深处计数
		head = 1 + depth(node.hp);
		tail = depth(node.tp);
		return head>tail ? head:tail;
	}
	
	public int depth1(){
		if(GenTable == null){
			throw new NullPointerException("广义表为空!");
		}
		return depth(GenTable);
	}
	
	public int length(){
		if(GenTable == null || GenTable.tp == null){
			return -1;
		}
		
		int len = 0;
		Node<T> temp = GenTable;
		while(temp.tp != null){
			temp = temp.tp;
			if(temp.hp == null && temp.tp == null){
				break;
			}
			len++;
		}
		return len;
	}
	
	
	public boolean isEmpty(){
		if(GenTable == null){
			return true;
		}
		Node<T> temp = GenTable.tp;
		return temp == null || temp.hp == null;
	}
	
	public GeneralizedTable getHeader(){
		if(isEmpty()){
			return null;
		}
		Node<T> temp = GenTable.tp;
		GeneralizedTable<T> gt = new GeneralizedTable<>();
		gt.GenTable.tp = temp.hp;
		return gt;
	}
	
	public GeneralizedTable<T> getTail(){
		if(isEmpty()){
			return null;
		}
		Node<T> temp = GenTable.tp;
		GeneralizedTable<T> gt = new GeneralizedTable<T>();
		gt.GenTable.tp = temp.tp;
		return gt;
	}
	
	public static void main(String[] args){
		String p = "(d,(a,b),(c,(a,b)))";
		GeneralizedTable gt1 = new GeneralizedTable(p);
		System.out.println("length: "+gt1.length());
		System.out.println("depth: "+gt1.depth1());
		System.out.println("第三个广义表的深度为:"+gt1.depth(gt1.GenTable.tp.tp.tp));
		gt1.print();
		System.out.println();
		gt1.getHeader().print();
		System.out.println();
		gt1.getTail().print();
	}
}

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值