【数据结构】广义表

一、问题概述

广义表是非线性的数据结构,是由若干个元素组合而成的,广义表中可以有子表,类似这样的:



我们以C=(a,b,(c,d))为例,将它定义为这样的数据结构:


我们会给定字符串的形式,如:char * str = "(a,b,(c,d))";     然后将它转化为如上的数据结构。


二、解决办法

(1)将符号'('看作是头节点,然后将是数值的部分链入当前位置的下一个位置;

(2)当遇到SUB时,就链入它的_sublink(连接子表的指针),此时可用递归(子表相当于是表的子问题);

(3)直到str为空时,广义表的数据结构创建完成。


三、实现代码

//GeneralizedList.h

#pragma once 
#include<iostream>
using namespace std;
#include<assert.h>enum Type
{HEAD,VALUE,SUB,
};struct GeneralizeListNode
{Type _type;GeneralizeListNode* _next;union{char _value;GeneralizeListNode* _sublink;};GeneralizeListNode(Type type,char value = 0):_next(NULL),_type(type),_value(value){if(type == VALUE){_value = value;}if(type == SUB){_sublink = NULL;}}
};class GeneralizeList
{typedef GeneralizeListNode Node;
public:GeneralizeList():_head(NULL){}//构造函数GeneralizeList(const char* str){_head = Create(str);}//拷贝构造函数GeneralizeList(const GeneralizeList& g){_head = _Copy(g._head);}//赋值运算符重载(1)//GeneralizeList& operator=(const GeneralizeList& g)//{//	if(this != &g)//	{//		Node* tmp = _Copy(g._head);//		delete _head;//		_head = tmp;//	}//	return *this;//}//赋值运算符重载(2)GeneralizeList& operator=(const GeneralizeList& g){if(_head != g._head){GeneralizeList tmp(g);swap(_head,tmp._head);}return *this;}~GeneralizeList(){if(_head){_Destroy(_head);_head = NULL;}}void Print(){_Print(_head);cout<<endl;}public:Node* Create(const char*& str)            //创建表{assert(*str == '(');Node* head = new Node(HEAD);++str;Node* tail = head;while(*str){if((*str >= '0' && *str <= '9')||(*str >= 'a' && *str <= 'z')||(*str >= 'A' && *str <= 'Z')){tail->_next = new Node(VALUE,*str);tail = tail->_next;++str;}else if(*str == '('){tail->_next = new Node(SUB);tail = tail->_next;tail->_sublink = Create(str);++str;}else if(*str == ')'){++str;return head;}else{++str;}}return head;}void _Print(Node* head){assert(head);Node* cur = head;while(cur){if(cur->_type == HEAD){cout<<"(";}else if(cur->_type == VALUE){cout<<cur->_value;if(cur->_next != NULL){cout<<",";}}else if(cur->_type == SUB){_Print(cur->_sublink);if(cur->_next != NULL){cout<<",";}}else{assert(false);}cur = cur->_next;}cout<<")";}Node* _Copy(Node* head){Node* cur = head;Node* newHead = new Node(HEAD);Node* newTail = newHead;while(cur){if(cur->_type == HEAD){cur = cur->_next;}else if(cur->_type == VALUE){newTail->_next = new Node(VALUE,cur->_value);newTail = newTail->_next;cur = cur->_next;}else if(cur->_type == SUB){newTail->_next = new Node(SUB);newTail = newTail->_next;newTail->_sublink = _Copy(cur->_sublink);cur = cur->_next;}else{assert(false);}}return newHead;}void _Destroy(Node* head)       //销毁表{Node* cur = head;while(cur){if(cur->_type == HEAD || cur->_type == VALUE){Node* del = cur;cur = cur->_next;delete del;}else if(cur->_type == SUB){Node* del = cur;cur = cur->_next;_Destroy(del->_sublink);delete del;}else{assert(false);}}}size_t Size(){return _Size(_head);}size_t _Size(Node* head)              //元素个数{assert(head);size_t count = 0;Node* cur = head;while(cur){if(cur->_type == VALUE){++count;}else if(cur->_type == SUB){count += _Size(cur->_sublink);}cur = cur->_next;}return count;}size_t Depth(){return _Depth(_head);}size_t _Depth(Node* head)        //表的深度{Node* cur = head;size_t MaxDepth = 1;while(cur){if(cur->_type == SUB){size_t Depth = _Depth(cur->_sublink);if(Depth+1 > MaxDepth){MaxDepth = Depth+1;}}cur = cur->_next;}return MaxDepth;}
protected:Node* _head;
};void FunTest()
{char* str = "(a,b,(c,d),(e,(f),g))";GeneralizeList g1(str);g1.Print();GeneralizeList g2(g1);g2.Print();GeneralizeList g3;g3 = g1;g3.Print();cout<<g3.Size()<<endl;cout<<g3.Depth()<<endl;
}

//GeneralizedList.cpp

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
#include"GeneralizedList.h"
int main()
{FunTest();return 0;
}

四、运行结果





本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/382772.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【数据结构】普通二叉树的实现

一、问题概述 树是n个有限个数据的集合&#xff0c;形如&#xff1a; 它像不像倒着的树呢&#xff1f;我们把它看成是一种数据结构----树。它的第一个节点称作树的根&#xff0c;最底下的那些节点称作树的叶子。 我们今天所要研究的是二叉树&#xff0c;即父节点最多只有两个孩…

setitimer用法说明

函数原型&#xff1a; int setitimer(int which, const struct itimerval *new_value,struct itimerval *old_value) 函数作用&#xff1a; 可用来实现延时和定时的功能 头文件&#xff1a; #include <sys/time.h> 参数详解 用一把&#xff1a;一个例子 #include &…

哈希表(闭散列、拉链法--哈希桶)

哈希表&#xff0c;也称散列表&#xff0c;是一种通过key值来直接访问在内存中的存储的数据结构。它通过一个关键值的函数&#xff08;被称为散列函数&#xff09;将所需的数据映射到表中的位置来访问数据。 关于哈希表&#xff0c;主要为以下几个方面&#xff1a; 一、哈希表…

僵尸进程的产生和SIGCHLD信号

核心句子 子进程在终止时会给父进程发SIGCHLD信号,该信号的默认处理动作是忽略,父进程可以自 定义SIGCHLD信号的处理函数。 僵尸进程的产生&#xff1a; #include "head.h" #include <unistd.h> #include <signal.h>int main() {key_t key ftok(&quo…

海量数据处理--位图(BitMap)

对于海量数据这个词&#xff0c;大家不难理解吧。主要是针对给定的数据量特别大&#xff0c;占用内存特别大的情况。那么和位图有什么关系呢。看下面一个腾讯的海量数据的例子吧。 例&#xff1a;给40亿个不重复的无符号整数&#xff0c;没排过序。给一个无符号整数&#xff0…

ps命令与top命令参数意义详解

文章目录1.ps -l2.ps aux3.top面试经常被问道&#xff0c;特别是top。1.ps -l 参数解释F代表这个程序旗标 (process flags)&#xff0c;说明这个程序的总结权限&#xff0c;常见号码有&#xff1a;o 若为 4 表示此程序的权限为 root &#xff1b;o 若为 1 则表示此子程序仅进行…

哈希拓展--布隆过滤器

一、问题概述 布隆过滤器是由布隆提出来的&#xff0c;是由一个很长的二进制序列和一系列的映射函数组成。主要用于检测一个元素是否在一个集合中。当然在设计计算机软件时&#xff0c;我们也经常会判断一个元素是否在一个集合中。比如&#xff1a;在字处理软件中&#xff0c;…

排序(Sort)--【一】

排序&#xff0c;对于大家再熟悉不过了吧。我们之前在学习c语言的时候接触过的冒泡排序&#xff0c;选择排序等。今天给大家介绍两种新的排序。 1、直接插入排序 升序排列&#xff1a;将第一个数确定好&#xff0c;从下标为1的数开始插入&#xff0c;如果插入的数比前一个数大…

快速排序--全集

快速排序&#xff1a;一听名字就知道这种排序很快的&#xff0c;是吧&#xff1f;没错&#xff0c;它是一种效率比较高的排序算法。 快速排序采用的是分治的思想。 比如&#xff0c;将一串数中的一个元素作为基准&#xff0c;然后将比它小的数排在它的左边&#xff0c;比它大…

task_struct结构体查找

网上有很多解析task_struct结构体的文章&#xff0c;可是都没有说这个结构体到底在哪里&#xff1f; 这个结构体位于头文件 shced.h cd / find -name sched.h 显示结果如下 注意只有 位于内核中的include 才是正确的。 /usr/src/kernels/2.6.32-431.el6.i686/include/linux…

闹钟函数alarm()的解释与实践

alarm 定义 也称为闹钟函数&#xff0c;它可以在进程中设置一个定时器&#xff0c;当定时器指定的时间到时&#xff0c;它向进程发送SIGALRM信号。可以设置忽略或者不捕获此信号&#xff0c;如果采用默认方式其动作是终止调用该alarm函数的进程。 #include "head.h&quo…

Linux下如何设置权限让用户只删除自己的文件(粘滞位)

之前我们知道如何针对用户和用户组来设置文件权限。通常是用三个八进制来设置权限的&#xff0c;这里我要说的是&#xff0c;其实是由四个八进制表示的。其中第一个八进制我们通常是忽略的。第二个到第四个是对应于SUID,SGID,sticky-bit。 SUID&#xff1a;设置了SUID 位的文件…

Vim简单配置

vim配置&#xff1a; &#xff08;在Centos6.5下配置vim&#xff09; 1.找到用户的主工作目录&#xff0c;ls看是否有.vimrc文件&#xff0c;有的话打开即可。没有的话自己touch一个。vim进入.vimrc中&#xff1a; set nu 设置行数 colorscheme desert syntax enabl…

[WPS笔试题]实现栈的push,pop,max且时间复杂度为O(1)

今天做了一下WPS的笔试题&#xff0c;遇到了一道关于栈的题&#xff0c;觉得挺有意思的&#xff0c;就写篇博客分享一下吧~~ 题目要求&#xff1a;要求实现栈的数据结构&#xff0c;在该类型中实现一个能够得到栈的最大元素的max函数&#xff0c;在该栈中&#xff0c;调用max,…

[剑指Offer]替换空格

今天看题的时候&#xff0c;遇到一个替换空格的题目&#xff0c;分析一下哈。 题目要求&#xff1a;把字符串中的每个空格替换成“%20”。例如输入“we are happy”&#xff0c;则输出“we%20are%20happy”。 解题思路&#xff1a;我们首先想到的是&#xff1a;移位思想。遇到…

C语言关键字 ISO/ANSI C90 C99 C11

面试考点 https://blog.csdn.net/csdn_kou/article/details/81113215 * 有的常用的我们都不知道是关键字&#xff0c;比如sizeof.这是面试中的考点&#xff0c;要注意。 * 同时当回答C语言中有多少关键字时&#xff0c;要回答前题条件&#xff0c;时针对哪一个版本

关于sudo

之前&#xff0c;我们使用sudo的时候&#xff0c;是因为其用户本身具有root权限&#xff0c;所以可以sudo后执行相关操作&#xff0c;但是对于普通用户来说&#xff0c;它是既不具有sudo权限&#xff0c;又不在sudo用户组中&#xff0c;那么我们来研究一下如何将新创建的用户添…

Bash入门

Bash简介&#xff1a; Bash&#xff08;GNU Bourne-Again Shell&#xff09;是一个为GNU计划编写的Unix shell&#xff0c;它是许多Linux平台默认使用的shell。 shell是一个命令解释器&#xff0c;是介于操作系统内核与用户之间的一个绝缘层。准确地说&#xff0c;它也是能力…

线程之售票系统pthread_mutex,_lock,_unlock

先看一下这篇文章 https://blog.csdn.net/csdn_kou/article/details/81148268 四个人同时买票票&#xff0c;引出线程 #include "head.h" int ticket 100; void * route(void *arg) {char *id (char *)arg;while(1){if(ticket>0){usleep(1000);printf("…