精华内容
下载资源
问答
  • c++ 数据结构
    千次阅读
    2022-01-09 12:59:13

    图和有向图

    图形结构简称为图,属于复杂的非线性结构。元素称为顶点,每个顶点可以有多个或零个前驱顶点,也可以有多个或零个后驱顶点。是多对多的任意关系。这些顶点通过一系列边结对(连接)

    • 图,包括无向图和有向图;网,是指带权的图,包括无向网和有向网。

    • 树和链表可以看成一种特殊的图

    图的基本常识

    弧头和弧尾

    有向图中,无箭头一端的顶点通常被称为"初始点"或"弧尾",箭头直线的顶点被称为"终端点"或"弧头"。

    入度和出度

    对于有向图中的一个顶点 V 来说,箭头指向 V 的弧的数量为 V 的入度(InDegree,记为 ID(V));箭头远离 V 的弧的数量为 V 的出度(OutDegree,记为OD(V))。拿图 2 中的顶点 V1来说,该顶点的入度为 1,出度为 2(该顶点的度为 3)。

    (V1,V2) 和 <V1,V2> 的区别

    无向图中描述两顶点(V1 和 V2)之间的关系可以用 (V1,V2) 来表示,而有向图中描述从 V1 到 V2 的"单向"关系用 <V1,V2> 来表示。

    图的表示

    邻接矩阵

    唯一

    在邻接矩阵实现中,由行和列都表示顶点,由两个顶点所决定的矩阵对应元素表示这里两个顶点是否相连、如果相连这个值表示的是相连边的权重。例如,如果从顶点A到顶点B有一条权重为 5.6 的边,那么矩阵中第A行第B列的位置的元素值应该是5.6:

    邻接表

    不唯一

    在邻接列表实现中,每一个顶点会存储一个从它这里开始的边的列表。比如,如果顶点A 有一条边到B、C和D,那么A的列表中会有3条边,每一个顶点都有一个链表。

    边列表

    图的搜索

    给定顶点开始遍历

    深度优先DFS

    1.首先任意找一个未被遍历过的顶点,例如从 V1 开始,由于 V1 率先访问过了,所以,需要标记 V1 的状态为访问过;

    2.然后遍历 V1 的邻接点,例如访问 V2 ,并做标记,然后访问 V2 的邻接点,例如 V4 (做标记),然后 V8 ,然后 V5 ;

    3.当继续遍历 V5 的邻接点时,根据之前做的标记显示,所有邻接点都被访问过了。此时,从 V5 回退到 V8 ,看 V8 是否有未被访问过的邻接点,如果没有,继续回退到 V4 , V2 , V1 ;

    4.通过查看 V1 ,找到一个未被访问过的顶点 V3 ,继续遍历,然后访问 V3 邻接点 V6 ,然后 V7 ;

    5.由于 V7 没有未被访问的邻接点,所有回退到 V6 ,继续回退至 V3 ,最后到达 V1 ,发现没有未被访问的;

    6.最后一步需要判断是否所有顶点都被访问,如果还有没被访问的,以未被访问的顶点为第一个顶点,继续依照上边的方式进行遍历。

    深度优先搜索是一个不断回溯的过程。

      for (list<int>::iterator 
              it = myAdjacencyLists[i].adjacencyList.begin();
              it != myAdjacencyLists[i].adjacencyList.end(); it++)
          out << *it << "  ";
        out << endl;
      }
    

    广度优先

    还拿图 1 中的无向图为例,假设 V1 作为起始点,遍历其所有的邻接点 V2 和 V3 ,以 V2 为起始点,访问邻接点 V4 和 V5 ,以 V3 为起始点,访问邻接点 V6 、 V7 ,以 V4 为起始点访问 V8 ,以 V5 为起始点,由于 V5 所有的起始点已经全部被访问,所有直接略过, V6 和 V7 也是如此。 以 V1 为起始点的遍历过程结束后,判断图中是否还有未被访问的点。

    广度优先搜索的实现需要借助队列这一特殊数据结构

    生成树

    对连通图进行遍历,过程中所经过的边和顶点的组合可看做是一棵普通树,通常称为生成树。

    连通图中的生成树必须满足以下 2 个条件:

    包含连通图中所有的顶点;
    任意两顶点之间有且仅有一条通路;
    

    边的数量比顶点数量少一

    最小生成树

    • 必须只使用该网络中的边构造最小生成树;
    • 必须使用且仅使用 n-1 条边来联结网络中的 n 个顶点;
    • 不能使用产生回路的边。

    普利姆算法

    以点为出发点
    

    某顶点 u0 出发,选择与它关联的具有最小权值的边(u0, v),将其顶点加入到生成树的顶点集合U中

    克鲁斯卡尔算法

    以边为出发点
    

    在 E 中选到一条具有最小权值的边,若该边的两个顶点落在不同的连通分量上(即不形成回路),则将此边加入到 T 中;

    生成森林

    生成树是对应连通图来说,而生成森林是对应非连通图来说的。

    我们知道,非连通图可分解为多个连通分量,而每个连通分量又各自对应多个生成树(至少是 1 棵),因此与整个非连通图相对应的,是由多棵生成树组成的生成森林。

    存储结构

    数组

        存储图中各顶点本身数据,使用一维数组就足够了;存储顶点之间的关系时,要记录每个顶点和其它所有顶点之间的关系,所以需要使用二维数组(邻接矩阵)。
    

    链表

    邻接表

        邻接表存储图的实现方式是,给图中的各个顶点独自建立一个链表,用节点存储该顶点,用链表中其他节点存储各自的临界点。
    

    活动网络AOV

        **有向图**表示一个工程。用顶点表示事件,用有向边<Vi, Vj>表示活动。Vi 必须先于活动Vj 进行。这种有向图叫做AOV网络。入度为0的顶点称为**源点**,出度为0的顶点称为**汇点**
    

    • 对给定的AOV网络,必须先判断它是否存在有向环。
      • 检测有向环的一种方法,是对AOV网络构造其拓扑有序序列。将各个顶点 排成一个线性有序的序列,使得AOV网络中所有应存在的前驱和后继关系都能得到满足。

    关键路径:从源点到汇点的最长路径的长度,下图中的:1-2-5-7-9 即为一条关键路径,权值的和为18。

    最短路径

    [​​​​​​【图】最短路径--迪杰斯特拉(Dijkdtra)算法_菜鸟成长记-CSDN博客_最短路径

    更多相关内容
  • C++数据结构与算法 (第4版)
  • 内含有C++数据结构与算法 第四版(带目录)完整版和C++函数手册两样。
  • C++ 数据结构

    千次阅读 2022-01-28 09:15:27
    C++ 数据结构

    数据结构

            结构是一种可以存储不同类型的数据项的数据类型。

    定义结构

            使用 struct 语句定义结构。struct 语句定义了一个包含多个成员的新的数据类型,struct 语句的格式如下:

    struct book
    {
        char title[40];
        char author[40];
        float value;
        int book_id;
    }book;

    访问结构成员

            使用成员访问运算符 " . " 访问结构的成员。成员访问运算符是结构变量名称(book)和要访问的结构成员(value、title等)之间的一个句号。可以使用 struct 关键字来定义结构类型的变量。下面的实例演示了结构的用法:

    #define _CRT_SECURE_NO_WARNINGS
    #include <iostream>
    #include <cstring>
    
    using namespace std;
    
    struct book
    {
    	char title[50];//书名
    	char author[50];//作者
    	char subject[100];//学科
    	int book_id;//图书id
    };
    
    int main()
    {
    	struct book book1; // 声明 Book1,类型为 book
    	struct book book2; // 声明 Book2,类型为 book
    
    	// Book1 
    	strcpy(book1.title, "三国演义");//将 "三国演义"拷贝到book.title指向的位置
    	strcpy(book1.author, "罗贯中");
    	strcpy(book1.subject, "长篇小说");
    	book1.book_id = 000001;
    
    	// Book2 
    	strcpy(book2.title, "水浒传");
    	strcpy(book2.author, "施耐庵");
    	strcpy(book2.subject, "长篇小说");
    	book2.book_id = 000002;
    
    	// 输出 Book1 的信息
    	cout << "Book 1 title : " << book1.title << endl;
    	cout << "Book 1 author : " << book1.author << endl;
    	cout << "Book 1 subject : " << book1.subject << endl;
    	cout << "Book 1 id : " << book1.book_id << endl;
    
    	// 输出 Book2 的信息
    	cout << "Book 2 title : " << book2.title << endl;
    	cout << "Book 2 author : " << book2.author << endl;
    	cout << "Book 2 subject : " << book2.subject << endl;
    	cout << "Book 2 id : " << book2.book_id << endl;
    
    	return 0;
    }

            编译和执行上面的代码:

    Book title : 三国演义
    Book author : 罗贯中
    Book subject : 长篇小说
    Book id : 1
    Book title : 水浒传
    Book author : 施耐庵
    Book subject : 长篇小说
    Book id : 2

    C:\Users\ll\source\repos\Project1\Debug\Project1.exe (进程 14600)已退出,代码为 0。
    按任意键关闭此窗口. . .

    结构作为函数参数

            结构可以作为函数参数,传递参数的方式与其他类型的变量或指针类似。使用上面实例中的方式来访问结构变量:

    #define _CRT_SECURE_NO_WARNINGS
    #include <iostream>
    #include <cstring>
    
    using namespace std;
    
    void printBook(struct book book);//函数声明
    
    struct book      //结构声明
    {
    	char title[50];
    	char author[50];
    	char subject[100];
    	int book_id;
    };
    
    int main()
    {
    	struct book book1; // 声明 Book1,类型为 Book
    	struct book book2; // 声明 Book2,类型为 Book
    
    	// Book1 
    	strcpy(book1.title, "三国演义");
    	strcpy(book1.author, "罗贯中");
    	strcpy(book1.subject, "长篇小说");
    	book1.book_id = 000001;
    
    	// Book2 
    	strcpy(book2.title, "水浒传");
    	strcpy(book2.author, "施耐庵");
    	strcpy(book2.subject, "长篇小说");
    	book2.book_id = 000002;
    
    	printBook(book1); //把结构book1作为函数参数传递,输出 book1 的信息
    
    	printBook(book2); //把结构book2作为函数参数传递,输出 book2 的信息
    
    	return 0;
    }
    void printBook(struct book book)
    {
    	cout << "Book title : " << book.title << endl;
    	cout << "Book author : " << book.author << endl;
    	cout << "Book subject : " << book.subject << endl;
    	cout << "Book id : " << book.book_id << endl;
    }

            编译和执行上面的代码:

    Book title : 三国演义
    Book author : 罗贯中
    Book subject : 长篇小说
    Book id : 1
    Book title : 水浒传
    Book author : 施耐庵
    Book subject : 长篇小说
    Book id : 2

    C:\Users\ll\source\repos\Project1\Debug\Project1.exe (进程 13840)已退出,代码为 0。
    按任意键关闭此窗口. . .

     指向结构的指针

            定义指向结构的指针,方式与定义指向其他类型变量的指针相似,如下所示:

    struct Books * struct_pointer;

            在指针变量中存储结构变量(比如book1)的地址。如下所示:

    struct_pointer = &Book1;

           使用指向该结构的指针访问结构的成员,须使用 -> 运算符,如下所示:

    struct_pointer -> title;

           使用结构指针重写上面的实例:

    #define _CRT_SECURE_NO_WARNINGS
    #include <iostream>
    #include <cstring>
    
    using namespace std;
    void printBook(struct book * book);// 该函数以结构指针作为参数
    
    struct book
    {
    	char title[50];
    	char author[50];
    	char subject[100];
    	int book_id;
    };
    
    int main()
    {
    	struct book book1; // 声明 Book1,类型为 Book
    	struct book book2; // 声明 Book2,类型为 Book */
    
    	// Book1 
    	strcpy(book1.title, "三国演义");
    	strcpy(book1.author, "罗贯中");
    	strcpy(book1.subject, "长篇小说");
    	book1.book_id = 000001;
    
    	// Book2 
    	strcpy(book2.title, "水浒传");
    	strcpy(book2.author, "施耐庵");
    	strcpy(book2.subject, "长篇小说");
    	book2.book_id = 000002;
    
    	printBook(&book1);//把结构book1的地址作为函数参数传递,输出 book1 的信息
    
    	printBook(&book2);//把结构book2的地址作为函数参数传递,输出 book2 的信息
    
    	return 0;
    }
    
    void printBook(struct book * book)
    {
    	cout << "Book title : " << book->title << endl;
    	cout << "Book author : " << book->author << endl;
    	cout << "Book subject : " << book->subject << endl;
    	cout << "Book id : " << book->book_id << endl;
    }

             编译和执行上面的代码:

    Book title : 三国演义
    Book author : 罗贯中
    Book subject : 长篇小说
    Book id : 1
    Book title : 水浒传
    Book author : 施耐庵
    Book subject : 长篇小说
    Book id : 2

    C:\Users\ll\source\repos\Project1\Debug\Project1.exe (进程 11768)已退出,代码为 0。
    按任意键关闭此窗口. . .

    typedef 关键字

             使用关键字 “typedef ”可以为创建的结构类型另取一个"别名"。例如:

    typedef struct
    {
    	char title[50];
    	char author[50];
    	char subject[100];
    	int book_id;
    }GOODBOOK;

             现在,可以直接使用 GOODBOOK 来定义 book 类型的变量,而不需要使用 struct 关键字,例如:

    Books Book1, Book2;

    展开全文
  • <<C++数据结构>> C++数据结构原理与经典问题求解》是一部关于计算机科学与工程领域基础性核心课程——数据结构与算法的专著,本书《内容实用,体例新颖,结构清晰,既可以作为大、中专院校在校师生相关课程的参考...
  • c++数据结构总结(干货)

    万次阅读 多人点赞 2020-05-23 13:57:59
    C++数据结构实用干货!!看到就是赚到!

    作为一个程序员以及技术小白,掌握c++中的数据结构必不可少,本人长期混迹于CSDN,这里面有很多大佬,做的关于数据结构的总结特别深入详细。

    在这里总结了自己平时阅读过程中收藏的关于数据结构觉得很优秀的博文(总阅读量100W+),和大家一起学习进步!


    工欲善其事,必先利其器!(收藏一下,少走弯路)


    展开全文
  • 数据结构c++

    2018-10-17 21:03:30
    关于数据结构与算法的学习,里面介绍的基于c++的有关算法
  • C++数据结构与算法实验报告C++数据结构与算法实验报告C++数据结构与算法实验报告 代码在报告里面
  • C++数据结构与程序设计 中文版 钱丽萍版本,纸质书不是很多。 原版英文的很多,好不容易找到的中文版,扫描的。PDF格式。
  • C++数据结构原理与经典问题求解》是一部关于计算机科学与工程领域基础性核心课程——数据结构与算法的专著。全书以典型数据结构、程序设计方法及问题求解方法为研究对象,用C++面向对象程序设计语言作为描述语言,...
  • C++数据结构——栈

    万次阅读 多人点赞 2018-06-25 21:54:49
    C++数据结构——栈 最近计划再复习一遍数据结构,看到一篇博客:https://www.cnblogs.com/QG-whz/p/5170418.html#_label0。 1、栈(Stack)是一种线性存储结构,它具有如下特点: ...

                                                          C++数据结构——栈

     

                最近计划再复习一遍数据结构,看到一篇博客:https://www.cnblogs.com/QG-whz/p/5170418.html#_label0

    1、栈(Stack)是一种线性存储结构,它具有如下特点:

    (1)栈中的数据元素遵守“先进后出"(First In Last Out)的原则,简称FILO结构。(后进先出的叫法,也是可以的)

    (2)限定只能在栈顶进行插入和删除操作。

    2、栈的相关概念:

    (1)栈顶与栈底:允许元素插入与删除的一端称为栈顶,另一端称为栈底。

    (2)压栈:栈的插入操作,叫做进栈,也称压栈、入栈。

    (3)弹栈:栈的删除操作,也叫做出栈。

    3、栈的常用操作为:

    (1)弹栈,通常命名为pop

    (2)压栈,通常命名为push

    (3)求栈的大小

    (4)判断栈是否为空

    (5)获取栈顶元素的值

    4、栈的常见分类:

    (1)基于数组的栈——以数组为底层数据结构时,通常以数组头为栈底,数组头到数组尾为栈顶的生长方向

    (2)基于单链表的栈——以链表为底层的数据结构时,以链表头为栈顶,便于节点的插入与删除,压栈产生的新节点将一直出现在链表的头部

    5、实例分析

           使用标准库的栈时, 应包含相关头文件,在栈中应包含头文件: #include< stack > 。定义:stack< int > s;

    s.empty();         //如果栈为空则返回true, 否则返回false;
    s.size();          //返回栈中元素的个数
    s.top();           //返回栈顶元素, 但不删除该元素
    s.pop();           //弹出栈顶元素, 但不返回其值
    s.push();          //将元素压入栈顶

    (1)基于数组的栈

    #include <stack>
    #include <iostream>
    using namespace std;
    
    int main()
    {
    	stack<int> mystack;
    	int sum = 0;
    	for (int i = 0; i <= 10; i++){
    		mystack.push(i);
    	}
    	cout << "size is " << mystack.size() << endl;
    	while (!mystack.empty()){
    		cout << " " << mystack.top();
    		mystack.pop();
    	}
    	cout << endl;
    	system("pause");
    	return 0;
    }
    //size is 11
    // 10 9 8 7 6 5 4 3 2 1 0

    (2)基于单链表的栈

    #include <iostream>
    using namespace std;
    template<class T>class Stack
    {
    private:
    	struct Node
    	{
    		T data;
    		Node *next;
    	};
    	Node *head;
    	Node *p;
    	int length;
    
    public:
    	Stack()
    	{
    		head = NULL;
    		length = 0;
    	}
    	void push(T n)//入栈
    	{
    		Node *q = new Node;
    		q->data = n;
    		if (head == NULL)
    		{
    			q->next = head;
    			head = q;
    			p = q;
    		}
    		else
    		{
    			q->next = p;
    			p = q;
    		}
    		length++;
    	}
    
    	T pop()//出栈并且将出栈的元素返回
    	{
    		if (length <= 0)
    		{
    			abort();
    		}
    		Node *q;
    		T data;
    		q = p;
    		data = p->data;
    		p = p->next;
    		delete(q);
    		length--;
    		return data;
    	}
    	int size()//返回元素个数
    	{
    		return length;
    	}
    	T top()//返回栈顶元素
    	{
    		return p->data;
    	}
    	bool isEmpty()//判断栈是不是空的
    	{
    		if (length == 0)
    		{
    			return true;
    		}
    		else
    		{
    			return false;
    		}
    	}
    	void clear()//清空栈中的所有元素
    	{
    		while (length > 0)
    		{
    			pop();
    		}
    	}
    };
    int main()
    {
    	Stack<char> s;
    	s.push('a');
    	s.push('b');
    	s.push('c');
    	while (!s.isEmpty())
    	{
    		cout << s.pop() << endl;
    	}
    	system("pause");
    	return 0;
    }

     

    练习1、实现一个特殊的栈,在实现栈的基本功能的基础上,再实现返回栈中最小元素的操作。

              解法参考博客:https://blog.csdn.net/cherrydreamsover/article/details/79475925,具体过程如下:

    (1)使用两个栈,一个栈用来保存当前的元素,记做:stackData,一个栈用来保存压入操作每一步的最小元素,记做:stackMin

    (2)入栈:当stackData栈中压入一个数据时,判断satckMin中是否为空。若为空,将该元素压入stackMin栈中。若不空,判断两者之间的大小,当前者小于或等于后者时,将前者中的数据压入后者中;当前者大于后者时,

    不进行任何操作。

    (3)出栈:保证stackMin中栈顶的元素是stackData中最小的。

    #include<iostream>  
    #include <stack>  
    #include <cassert>  
    using  namespace std;
    
    //方法一:  一个辅助栈,如果这个栈为空,直接将元素入这个栈,如果辅助栈中有元素,将压入的元素和辅助栈顶元素比较,  
    //压入两者中较小的那个元素使得辅助栈总是维持栈顶元素为最小值。  
    //class Stack  
    //{  
    //public:  
    //  void Push(int data)  
    //  {  
    //      stackData.push(data);  
    //      if (stackMin.empty())  
    //      {  
    //          stackMin.push(data);  
    //      }  
    //      else  
    //      {  
    //          int tmp = stackMin.top();  
    //          int min = data > tmp ? tmp : data;  
    //          stackMin.push(min);  
    //      }  
    //  }  
    //  
    //  void Pop()  
    //  {  
    //      assert(!stackData.empty() && !stackMin.empty());  
    //      stackData.pop();  
    //      stackMin.pop();  
    //  }  
    //  
    //  int GetMin()  
    //  {  
    //      assert(!stackMin.empty());  
    //      return stackMin.top();  
    //  }  
    //  
    //private:  
    //  stack<int> stackData;  
    //  stack<int> stackMin;  
    //};  
    
    //方法二: 一个辅助栈,如果这个栈为空,直接将元素入这个栈,如果辅助栈中有元素,将压入的元素和辅助栈顶元素比较,  
    //如果压入的元素小于等于辅助栈顶元素,者将这个元素入辅助栈,否则无操作,出栈的时候判断要出栈的元素是否等于辅助  
    //栈顶元素,如果是,也将辅助栈顶元素出栈。否则无操作。  
    class Stack
    {
    public:
    	void Push(int data)
    	{
    		stackData.push(data);
    		if (stackMin.empty())
    		{
    			stackMin.push(data);
    		}
    		else
    		{
    			if (data <= stackMin.top())
    			{
    				stackMin.push(data);
    			}
    		}
    	}
    
    	void Pop()
    	{
    		assert(!stackData.empty() && !stackMin.empty());
    		if (stackData.top() == stackMin.top())
    		{
    			stackMin.pop();
    		}
    		stackData.pop();
    	}
    
    	int GetMin()
    	{
    		assert(!stackMin.empty());
    		return stackMin.top();
    	}
    
    private:
    	stack<int> stackData;
    	stack<int> stackMin;
    
    };
    
    
    int main()
    {
    	Stack s;
    	//s.Push(5);  
    	s.Push(36);
    	s.Push(15);
    	s.Push(95);
    	s.Push(50);
    	s.Push(53);
    	cout << s.GetMin() << endl;
    	system("pause");
    	return 0;
    }//15

    (3)栈的应用举例

    1)进制转换

    2)括号匹配的检验

    3)行编辑程序

    4)迷宫求解、汉诺塔等经典问题

    5)表达式求值

    6)栈与递归的实现

     

    练习2、剑指offer面试题30——包含min函数的栈

    题目描述

    定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数。
    class Solution {
    public:
        stack<int> stackData;//保存数据用的栈stackData
        stack<int> stackMin;//保存最小的数的栈stackMin,其中它的栈顶始终为最小的数
        void push(int value) {
            stackData.push(value);
            if(stackMin.empty()) 
                stackMin.push(value);//如果stackMin为空,则value是最小的值,入栈
            else{
                if(stackMin.top()>=value) 
                    stackMin.push(value);//否则当value小于等于stackMin的栈顶元素时,入栈(等于的时候也入栈是因为我考虑有相同的数)
            }
      }
      void pop() {
          if(stackData.top()==stackMin.top())//如果出栈的数刚好是最小的数,那么stackMin也应该出栈
            stackMin.pop();
          stackData.pop();
      }
      int top() {
        return stackData.top();//栈顶元素应返回stackData的栈顶元素
      }
      int min() {
        return stackMin.top();//stackMin的栈顶元素即是最小的数
      }
    };

    运行结果:

    练习3、剑指offer面试题31——栈的压入、弹出序列

           参考博客:https://blog.csdn.net/budf01/article/details/76232497,解题思路为:创建一个栈进行压入、弹出操作。具体操作如下: 
    (1)当栈为空或者栈顶元素和popV当前元素不相等时,将pushV当前元素压入; 
    (2)当栈顶元素与popV当前元素相等时,将栈顶元素弹出,并移至popV下一个元素; 
    (3)如果需要压入的元素个数大于pushV的元素个数,说明popV不可能是pushV的弹出序列。

    代码为:

    class Solution {
    public:
        bool IsPopOrder(vector<int> pushV,vector<int> popV) {
            //特殊输入测试
            if(pushV.empty() || popV.empty() || pushV.size()!=popV.size())
                return false;
            stack<int> mystack;//定义一个辅助栈
            int index=0;
            for(int i=0;i<popV.size();i++){
                //当辅助栈为空或者栈顶元素和popV当前元素不相等时,将pushV当前元素压入
                while(mystack.empty()||mystack.top()!=popV[i]){
                    if(index>=pushV.size())
                        //如果需要压入的元素个数大于pushV的元素个数,说明popV不可能是pushV的弹出序列
                        return false;
                    mystack.push(pushV[index++]);
                }
                //当栈顶元素与popV当前元素相等时,将栈顶元素弹出,并移至popV下一个元素
                if(mystack.top()==popV[i])
                    mystack.pop();
            }
            return true;
        }
    };

    运行结果:

     

     

    当然可以利用其他思想解决,如引入哈希或直接利用向量的方式求解。

    class Solution {
    public:
        bool IsPopOrder(vector<int> pushV,vector<int> popV) {
            if(pushV.empty() && popV.empty() && pushV.size() != popV.size()){
                return false;
            }
            map<int,int> Hash; //用map做一个映射,入栈顺序的值不一定是递增  
            for(int i=0;i<pushV.size();i++){
                Hash[pushV[i]]=i+1;
            }
            int now=Hash[popV[0]]; //当前最靠后入栈的键值,例如题目给的4 3 5 1 2,now先等于4,再等于5
            for(int i=0;i<popV.size();i++){
            //如果入栈序列中没有这个值
                if(Hash[popV[i]]==0){
                    return false;
                }
                if(Hash[popV[i]]>=now){
                now=Hash[popV[i]];
                }
                else if(Hash[popV[i]]<=Hash[popV[i-1]]){
                    continue ;
                }
                else{
                    return false;
                }
            }
            return true;
        }
    };

    练习4、简单的括号匹配判断

           例如,爱奇艺的一道实习在线编程题:当输入为()(())(),返回true;当输入为)()()()()),返回false,时间15min。(不能使用栈)

    1、假设可以使用栈(15min可以完成)

    C++代码:

    #include <iostream>
    #include <stack>
    #include <vector>
    using namespace std;
    
    bool isRight(vector<char> &vec){
    	stack<char> stack1;
    	bool index = false;
    	if (vec.size() <= 1 || vec[0]!='(' || vec.size()%2!=0){
    		return index;
    	}
    	for (int i = 0; i < vec.size(); i++){
    		if (vec[i] == '(')
    			stack1.push(vec[i]);
    		else if (vec[i] == ')')
    			stack1.pop();
    	}
    	if (stack1.empty())
    		index = true;
    	return index;
    }
    
    int main(){
    	//输入不定长的括号
    	vector<char> vec;
    	char tmpCh;
    	char t;
    	cout << "输入一串括号为:";
    	do{
    		cin >> tmpCh;
    		vec.push_back(tmpCh);
    	} while ((t = cin.get()) != '\n');
    
    	//调用isRight函数
    	bool myRes = isRight(vec);
    	cout << myRes << endl;
    	system("pause");
    	return 0;
    }

    运行结果:

    python代码:

    def isRight(str1):
        index = False
        tmp = []
        if(len(str1)>=2 and len(str1)%2==0 and str1[0]=='('):
            for id in range(len(str1)):
                if str1[id] == '(':
                    tmp.append(str1[id])
                else:
                    tmp.pop()
            if len(tmp)==0:
                index = True
        return index
    
    if __name__ == "__main__":
        try:
            while True:
                str1 = [i for i in input().split()]
                print(isRight(str1))  # 返回判断结果
        except:
            pass

    运行结果:

    2、不能使用栈(15min,不太好想,mad,笔试那会儿就没想到!)

           以下是我的想法,具体的过程如下:

          (1)由于不能使用栈,将左括号定义为数值1,右括号定义为数值-1,存放到向量id(C++)或列表tmp (Python)中;

          (2)初始化变量sum,用于判断总的求和结果是否等于0,若不等于0,则肯定不正确,若等于0,不一定正确;

          (3)循环遍历输入的括号向量vec,判断当前括号属性的同时,进行累加求和,如果求和值小于等于-1,break(跳出循环);

          (4)最后再检查sum是否等于0,此时若等于0,则为正确。

    C++代码:

    #include <iostream>
    #include <vector>
    using namespace std;
    
    bool isRight(vector<char> &vec){
    	vector<int> id(vec.size()); //用于存放左右括号的属性:左括号用1表示,右括号用-1表示
    	int sum = 0;
    	bool index = false;
    	if (vec.size() <= 1 || vec[0]!='(' || vec.size()%2!=0){
    		return index;
    	}
    	for (int i = 0; i < vec.size(); i++){
    		if (vec[i] == '('){
    			id.push_back(1);
    			sum = id[i] + sum;
    		}
    			
    		else if (vec[i] == ')'){
    			id.push_back(-1);
    			sum = id[i] + sum;
    			if (sum <= -1)
    				break;
    		}
    	}
    
    	if (sum == 0)
    		index = true;
    	return index;
    }
    
    int main(){
    	//输入不定长的括号
    	vector<char> vec;
    	char tmpCh;
    	char t;
    	cout << "输入一串括号为:";
    	do{
    		cin >> tmpCh;
    		vec.push_back(tmpCh);
    	} while ((t = cin.get()) != '\n');
    
    	//调用isRight函数
    	bool myRes = isRight(vec);
    	cout << myRes << endl;
    	system("pause");
    	return 0;
    }

    运行结果同上

    python代码:

    def isRight(str1):
        index = False
        sum = 0
        tmp = []
        if(len(str1)>=2 and len(str1)%2==0 and str1[0]=='('):
            for id in range(len(str1)):
                if str1[id] == '(':
                    tmp.append(1)
                    sum += tmp[id]
                else:
                    tmp.append(-1)
                    sum += tmp[id]
                    if sum<=-1:
                        break
            if sum == 0:
                index = True
        return index
    
    if __name__ == "__main__":
        try:
            while True:
                str1 = [i for i in input().split()]
                print(isRight(str1))  # 返回判断结果
        except:
            pass

    运行结果同上。

    展开全文
  • c++数据结构之树

    千次阅读 2021-09-22 09:46:02
    树的定义
  • c++数据结构与算法

    千次阅读 2019-07-08 17:05:24
    数组在程序设计语言中非常有用的数据结构。 数组的局限性: 编译期就必须知道数组的大小。 数组在计算机内存中是以相同的距离间隔开的。 链表较数组的优势在于插入一个数据,不需要移动其他数据。链表是节点的集合...
  • c++数据结构之栈

    千次阅读 2021-09-21 15:56:46
    栈(Stack)是由有限个数据类型相同元素组成的有序集合,对元素的操作只能在栈顶进行,遵循后进先出(Last In,First Out)的原则,其相关运算有创建空栈、判空、判满、入栈、出栈等。 二、栈的ADT 数据: 有限个...
  • C++数据结构——队列

    万次阅读 多人点赞 2018-06-26 22:20:30
    C++数据结构——队列参考博客:http://www.cnblogs.com/QG-whz/p/5171123.htmlhttp://www.169it.com/article/2718050585107790752.html1、队列(Queue)与栈一样,是一种线性存储结构,它具有如下特点:(1)队列中...
  • C++数据结构——链表

    千次阅读 2018-06-27 22:03:59
    C++数据结构——链表参考博客:(1)实践:https://www.cnblogs.com/renyuan/archive/2013/05/21/3091524.html(2)实践:https://blog.csdn.net/lg1259156776/article/details/47021505(3)理论:数据结构(二)...
  • C++数据结构与程序设计中文版及答案PDF格式
  • 严蔚敏c++数据结构c++严蔚敏c++数据结构严蔚敏c++数据结构c++严蔚敏c++数据结构严蔚敏c++数据结构c++严蔚敏c++数据结构
  • C++数据结构一元多项式 加减乘运算,有报告
  • c++数据结构——链表

    千次阅读 多人点赞 2021-06-06 21:43:53
    链表的定义:此处给出单链表的c++定义 struct ListNode { int val; // 节点上存储的元素 ListNode *next; // 指向下一个节点的指针 ListNode(int x) : val(x), next(NULL) {} // 节点的构造函数 }; 链表初始化...
  • C++数据结构书籍,包括: 1. 清华大学 严蔚敏 的数据结构(C++)版本 2. 清华大学 邓俊辉 的数据结构(C++)版本 二者结合,可以互相参照,全面学习C++数据结构相关知识。
  • 高清版,清华大学邓俊辉教授 C++数据结构版本。 高清版,清华大学邓俊辉教授 C++数据结构版本。
  • 冒泡排序 快速排序 直接插入排序 简单选择排序 希尔排序 堆排序算法等对正序随机数,逆序随机数,无序随机数进行排序,并统计关键词比较次数 记录移动次数的c++代码
  • c++数据结构

    2007-05-03 23:04:23
    关于c++数据结构的书 pdf
  • c/c++ 数据结构与算法

    千次阅读 多人点赞 2019-02-14 11:13:44
    参考;... 程序设计 = 数据结构 + 算法 1.数据结构 数据结构就是指一组数据的存储结构。算法就是操作数据的一组方法。... 因此,我们无法孤立数据结构来讲算法,也无法孤立算法来讲数据结构数据结构...
  • C++ 数据结构与算法

    千次阅读 2018-02-05 06:47:43
    数据结构分为逻辑结构和物理结构 四大逻辑结构: 集合结构,集合结构中的数据元素除了同属于一个集合外,他们之间没有其他不三不四的关系。 线性结构,线性结构中的数据元素之间是一对一的关系。 树形结构,树形...
  • 数据结构C++实现

    2014-07-10 20:42:27
    数据结构C++实现,包括邻接表和邻接矩阵两种实现方式以及各种常用图算法,共同继承于抽象类。
  • 在一个项目中,由于客户端与服务端程序各自采用编程平台有差别, ...但是由于客户端的框架代码基于原来Json格式,服务器则是C++数据结构格式, 两者都已经存在现成的框架代码,为了不做大的变动,...
  • c++数据结构实验指导书c++数据结构实验指导书c++数据结构实验指导书c++数据结构实验指导书
  • 这本《C++数据结构与算法(第4版)》全面系统地介绍了数据结构,并以C++语言实现相关的算法。 主要强调了数据结构和算法之间的联系,使用面向对象的方法介绍数据结构,其内容包括算法的复杂度分析、链表、栈、队列、...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 730,296
精华内容 292,118
关键字:

c++ 数据结构

c++ 订阅
数据结构 订阅