廣義表(非線性結構)

廣義表

        廣義表是一種非線性的數據結構,是一種較爲簡單的數據結構,是線性表的擴展,是一個由n個元素組成的序列。實現廣義表主要是利用遞歸,將其分爲子問題來進行解決。下面是一些常見類型的廣義表:


1)A = ();          常稱爲“空表”

2)B = (a,b);          一般的廣義表

3)C = (a, b, (c, d))         具有子表的廣義表

4)D = (a, b, (c,(d)))        子表中有表的廣義表

5)E = ((),())         空表嵌套空表



      一般對於廣義表採取的存儲方式爲鏈式存儲,下面爲簡單的存儲圖示:


650) this.width=650;" width="691" height="260" title="無標題.png" style="width:690px;height:165px;" src="http://s3.51cto.com/wyfs02/M01/7F/2F/wKioL1cWFSOi9a1lAAAd6Nai4PM442.png" alt="wKioL1cWFSOi9a1lAAAd6Nai4PM442.png" />


       對於上面的一些常見類型的廣義表,應當如何對其進行創建和操作?常見對於廣義表會對其進行創建、求廣義表的大小(這裏指有值的節點)、求廣義表的深度等操作。


下面是對廣義表操作的具體程序代碼:

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



本文出自 “無心的執着” 博客,謝絕轉載!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章