广义表是对线性表的扩展,在线性表中,表中元素具有原子性,不可分解。如果允许表中的元素具有某种结构,这就引入了广义表的概念。广义表的定义如下:
它是n(n>0)个数据元素a0,a1,……,an-1组成的有限序列,记为GList=(a0,a1,……,an-1),其中,ai(0<=i
语法图如下:
举个例子:
中国(北京,上海,江苏(南京,苏州),浙江(杭州))
结构:
广义表节点(data数据域,child子表地址域,next后继结点地址域)
举例:已知三个有名广义表
L(a,b)
T(c,L(a,b))
G(d,L(a,b),T(c,L(a,b)))
G的存储结构如下:
为什么需要头节点?便于在表头增加删除结点。如果不要头结点,那么对广义表的表头添加删除,将可能影响其他广义表中元素。比如,上面G的存储结构改为不要头结点的方式。如下:
如果此时通过G访问子表L并删除L中的第一个结点a后,G中L结点的child指向原a结点的后继结点b。而这样的删除并没有影响到T表中的L结点的child域。如下:
uml图如下:
说明:
head:广义表头结点
GenList
boolean depth():求广义表的深度
int insert(int i,T t):插入原子作为第i个元素,如果插入成功返回1,否则返回0
int insert(int i,GenList
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
GenNode
GenNode
GenNode
广义表的遍历(注意以下的广义表的遍历和求深度的方法都是针对再入表的,不适用于递归表,不信你试试!),采用的是递归的方法,其流程图如下:
代码如下:
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());
运行结果:
广义表求深度(针对再入表)的流程图如下:
代码如下:
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;
}
}
}