數據結構 廣義表

pre_define.h

//======================================
// pre_define.h
// 預定義函數返回結果頭文件
//======================================
#ifndef HEADER_PRE_DEFINE
#define HEADER_PRE_DEFINE

//函數結果狀態代碼
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2

//Status是函數的類型,其值是函數結果狀態代碼
typedef int Status;

//ElemType是元素類型
typedef int ElemType;

//ElemType是元素類型
typedef char AtomType;

//Boolean是布爾類型,其值是TRUE或FALSE
typedef int Boolean;

#endif
GList.cpp

#include "pre_define.h"
#include "SStrig.h"

typedef enum {ATOM, LIST} ElemTag;		// ATOM == 0:原子 LIST == 1:子表

typedef struct GLNode
{
	ElemType tag;
	union
	{
		AtomType atom;
		struct 
		{
			struct GLNode *hp, *tp;
		} ptr;
	};
}*GList;

void InitList(GList &L)
{
	L = NULL;
}

void CreateGList(GList &L, SString S)
{
	SString sub, hsub, emp;
	GList p, q;
	StrAssign(emp, '()');		/* 空串emp="()" */
	if (StrCompare(S, emp))		/* S="()" */
		L = NULL;				/* 創建空表 */
	else						/* S不是空串 */	
	{
		L = (GList)malloc(sizeof(GLNode));
		if (!L)
			exit(OVERFLOW);
		if (StrLength(S) == 1)	/* S爲單原子,只會出現在遞歸調用中 */
		{
			L->tag = ATOM;
			L->atom = S;
		}
		else					/* S爲表 */
		{
			L->tag = LIST;
			p = L;
			SubString(sub, S, 2, StrLength(S) - 2);		/* 脫外層括號(去掉第1個字符和最後1個字符)給串sub */
			do
			{
				/* 重複建n個子表 */
				sever(sub, hsub);
				CreateGList(p->ptr.hp, hsub);
				q = p;
				if (!StrEmpty(sub))		/* 表尾不空 */
				{
					p = (GList)malloc(sizeof(GLNode));
					if (!p) exit(OVERFLOW);
					p->tag = LIST;
					q->ptr.tp = p;
				}
			} while (!StrEmpty(sub));
			q->ptr.tp = NULL;
		}
	}
}

void sever(SString &str, SString &hstr)
{
	int n, i = 0, k = 0;
	char ch;
	n = StrLength(str);
	do
	{
		++i;
		SubString(ch, str, i, 1);
		if (ch == '(') ++k;
		else if (ch == ')') --k;
	} while (i < n && (ch != ',' || k != 0));
	if (i < n) 
	{
		SubString(hstr, str, 1, i - 1);
		SubString(str, str, i + 1, n - i);
	}
	else
	{
		StrCopy(hstr, str);
		ClearString(Str);
	}
}

void DestroyGList(GList &L)
{
	GList q1, q2;
	if (L)
	{
		q1 = L->ptr.hp;
		q2 = L->ptr.tp;
		DestroyGList(q1);
		DestroyGList(q2);
	}
	free(L);
	L =  NULL;
}

void CopyGList(GList &T, GList L)
{
	if (!L) T = NULL;		// 複製空表
	else
	{
		T = (GList)malloc(sizeof(GLNode));
		if (!T) exit(OVERFLOW);
		T->tag = L->tag;
		if (L->tag == ATOM)
			T->atom =L->atom;	/* 複製單原子 */
		else
		{
			CopyGList(T->ptr.hp, L->ptr.hp);
			CopyGList(T->ptr.tp, T->ptr.tp);
		}
	}
}

int GListLength(GList L)
{
	int len = 0;
	while (L)
	{
		L = L->ptr.tp;
		++len;
	}
	return len;
}

int GListDepth(GList L)
{
	int max, dep;
	GList pp;
	if (!L) return 1;
	if (L->tag == ATOM) return 0;
	for (max = 0, pp = L; pp; pp = pp->ptr.tp)
	{
		dep = GListDepth(pp->ptr.hp);
		if (dep > max) max = dep;
	}
	return max + 1;
}

Status GList(GList L)
{
	if (L)
		return TRUE;
	else
		return FALSE;
}

GList GetHead(GList L)
{
	GList h, p;
	if (!L)
		return NULL;
	p = L->ptr.hp;
	CopyGList(&h, p);
	return h;
}

GList GetTail(GList L)
{
	GList h, p;
	if (!L)
		return NULL;
	p = L->ptr.tp;
	CopyGList(&h, p);
	return h;
}

SString.cpp

#include "pre_define.h"
#include <string.h>
#include <ctype.h>
#include <malloc.h>
#include <stdlib.h>		/* atoi() */
#include <stdio.h>		/* EOF(=^Z或F6),NULL */
#include <limits.h>		/* INT_MAX等 */
#include <io.h>			/* eof() */
#include <process.h>

//串的定長順序表示
#define MAXSTRLEN 100

typedef unsigned char SString[MAXSTRLEN+1];			//0號單元存放串的長度

//生成一個其值等於chars的串T
Status StrAssign(SString &T , char *chars)
{
	int i;
	if(strlen(chars) > MAXSTRLEN) 
		return ERROR;
	else
	{
		T[0] = strlen(chars);
		for(i = 1 ; i <= T[0] ; i++)
			T[i] = *(chars+i-1);
		return OK;
	}
}

//由串S複製得串T
Status StrCopy(SString &T , SString S)
{
	int i;
	for(i = 0 ; i <= S[0] ; i++)
		T[i] = S[i];
	return OK;
}

//若S爲空串,則返回TRUE,否則返回FALSE
Status StrEmpty(SString S)
{
	if(S[0] == 0)
		return TRUE;
	else
		return FALSE;
}

//若S>T,則返回值>0;若S=T,則返回值=0;若S<T,則返回值<0
int StrCompare(SString S , SString T)
{
	int i;
	for(i = 1 ; i <= S[0] && i <= T[0] ; i++)
		if(S[i] != T[i]) 
			return S[i] - T[i];
	return S[0]-T[0];
}

//返回S的元素個數
int StrLength(SString S)
{
	return S[0];
}

//將S清爲空串
Status ClearString(SString &S)
{
	S[0] = 0;		//令串長爲0
	return OK;
}

//用T返回由S1和S2連接而成的新串
Status Concat(SString &T , SString S1 , SString S2)
{
	int i;
	if(S1[0]+S2[0] <= MAXSTRLEN)
	{	//未截斷
		T[0] = S1[0]+S2[0];
		for(i = 1 ; i <= S1[0] ; i++)
			T[i] = S1[i];
		for(i = 1 ; i <= S2[0] ; i++)
			T[i+S1[0]] = S2[i];
		return TRUE;
	}
	else
	{	//截斷S[2]
		for(i = 1 ; i <= S1[0] ; i++)
			T[i] = S1[i];
		for(i = 1 ; i <= (MAXSTRLEN-S1[0]) ; i++)
			T[i+S1[0]] = S2[i];
		T[0] = MAXSTRLEN;
		return OK;
	}
}

//用Sub返回串S的第pos個字符起長度爲len的子串
Status SubString(SString &Sub , SString S , int pos , int len)
{
	int i;
	if(pos < 1 || pos > S[0] || len < 0 || len > S[0]-pos+1)
		return ERROR;
	for(i = 1 ; i <= len ; i++)
		Sub[i] = S[i+pos-1];	//注意此處是S[i+pos-1],從第pos個字符
	Sub[0] = len;
	return OK;
}

//若主串S中存在和串T值相同的子串,則返回它在主串S中第pos個字符之後第一次出現的位置;否則函數值爲0
int Index(SString S , SString  T , int pos)
{
	int i , j;
	if(pos >= 1 || pos <= S[0])
	{
		i = pos;
		j = 1;
		while(i <= S[0] && j <= T[0])
		{
			if(S[i] == T[j])		//繼續比較後繼字符
			{
				++i;
				++j;
			}
			else					//指針後退重新開始匹配
			{
				i = i-j+2;
				j = 1;
			}
		}
		if(j > T[0])
			return i - T[0];
		else
			return 0;
	}
	else
		return 0;
}

void get_next(SSTring T , int next[])
{
	int i = 1 ; j = 0 ;
	next[1] = 0;
	while(i < T[0])
	{
		if(j == 0 || T[i] == T[j])
		{
			++i;
			++j;
			next[i] = j;
		}
		else
			j = next[j];
	}
}

void get_nextval(SString T , int next[])
{
	int i = 1 , j = 0;
	next[1] = 0;
	while(i < T[0])
	{
		if(j == 0 || T[i] == T[j])
		{
			++i;
			++j;
			if(T[i] != T[j]) next[i] = j;
			else next[i] = next[j];
		}
		else j = next[j];
	}
}
int Index_KMP(SString S , SString T , int pos)
{
	int i = pos , j = 1;
	while(i <= S[0] && j <= T[0])
	{
		if(j == 0 || S[i] == T[j]) {++i; ++j;}
		else j = next[j];
	}
	if(j > T[0]) return i - T[0];
	else return 0;
}

//在串S的第pos個字符之前插入串T
Status StrInsert(SString &S , int pos , SString T)
{
	int i;
	if(pos < 1 || pos > S[0]+1) return ERROR;
	if(S[0]+T[0] <= MAXSTRLEN)		//完全插入
	{
		for(i = S[0] ; i >= pos ; i--)
			S[i+T[0]] = S[i];
		for(i = pos ; i <= (pos+T[0]) ; i++)
			S[i] = T[i-pos+1];
		S[0] += T[0];
		return OK;
	}
	else		//部分插入
	{
		for(i = MAXSTRLEN ; i <= pos ; i--)
			S[i] = S[i-T[0]];
		for(i = pos ; i <= pos+T[0] ; i++)
			S[i] = T[i-pos+1];
		S[0] = MAXSTRLEN;
		return FALSE;
	}
}

//從串中刪除第pos個字符開始的長度爲len的字符
Status StrDelete(SString &S , int pos , int len)
{
	int i;
	if(pos < 1 || pos > S[0]-len+1 || len < 0) return ERROR;
	for(i = pos+len ; i <= S[0] ; i++)
		S[i-len] = S[i];
	S[0] -= len;
	return OK;
}

//用V替換主串S中出現的所有與T相等的不重疊的子串
Status Replace(SString &S , SString T , SString V)
{
	int i = 1;		//從串S的第一個字符起查找串T
	if(StrEmpty(T)) return ERROR;
	do
	{
		i = Index(S , T , i);		//結果i爲從上一個i之後找到的子串T的位置
		if(i)			//串S中存在串T
		{
			StrDelete(S , i , StrLength(T));		//刪除該串T
			StrInsert(S , i , V);					//在原串T的位置插入串V
			i += StrLength(V);						//在插入的串V後面繼續查找串T
		}
	}while(i);
	return OK;
}

//輸出字符串T。另加
 void StrPrint(SString T)
 {
   int i;
   for(i=1;i<=T[0];i++)
     printf("%c",T[i]);
   printf("\n");
 }



發佈了37 篇原創文章 · 獲贊 6 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章