C++实现广义表及其遍历

/*
 * 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;
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值