数据结构之用C++实现广义表

  广义表,相对于链表较复杂,相对于树又较简单....用来过渡顺序表和树是非常好的选择.

  废话不多说,一言不合就贴代码.

/*
*文件说明:广义表相关声明及定义
*作者:高小调
*日期:2016-12-12
*集成开发环境:Microsoft Visual Studio 2010 
*/
#ifndef __GENERALLIST_H__
#define __GENERALLIST_H__
#include<assert.h>
enum Type{
	HEAD,
	SUB,
	VALUE
};
struct GeneralListNode{
	Type type;
	union{
		char value;
		GeneralListNode *sublink;
	};
	GeneralListNode *next;
	GeneralListNode(Type t,const char v = 0)
		:type(t)
		,next(0){
			if(t == HEAD || t ==VALUE){
				value = v;
			}else if(t == SUB){
				sublink = 0;
			}else {
				assert(false);	
			}
	}
};

class GeneralList{
typedef GeneralListNode Node;
public:
	//构造函数
	GeneralList(const char *s){
		_head = _CreateList(s);
	}
	//拷贝构造
	GeneralList(const GeneralList &g){
		_head = _Copy(g._head);
	}
	//赋值运算符重载
	GeneralList &operator=(const GeneralList &g){
		if(_head!=g._head){		//不是自己给自己赋值
			GeneralList temp(g);
			swap(_head,temp._head);
		}
	}
	//析构函数
	~GeneralList(){
		if(_head!=NULL){
			_Destory(_head);
			_head = NULL;
		}
	}
public:
	//打印广义表
	void Print(){
		_Print(_head);
		cout<<endl;
	}
	//广义表数据个数
	size_t Size(){
		return _Size(_head);
	}
	//广义表深度
	size_t Depth(){
		return _Depth(_head);
	}
protected:
	//拷贝广义表
	Node * _Copy(Node* head){
		Node *NewHead = new Node(HEAD);
		Node *Tail = NewHead;
		Node *cur = head;
		while(cur){
			if(cur->type == VALUE){							//数据节点
				Tail->next = new Node(VALUE,cur->value);	//创建新节点,添加至尾节点
				Tail = Tail->next;							//尾节点后移
				cur = cur->next;							//被拷贝节点后移
			}else if(cur->type == SUB){						//子表节点
				Node *NewSub = new Node(SUB);				//创建新子表节点
				Tail->next = NewSub;						//添加至尾节点
				Tail = Tail->next;							//尾节点后移
				NewSub->sublink = _Copy(cur->sublink);		//递归拷贝子节点
				cur = cur->next;							//被拷贝节点后移
			}else if(cur->type == HEAD){					//头节点
				cur = cur->next;							//被拷贝节点后移
			}else{
				assert(false);			//出错!
			}
		}
		return NewHead;
	}
	//交换
	void _Swap(Node* &l,Node *&r){
		Node *tmp = l;
		l = r;
		r = tmp;
	}
	//销毁
	void _Destory(Node *head){
		Node *cur = head;
		while(cur){
			if((cur->type == VALUE)	
				||(cur->type == HEAD)){		//当前节点为头节点或数据节点
				Node *del = cur;			//保存当前节点
				cur = cur->next;			//当前节点后移
				delete del;					//删除节点
			}else if(cur->type == SUB){		//当前节点为子表
				Node * del = cur;			//保存当前节点
				cur = cur->next;			//当前节点后移
				_Destory(del->sublink);		//递归销毁子表里的数据	
				delete del;					//销毁子表
			}else{
				assert(false);				//程序运行出错!
			}
			
		}
	}
	//判断是否为数据
	bool _IsValue(const char s){
		if((s>='0'&&s<='9')
			||(s>='a'&&s<='z')
			||(s>='A'&&s<='Z')){
			return true;
		}
		return false;
	}
	//递归创建广义表
	Node *_CreateList(const char * &s){
		assert(*s=='(');						//断言字符串s第一个字符是(
		++s;									//跳过(进入数据部分
		Node *head = new Node(HEAD);			//创建头节点
		Node *Tail = head;						//作为尾节点,来插入新数据
		while(*s){
			if(_IsValue(*s)){						//数据项
				Tail->next = new Node(VALUE,*s);	//创建数据节点
				Tail = Tail->next;					//尾节点后移
				++s;
			}else if(*s == '('){				//子表项
				Node *NewNode = new Node(SUB);	//创建子表节点
				Tail->next = NewNode;			//插入尾部
				Tail = Tail->next;				//尾部后移
				NewNode->sublink = _CreateList(s);	//递归创建子表数据节点
			}else if(*s ==')'){						//数据结束
				++s;
				return head;						//返回头节点
			}else{
				++s;								//遇到逗号跳过
			}
		}
		return head;
	}
	//递归打印广义表
	void _Print(Node *head){
		Node * cur = head;
		while(cur){
			if(cur->type == HEAD){			//头节点
				cout<<"(";
			}else if(cur->type == VALUE){	//值节点
				cout<<cur->value;
				if(cur->next!=NULL){		//不是最后一个元素
					cout<<",";				//以逗号分隔
				}
			}else if(cur->type == SUB){		//子表项
				_Print(cur->sublink);		//递归打印子表
				if(cur->next!=NULL){		//不是最后一项数据
					cout<<",";				//以逗号分隔
				}
			}else{
				assert(false);
			}
			cur = cur->next;
		}
		cout<<")";
	}
	//递归获取广义表数据个数
	size_t _Size(Node *head){
		Node *cur = head;
		size_t ret = 0;
		while(cur){
			if(cur->type ==VALUE){			//当前为值节点
				++ret;						//数据个数+1
			}else if(cur->type ==SUB){
				ret += _Size(cur->sublink);	//递归求取子表数据个数
			}else{
				//头节点
			}
			cur = cur->next;
		}
		return ret;
	}
	//递归求广义表深度
	size_t _Depth(Node *head){
		Node *cur = head;
		size_t MaxDepth = 1;						//当前深度为1
		while(cur){
			if(cur->type == SUB){					//遇到子表
				size_t Depth = _Depth(cur->sublink);//递归求子表深度
				if(MaxDepth<Depth+1){				//如果子表深入大于当前值
					MaxDepth = Depth+1;				//更新最大深入
				}
			}
			cur = cur->next;
		}
		return MaxDepth;							//返回最大深度
	}
private:
	Node * _head;
};
#endif

  

/*
*文件说明:测试文件
*作者:高小调
*日期:2016-12-12
*集成开发环境:Microsoft Visual Studio 2010 
*/
#include<iostream>
using namespace std;
#include"GeneralList.h"
void GeneralListTest(){
	const char * const str1 = "(a)"; 
	GeneralList g1(str1);
	g1.Print();
	cout<<"Size = "<<g1.Size()<<endl;
	cout<<"Depth = "<<g1.Depth()<<endl;

	const char * const str2 = "(a,b)"; 
	GeneralList g2(str2);
	g2.Print();
	cout<<"Size = "<<g2.Size()<<endl;
	cout<<"Depth = "<<g2.Depth()<<endl;

	const char * const str3 = "(a,b,(c,d))"; 
	GeneralList g3(str3);
	g3.Print();
	cout<<"Size = "<<g3.Size()<<endl;
	cout<<"Depth = "<<g3.Depth()<<endl;
	
	const char * const str4 = "((e,(f),h))"; 
	GeneralList g4(str4);
	g4.Print();
	cout<<"Size = "<<g4.Size()<<endl;
	cout<<"Depth = "<<g4.Depth()<<endl;

	const char * const str5 = "(((1,2)),((3,4)))";
	GeneralList g5(str5);
	g5.Print();
	cout<<"Size = "<<g5.Size()<<endl;
	cout<<"Depth = "<<g5.Depth()<<endl;

	cout<<"////////拷贝构造//////"<<endl<<endl;
	//(a)
	GeneralList g6(g1);
	g6.Print();
	cout<<"Size = "<<g6.Size()<<endl;
	cout<<"Depth = "<<g6.Depth()<<endl;
	//(a,b)
	GeneralList g7(g2);
	g7.Print();
	cout<<"Size = "<<g7.Size()<<endl;
	cout<<"Depth = "<<g7.Depth()<<endl;

	//(a,b,(c,d))
	GeneralList g8(g3);
	g8.Print();
	cout<<"Size = "<<g8.Size()<<endl;
	cout<<"Depth = "<<g8.Depth()<<endl;

	GeneralList g9(g4);
	g9.Print();
	cout<<"Size = "<<g9.Size()<<endl;
	cout<<"Depth = "<<g9.Depth()<<endl;

	GeneralList g10(g5);
	g10.Print();
	cout<<"Size = "<<g10.Size()<<endl;
	cout<<"Depth = "<<g10.Depth()<<endl;
}
int main(){
	GeneralListTest();
	return 0;
}

  总结:

  第一次接触这个,还确实有点难办,写得我脑袋都透支了,还专门打了几把LOL休息了一下....

  这个东西并不是有多难,仅仅是因为递归程序,极其难于调试.当程序出问题时,调试比较让人抓狂!

  还有一点就是,个人太钻牛角尖.有时候及时接受别人的知识,然后纳入自己的知识体系,比自己死磕要快得多....

posted @ 2016-12-12 17:49  数据结构专题  阅读(953)  评论(0编辑  收藏  举报