广义表是一种复杂的数据结构,是线性表的拓展,可以表示树结构和图结构。广义表在文本处理,人工智能,计算机图形学中有着广泛的应用。
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();
}
}