廣義表
廣義表是一種非線性的數據結構,是一種較爲簡單的數據結構,是線性表的擴展,是一個由n個元素組成的序列。實現廣義表主要是利用遞歸,將其分爲子問題來進行解決。下面是一些常見類型的廣義表:
1)A = (); 常稱爲“空表”
2)B = (a,b); 一般的廣義表
3)C = (a, b, (c, d)) 具有子表的廣義表
4)D = (a, b, (c,(d))) 子表中有表的廣義表
5)E = ((),()) 空表嵌套空表
一般對於廣義表採取的存儲方式爲鏈式存儲,下面爲簡單的存儲圖示:
對於上面的一些常見類型的廣義表,應當如何對其進行創建和操作?常見對於廣義表會對其進行創建、求廣義表的大小(這裏指有值的節點)、求廣義表的深度等操作。
下面是對廣義表操作的具體程序代碼:
--GeneralList.h文件
#pragma once
#include <stdlib.h>
//遞歸實現廣義表
enum Type
{
HEAD, //頭節點
VALUE, //直節點
SUB, //有子表的點
};
struct GeneralListNode
{
Type _type;
GeneralListNode* _next; //指向同層下一個子節點
union
{
int _value;
GeneralListNode* _subLink; //指向子表的指針
};
GeneralListNode(Type type = HEAD, int value = 0); //構造節點
};
class GeneralList
{
public:
GeneralList(); //無參構造
GeneralList(const char* str); //有參構造
GeneralList(const GeneralList& List); //拷貝構造
GeneralList& operator=(const GeneralList& List); //賦值運算符重載
~GeneralList(); //析構函數
public:
bool _isValue(char ch); //判斷是否爲有效值
GeneralListNode* _CreateList(const char*& str); //創建廣義表
void print(); //打印
size_t size(); //求廣義表中有值節點個數
size_t Depth(); //求廣義表的深度
GeneralListNode* _copy(GeneralListNode* head); //廣義表的拷貝
protected:
void _print(GeneralListNode* head); //打印
size_t _size(GeneralListNode* head); //大小
size_t _depth(GeneralListNode* head); //深度
void Distroy(GeneralListNode* head); //刪除節點
protected:
GeneralListNode* _head;
};
--GeneralList.cpp文件
#include "GeneralList.h"
#include <stdlib.h>
#include <assert.h>
#include <iostream>
using namespace std;
GeneralListNode::GeneralListNode(Type type, int value) //構造節點
:_type(type)
, _next(NULL)
{
if (_type == VALUE) //若爲值節點
{
_value = value;
}
if (_type == SUB)
{
_subLink = NULL;
}
}
GeneralList::GeneralList()
:_head(NULL)
{ }
GeneralList::GeneralList(const char* str)
{
_head = _CreateList(str);
}
GeneralList::GeneralList(const GeneralList& List)
{
_head = _copy(List._head);
}
GeneralList& GeneralList::operator=(const GeneralList& List)
{
if (this != &List)
{
GeneralListNode* cur = _copy(List._head);
Distroy(_head);
_head = cur;
}
return *this;
}
GeneralList::~GeneralList()
{
Distroy(_head);
}
bool GeneralList::_isValue(char ch) //判斷值是否有效
{
if ((ch >= '0' && ch <= '9') ||
(ch >= 'a' && ch <= 'z') ||
(ch >= 'A' && ch <= 'Z'))
{
return true;
}
else
{
return false;
}
}
GeneralListNode* GeneralList::_CreateList(const char*& str) //創造廣義表
{
assert('('==*str);
++str; //將括號進行越過
GeneralListNode* head = new GeneralListNode(HEAD, 0);
GeneralListNode* cur = head;
while (*str)
{
if (_isValue(*str))
{
cur->_next = new GeneralListNode(VALUE, *str);
cur = cur->_next;
str++;
}
else
{
if (*str == '(') //表示子表開始
{
GeneralListNode* tail = new GeneralListNode(SUB, 0);
cur->_next = tail;
cur = cur->_next;
tail->_subLink = _CreateList(str);
}
else if (*str == ')') //表示子表結束
{
str++;
return head;
}
else
{
str++;
}
}
}
assert(false);
return head;
}
void GeneralList::print() //打印廣義表
{
_print(_head);
cout << endl;
}
size_t GeneralList::size() //廣義表大小
{
return _size(_head);
}
size_t GeneralList::Depth() //廣義表深度
{
return _depth(_head);
}
GeneralListNode* GeneralList::_copy(GeneralListNode* head) //廣義表的拷貝
{
GeneralListNode* cur = head;
GeneralListNode* newhead = new GeneralListNode(HEAD, 0);
GeneralListNode* ptr = newhead; //新建表的指針
while (cur)
{
if (cur->_type == VALUE)
{
ptr->_next = new GeneralListNode(VALUE, cur->_value);
ptr = ptr->_next;
}
else if (cur->_type == SUB)
{
ptr->_next = new GeneralListNode(SUB, 0);
ptr = ptr->_next;
ptr->_subLink = _copy(cur->_subLink);
}
cur = cur->_next;
}
return newhead;
}
void GeneralList::_print(GeneralListNode* head) //打印
{
GeneralListNode* cur = head;
while (cur)
{
if (cur->_type == HEAD)
{
cout << "(" ;
}
else if (cur->_type == VALUE)
{
cout << (char)cur->_value;
if (cur->_next)
{
cout << ",";
}
}
else if (cur->_type == SUB)
{
_print(cur->_subLink); //打印子表
if (cur->_next)
{
cout << ",";
}
}
cur = cur->_next;
}
cout << ")";
}
size_t GeneralList::_size(GeneralListNode* head) //大小(只計算值節點)
{
size_t size = 0;
GeneralListNode* cur = head;
while (cur)
{
if (cur->_type == VALUE)
{
size++;
}
else if (cur->_type == SUB)
{
size += _size(cur->_subLink);
}
cur = cur->_next;
}
return size;
}
size_t GeneralList::_depth(GeneralListNode* head) //深度
{
size_t deep = 1;
GeneralListNode* cur = head;
while (cur)
{
if (cur->_type == SUB) //若遇到有子表的節點,計算子表的深度,同時進行記錄,找出最大的深度
{
size_t pdepth = _depth(cur->_subLink);
if (pdepth + 1 > deep)
{
deep = pdepth + 1;
}
}
cur = cur->_next;
}
return deep;
}
void GeneralList::Distroy(GeneralListNode* head) //刪除所有節點
{
GeneralListNode* cur = head;
while (cur)
{
GeneralListNode* tmp = cur;
if (cur->_type == SUB) //若節點爲有子表的節點,則先遞歸刪除子表節點
{
Distroy(cur->_subLink);
}
cur = cur->_next;
delete tmp;
}
}
本文出自 “無心的執着” 博客,謝絕轉載!