/*
* GList.h
*
* Created on: Oct 19, 2015
* Author: chris
*/
#ifndef GLIST_H_
#define GLIST_H_
#include<iostream>
typedef int AtomType;
enum ElemTag{ATOM, LIST};
struct GLNode{
ElemTag tag;
union{
AtomType atom;
GLNode * subL;
};
GLNode * next;
GLNode(ElemTag _tag = ATOM):
tag(_tag), next(NULL) {}
};
typedef GLNode * GList;
bool GListCreate(GList & L);
void GListDestroy(GList & L);
bool GListCopy(GList & from, GList & to);
int GListLength(GList & L);
bool GListEmpty(GList & L);
int GListDepth(GList & L);
bool GListInsertAtomAt(GList & L, int pos, AtomType a);
bool GListInsertSubLAt(GList & L, int pos);
bool GListGetAtomAt(GList & L, int pos, AtomType & a);
bool GListGetSubLAt(GList & L, int pos, GList & subL);
bool GListTraverse(GList & L, bool (*visit)(AtomType &));
void GListWalkThrough(GList &L);
#endif /* GLIST_H_ */
/*
* GList.cpp
*
* Created on: Oct 19, 2015
* Author: chris
*/
#include"GList.h"
#include<iostream>
using namespace std;
bool GListCreate(GList & L)
{
if(L != NULL) delete L;
L = new GLNode;
if(!L) return false;
return true;
}
void GListDestroy(GList & L)
{
GLNode * pcur = NULL;
while(L) {
// detach.
pcur = L;
L = L->next;
if(pcur->tag == LIST)
GListDestroy(pcur->subL);
delete pcur;
}//endw
}
bool GListCopy(GList & from, GList & to)
{
if(to != NULL) delete to;
to = new GLNode;
if(!to) return false;
GLNode * pto = to;
GLNode * pfrom = from->next;
bool failed = false;
while(pfrom) {
GLNode * pcur = NULL;
if(pfrom->tag == LIST) {
pcur = new GLNode(LIST);
if(!pcur || !GListCopy(pfrom->subL, pcur->subL)) {
delete pcur;
failed = true;
break;
}
}
else if(pfrom->tag == ATOM) {
pcur = new GLNode(ATOM);
if(!pcur) {
failed = true;
break;
}//endif
pcur->atom = pfrom->atom;
}//endif
//success.
pto->next = pcur;
pto = pcur;
pfrom = pfrom->next;
}// endw
if(failed) {
GListDestroy(to);
return false;
}
return true;
}
int GListLength(GList & L)
{
GLNode * pcur = L->next;
int cnt = 0;
while(pcur) {
++cnt;
pcur = pcur->next;
}
return cnt;
}
bool GListEmpty(GList & L)
{
return L->next == NULL;
}
int GListDepth(GList & L)
{
GLNode * pcur = L->next;
int mxdepth = 1;
while(pcur) {
int dep = 1;
if(pcur->tag == LIST)
dep = 1 + GListDepth(pcur->subL);
if(mxdepth < dep)
mxdepth = dep;
pcur = pcur->next;
}
return mxdepth;
}
bool GListInsertAtomAt(GList & L, int pos, AtomType a)
{
if(pos < 0) return false;
GLNode *prior = L;
int i = 0;
while(prior && i != pos) {
prior = prior->next;
++i;
}
if(!prior) return false;
GLNode * pcur = new GLNode(ATOM);
if(!pcur) return false;
pcur->atom = a;
pcur->next = prior->next;
prior->next = pcur;
return true;
}
bool GListInsertSubLAt(GList & L, int pos)
{
if(pos < 0) return false;
GLNode * prior = L;
int i = 0;
while(prior && i != pos) {
prior = prior->next;
++i;
}
if(!prior) return false;
GLNode * pcur = new GLNode(LIST);
if(!pcur) return false;
pcur->subL = NULL;
if(!GListCreate(pcur->subL)) {
delete pcur;
return false;
}
pcur->next = prior->next;
prior->next = pcur;
return true;
}
bool GListGetAtomAt(GList & L, int pos, AtomType& a)
{
if(pos < 0) return false;
GLNode *pcur = L->next;
int i = 0;
while(pcur && i != pos) {
pcur = pcur->next;
++i;
}
if(!pcur || pcur->tag != ATOM) return false;
a = pcur->atom;
return true;
}
bool GListGetSubLAt(GList & L, int pos, GList& subL)
{
if(pos < 0) return false;
GLNode *pcur = L->next;
int i = 0;
while(pcur && i != pos) {
pcur = pcur->next;
++i;
}
if(!pcur || pcur->tag != LIST) return false;
subL = pcur->subL;
return true;
}
bool GListTraverse(GList & L, bool (*visit)(AtomType &))
{
GLNode * pcur = L->next;
while(pcur) {
if(pcur->tag == ATOM) {
if(!visit(pcur->atom))
return false;
}
else if(pcur->tag == LIST) {
if(!GListTraverse(pcur->subL, visit))
return false;
}
pcur = pcur->next;
}//endw.
return true;
}
void GListWalkThrough(GList &L)
{
if(L == NULL) {
cout << "NULL" << endl;
return;
}
static int depth = 0;
++depth;
GLNode *pcur = L;
int ord = -1;
while(true) {
cout << "Depth: " << depth << "; Now: " << pcur << "; Order: " << ord << endl;
if(pcur->tag == LIST) {
cout << "Type: LIST" << endl;
} else if(pcur->tag == ATOM){
cout << "Type: ATOM; Data: " << pcur->atom << endl;
}
int ans = 0;
do{
cout << "1. to pre-head; 2. to next; 3. deepen; 4. back; 5.InsertAtom 6.InsertList" << endl;
cin >> ans;
if(1 <= ans && ans <= 6)
break;
}while(true);
if(ans == 1) {
pcur = L;
ord = -1;
}
else if(ans == 2) {
if(pcur->next) {
pcur = pcur->next;
++ord;
}
else
cout << "failed" << endl;
}
else if(ans == 3) {
if(pcur->tag == LIST)
GListWalkThrough(pcur->subL);
else
cout << "failed" << endl;
}
else if(ans == 4) {
break;
}
else if(ans == 5) {
int pos = 0;
AtomType a;
cout << "pos: "; cout.flush(); cin >> pos;
cout << "atom: "; cout.flush(); cin >> a;
if(!GListInsertAtomAt(L, pos, a))
cout << "failed" << endl;
else {
pcur = L;
ord = -1;
}
}
else if(ans == 6) {
int pos = 0;
cout << "pos: "; cin >> pos;
if(!GListInsertSubLAt(L, pos))
cout << "failed" << endl;
else {
pcur = L;
ord = -1;
}
}
}//endw.
--depth;
}
/*
* Main.cpp
*
* Created on: Oct 19, 2015
* Author: chris
*/
#include<iostream>
#include"GList.h"
using namespace std;
int main(void)
{
GList L = NULL;
GListCreate(L);
GListWalkThrough(L);
cout << "Depth: " << GListDepth(L) << endl;
GListDestroy(L);
system("pause");
return 0;
}