#ifndef GLLIST_H
#define GLLIST_H
struct GLNode{
bool isNum;
union {
int data;
struct {
GLNode* hp,*tp;
};
};
};
class GLlist
{
private:
GLNode* pNode;
GLNode* init_GLNode(int);
GLNode* init_GLNode();
unsigned travel_depth(GLNode*);
void travel_input(GLNode**);
void travel_output(GLNode*);
GLlist(GLNode*);
void destory(GLNode*);
public:
GLlist();
~GLlist();
void input();
void output();
GLNode* getHead();
GLlist getTail();
unsigned depth();
unsigned length();
};
//all this definitions is just used to be a sign
#define PRIVATE
#define PUBLIC
#include "GLlist.h"
#include<iostream>
using namespace std;
PRIVATE GLNode* GLlist::init_GLNode(int element){
GLNode* temp=new GLNode;
temp->isNum=1;
temp->data=element;
return temp;
}
PRIVATE GLNode* GLlist::init_GLNode(){
GLNode* temp=new GLNode;
temp->isNum=0;
temp->hp=temp->tp=0;
return temp;
}
PRIVATE GLlist::GLlist(GLNode* p):pNode(p){}
PRIVATE unsigned GLlist::travel_depth(GLNode* p){
unsigned dep=1,max=1;
while(p!=0){
if(p->isNum==0&&p->hp!=0&&p->hp->isNum==0){
if((dep=travel_depth(p->hp)+1)>max)
max=dep;
}
p=p->tp;
}
return max;
}
PRIVATE void GLlist::destory(GLNode* p){
while(p!=0){
if(p->isNum==0&&p->hp!=0&&p->hp->isNum==1)
delete p->hp;
else if(p->isNum==0&&p->hp!=0&&p->hp->isNum==0)
destory(p->hp);
GLNode* temp;
temp=p;
p=p->tp;
delete temp;
}
}
PRIVATE void GLlist::travel_output(GLNode* p){
cout<<'(';
while(p!=0){
if(p->isNum==0&&p->hp!=0&&p->hp->isNum==0)
travel_output(p->hp);
else if(p->isNum==0&&p->hp!=0&&p->hp->isNum==1)
cout<<p->hp->data;
else
break;
if(p->tp!=0)
cout<<',';
p=p->tp;
}
cout<<')';
}
//TODO: reconstruct it!
//must use point**, because you will change the value of point
PRIVATE void GLlist::travel_input(GLNode** p){
char ch;
int data;
cin.get(ch);//skip the first '('
while(cin.get(ch)){
/*
*iterate the main GLlist,
*if there is a sub GLlist,
*then recurrent the function
*/
if(ch==',')//skip comma
continue;
switch(ch){//aumatic computability
case '('://create the sub GLlist
cin.putback(ch);
//you must putback '(',for you will skip it next
*p=init_GLNode();
(*p)->hp=init_GLNode();
travel_input(&(*p)->hp);
break;
//if ch is a num, just putback it to the input stream, then use cin
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
cin.putback(ch);
cin>>data;
*p=init_GLNode();
(*p)->hp=init_GLNode(data);
break;
case ')':
return;
}
p=&(*p)->tp;
}
}
PUBLIC GLlist::GLlist():pNode(0){}
PUBLIC GLlist::~GLlist(){
if(pNode!=0){
destory(pNode);
}
}
PUBLIC void GLlist::input(){
travel_input(&pNode);
if(pNode==0)
//if the input is "()",just give pNode an empty GLNode
//TODO: reconstruct it, it a poor idea
pNode=init_GLNode();
}
PUBLIC void GLlist::output(){
if(pNode==0)
cout<<"Not A GLlist!"<<endl;
travel_output(pNode);
}
PUBLIC GLNode* GLlist::getHead(){
if(pNode==0){
cerr<<"ERROR: empty GLlist!
";
return 0;
}
return pNode->hp;
}
PUBLIC GLlist GLlist::getTail(){
if(pNode==0){
cerr<<"ERROR: empty GLlist!
";
return 0;
}
GLlist temp;
temp.pNode=pNode->tp;
if(temp.pNode==0)
temp.pNode=init_GLNode();
return temp;
}
PUBLIC unsigned GLlist::depth(){
if(pNode==0){
cerr<<"ERROR: empty GLlist!
";
return 0;
}
return travel_depth(pNode);
}
PUBLIC unsigned GLlist::length(){
if(pNode==0){
cerr<<"ERROR: empty GLlist!
";
return 0;
}
GLNode* p=pNode;
unsigned count=0;
while(p!=0){
if(p->isNum==0&&p->hp!=0)
++count;
p=p->tp;
}
return count;
}