数据结构——线性结构总结

  • 数据结构——线性结构总结

    • 写在前面
    • 线性结构的特点
    • 线性表
    • 队列
    • 相关的STL容器的基本操作
      • vector
      • list
      • stack
      • queue
      • deque
    • 习题
      • 线性表相关——一元多项式的加法和乘法
      • 线性表相关——链表的反转
      • 栈相关——栈的混洗&栈的模拟
    • Reference

写在前面

数据元素的存储(顺序存储和链式存储)和数据元素的操作(插入和删除)是数据结构的重要部分。
数据结构中的线性结构可分为线性表,栈和队列。对于这三种结构,有两种存储方式顺序存储和链式存储以两种主要操作,插入和删除。不同线性结构的插入和删除操作的方式不同,而且不同存储方式在插入和删除的效率上也有所不同。本文就这三种结构x两种存储x两种操作来进行总结,并附上几道相关习题。


线性结构的特点

线性结构的特点是:在数据元素的非空有限集中,
(1)存在惟一的一个被称作“第一个”的数据元素和惟一的一个被称作“最后一个”的数据元素;
(2)除第一个之外,集合中的每个数据元素均只有一个前驱;除最后一个之外,集合中的每一个数据元素均只有一个后继。

线性表

线性表简单来说就是数据元素的非空有限序列,其特点是可以从表中的任何位置进行插入([0 , n])和删除([0 , n-1])操作。本文利用C++实现了线性表的初始化,查找,插入和删除操作,直接附代码如下:

  • 顺序存储
#define MAX_SIZE 100
typedef int ElementType;
typedef struct sqlist{ElementType *elem;  //存储空间的基地址int length;      //当前长度int listsize;     //当前存储空间的大小
}Sqlist;
int init(Sqlist &L) // 初始化
{L.elem = (ElementType*)malloc(MAX_SIZE*sizeof(ElementType));if(!L.elem) exit(0);L.length=0;L.listsize = MAX_SIZE;return 1;
}
int inser(Sqlist &L, int i, ElementType e) //插入操作
{//i的合法值是[0,length]//i的意思表示在第i个位置之前插入新元素,i=length时表示在list末尾插入新元素if(i<0||i>L.length)return 0;if(L.listsize<=L.length){ElementType *newbase = (ElementType*)realloc(L.elem,((MAX_SIZE+L.listsize)*sizeof(ElementType)));if(!newbase)exit(0);L.elem = newbase;L.listsize +=MAX_SIZE;}for(int j=L.length;j>i;j--)L.elem[j]=L.elem[j-1];L.elem[i] = e;L.length++;return 1;
}int delet(Sqlist &L,int i,ElementType &e)
{//删除第i个位置上的元素并用e返回其值//i的合法值是[0,length-1]if(i<0||i>L.length-1)return 0;e = L.elem[i];for(int j=i;j<L.length-1;j++)L.elem[j]=L.elem[j+1];L.length--;return 1;
}
int cmpEqual(ElementType a, ElementType b)
{return a==b;
}
int cmpGreat(ElementType a, ElementType b)
{return a>b;
}
int cmpLess(ElementType a, ElementType b)
{return a<b;
}
int fin(Sqlist &L, ElementType e,int (*cmp)(ElementType, ElementType))
{//查找L中第一个与e满足cmp关系的元素的位序[0,length-1],如果没有则返回-1//cmp是比较函数,如果满足cmp的比较条件则返回1,否则返回0int i=0;for(i=0;i<L.length;i++){if((*cmp)(L.elem[i],e))return i;}return -1;
}
  • 链式存储
typedef int ElementType;
typedef struct Lnode{ElementType data;Lnode* next;
}Lnode, *Lnodelist;void createList(Lnodelist &l,int n)
{/*通过控制台的输入,创建大小为n的链表两种创建方式,头插法创建的链表和输入顺序相反,尾插法创建的链表和输入顺序相同*/l = (Lnode*)malloc(sizeof(Lnode));l->next=NULL;Lnode *p;/*Lnode *q = l;for(int i=0;i<n;i++)//尾插法{p = (Lnode*)malloc(sizeof(Lnode));cin>>p->data;p->next = q->next;q->next = p;q = p;}*/for(int i=n;i>0;i--) //头插法{p=(Lnode*)malloc(sizeof(Lnode));cin>>p->data;p->next=l->next;l->next = p;}
}
int getElem(Lnodelist &l,int i,ElementType&e)
{/*返回单链表中第i个元素,i的取值范围是[1,n];*/Lnode *p= l->next;int j=1;while(p&&j<i){p=p->next;j++;}if(!p||j>i)return 0; /*此处判断j>i的原因是,如果传入的i小于1时能够及时报错。*/e = p->data;return 1;
}
int listInser(Lnodelist &l,int i,ElementType e)
{/*在链表第i个位置之前插入元素e,i的取值范围[1, n]*/Lnode *p = l,*newP;int j=0;while(p&&j<i-1){p=p->next;j++;}if(!p||j>i-1)return 0; /*此处判断j>i-1的原因是,如果传入的i小于1时能够及时报错。*/newP = (Lnode*)malloc(sizeof(Lnode));newP->data = e;newP->next = p->next;p->next = newP;return 1;
}
int listDel(Lnodelist &l,int i,ElementType &e)
{/*删除链表中第i个元素,并用e返回其值,i的取值范围是[1, n]*/Lnode *p= l,*q;int j=0;while(p->next&&j<i-1){p = p->next;j++;}if(!p->next||j>i-1)return 0;/*此处判断j>i-1的原因同上*/q = p->next;p->next = q->next;e =q->data;free(q);return 1;
}

栈的结构特点是,仅在栈顶(表尾)进行插入和删除操作。栈可以说是操作受限的线性表。栈中元素的修改是按后进先出(LIFO)的原则进行的,所以又称后进先出的线性表。
- 顺序栈

#define STACK_SIZE 100
typedef int SelemType;
typedef struct Stack{SelemType *base; //存放数据的数组SelemType *top; //栈顶指针,指向栈顶元素上面的地址int stacksize; //栈的大小
}Sqstack;
int initS(Sqstack &s)
{s.base = (SelemType*)malloc(STACK_SIZE*sizeof(SelemType));if(!s.base)exit(0);s.top=s.base;s.stacksize = STACK_SIZE;return 1;
}
int getTop(Sqstack &s,SelemType &e)
{//如果不是空栈,则将栈顶元素返回到e,并返回1,否则返回0if(s.top==s.base)return 0;e = *(s.top-1);return 1;
}
int push(Sqstack &s,SelemType e)
{//元素e入栈,成功则返回1if(s.top-s.base>=s.stacksize)//栈满,追加空间{s.base = (SelemType*)realloc(s.base,((s.stacksize+STACK_SIZE)*sizeof(SelemType)));if(!s.base)exit(0);s.top = s.base+s.stacksize; //因为栈数据空间的base指针改变,所以需要更新栈顶top指针;如果top只是一个索引值(整数型),则不必改变。s.stacksize +=STACK_SIZE;}*s.top=e;s.top++;return 1;
}
int pop(Sqstack &s, SelemType &e)
{//若栈不空,则删除栈顶元素,并通过e返回其值,函数返回1,否则,函数返回0if(s.top==s.base)return 0;s.top--;e = *s.top;return 1;
}
  • 链栈
    链栈,可以在链表的基础上进行了修改,需要限制插入操作从头插入,删除操作从头删除即可。
typedef struct snode{SelemType data;struct snode* next;
}*Snode;
typedef struct Lstack{Snode stk;
}LStack;
int LinitS(LStack &s)
{s.stk = (Snode)malloc(sizeof(struct snode));s.stk->next=NULL;return 1;
}
int LgetTop(LStack &s,SelemType &e)
{//如果不是空栈,则将栈顶元素返回到e,并返回1,否则返回0if(s.stk->next==NULL)return 0;e = s.stk->next->data;return 1;
}
int Lpush(LStack &s,SelemType e)
{//元素e入栈,成功则返回1Snode newp = (Snode)malloc(sizeof(struct snode));if(!newp)exit(0);newp->data = e;newp->next= s.stk->next;s.stk->next = newp;return 1;
}
int Lpop(LStack &s, SelemType &e)
{//若栈不空,则删除栈顶元素,并通过e返回其值,函数返回1,否则,函数返回0if(s.stk->next==NULL)return 0;Snode temp = s.stk->next;s.stk->next = temp->next;e = temp->data;free(temp);return 1;
}

队列

队列是一种先进先出(FIFO)的线性表,元素从表的一端插入,而从另一端删除。

  • 队列的链式表示
typedef int QElemType;
typedef struct QNode{QElemType data;struct QNode *next;
}QNode,*Qptr;
typedef struct linkQ{Qptr fron;  //队头指针Qptr rear;  //队尾指针
}LinkQ;
int InitQ(LinkQ &Q)
{//队列初始化为空Q.fron =Q.rear = (Qptr)malloc(sizeof(QNode));if(!Q.fron)exit(0);Q.fron->next=NULL;return 1;
}
int DesQ(LinkQ &Q)
{//销毁队列Qwhile(Q.fron){Q.rear = Q.fron->next;free(Q.fron);Q.fron = Q.rear;}return 1;
}
int EnQ(LinkQ &Q,QElemType e)
{//入队操作Qptr p =(Qptr)malloc(sizeof(QNode));if(!p)exit(0);p->data = e;p->next= Q.rear->next;Q.rear->next = p;Q.rear=p;return 1;
}
int DeQ(LinkQ &Q,QElemType &e)
{//出队操作,用e返回其值if(Q.fron==Q.rear)return 0;Qptr p = Q.fron->next;Q.fron->next = p->next;e = p->data;if(Q.rear==p)Q.rear = Q.fron;free(p);return 1;
}
  • 队列的顺序表示
    这里利用队列的顺序表示实现了循环队列。
#define MAXQSIZE 10
typedef struct sqQ{QElemType *base;int fron;int rear;
}SqQ;
int SinitQ(SqQ &Q)
{//初始化一个空队列Q.base = (QElemType*)malloc(MAXQSIZE*sizeof(QElemType));if(!Q.base)exit(0);Q.fron = Q.rear=0;return 1;
}
int Qlen(SqQ &Q)
{return (Q.rear-Q.fron+MAXQSIZE)%MAXQSIZE;
}
int SenQ(SqQ &Q,QElemType e)
{//插入元素e为Q新的队尾元素if((Q.rear+1)%MAXQSIZE ==Q.fron)return 0; //队列满的时候返回0Q.base[Q.rear]=e;Q.rear = (Q.rear+1)%MAXQSIZE;return 1;
}
int SdeQ(SqQ &Q,QElemType &e)
{//删除队首元素,用e返回其值if(Q.fron==Q.rear)return 0;//队列空的时候返回0e = Q.base[Q.fron];Q.fron = (Q.fron+1)%MAXQSIZE;return 1;
}

相关的STL容器的基本操作

vector

c++ reference
vector是一个能够存放任意类型的动态数组,能够增加和压缩数据。如果向量长度较长(需要为向量内部保存很多数),容易导致内存泄漏,而且效率会很低;Vector作为函数的参数或者返回值时,需要注意它的写法:
double Distance(vector<int>&a, vector<int>&b)
其中的“&”绝对不能少
(1)头文件 #include<vector>.
(2)创建vector对象,vector<int> vec;
(3)尾部插入数字:vec.push_back(a);
(4)使用下标访问元素,cout<<vec[0]<<endl;下标是从0开始的。
(5)使用迭代器访问

vector<int>::iterator it;
for(it=vec.begin();it!=vec.end();it++)cout<<*it<<endl;

(6)插入元素: vec.insert(vec.begin()+i,a);在第i+1个元素前面插入a;
(7)删除元素:
vec.erase(vec.begin()+2);删除第3个元素
vec.erase(vec.begin()+i,vec.end()+j);删除区间[i,j-1];区间从0开始
(8)向量大小:vec.size();
(9)清空:vec.clear();

list

c++ reference
List是stl实现的双向链表,与向量(vectors)相比, 它允许快速的插入和删除,但是随机访问却比较慢。使用时需要添加头文件#include <list>

list<int>lst1;          //创建空list
list<int> lst2(5);       //创建含有5个元素的list
list<int>lst3(3,2);  //创建含有3个元素的list,三个元素的初始值是1
list<int>lst4(lst2);    //使用lst2初始化lst4
list<int>lst5(lst2.begin(),lst2.end());  //同lst4

Lst1.assign() 给list赋值
Lst1.back() 返回最后一个元素
Lst1.begin() 返回指向第一个元素的迭代器
Lst1.clear() 删除所有元素
Lst1.empty() 如果list是空的则返回true
Lst1.end() 返回末尾的迭代器
Lst1.erase() 删除一个元素
Lst1.front() 返回第一个元素
Lst1.get_allocator() 返回list的配置器
Lst1.insert() 插入一个元素到list中
Lst1.max_size() 返回list能容纳的最大元素数量
Lst1.merge() 合并两个list
Lst1.pop_back() 删除最后一个元素
Lst1.pop_front() 删除第一个元素
Lst1.push_back() 在list的末尾添加一个元素
Lst1.push_front() 在list的头部添加一个元素
Lst1.remove() 从list删除元素
Lst1.resize() 改变list的大小
Lst1.reverse() 把list的元素倒转
Lst1.size() 返回list中的元素个数
Lst1.sort() 给list排序

stack

c++ reference
C++ Stack(堆栈) 是一个容器类的改编,为程序员提供了堆栈的全部功能,——也就是说实现了一个先进后出(FILO)的数据结构。
头文件为:
#include <stack>
c++ stl栈stack的成员函数介绍
empty() 堆栈为空则返回真
pop() 移除栈顶元素
push() 在栈顶增加元素
size() 返回栈中元素数目
top() 返回栈顶元素

queue

c++ reference
C++队列queue模板类的定义在<queue>头文件中,queue 模板类需要两个模板参数,一个是元素类型,一个容器类型,元素类型是必要的,容器类型是可选的,默认为deque 类型。
C++队列Queue是一种容器适配器,它给予程序员一种先进先出(FIFO)的数据结构。
C++队列Queue类成员函数如下:
back()返回最后一个元素
empty()如果队列空则返回真
front()返回第一个元素
pop()删除第一个元素
push()在末尾加入一个元素
size()返回队列中元素的个数

deque

c++ reference
容器deque和vector非常相似,操作函数基本一致。它采用动态数组来管理元素,提供随机存取,可以在头尾两端进行快速安插和删除元素操作。特别要注意,除了头尾两端,在任何地方安插与删除元素,都将导致指向deque元素的任何pointers references iterators 失效。
包括的头文件为:
#include <deque>
构造函数:

deque<Elem> c   ;  //产生一个空的deque,其中没有任何元素
deque<Elem> c1(c2); //产生另一个同型deque的副本(所有元素都被拷贝)
deque<Elem> c(n) ;  //产生一个大小为n的deque
deque<Elem> c(n , elem) ;  //产生一个大小为n的deque,//每个元素值都是elem。
deque<Elem> c(begin,end); //产生一个deque,以区间[begin ; end]//做为元素初值

基本操作:

c.size();         //返回当前的元素数量
c.empty();       //判断大小是否为零。等同于c.size() == 0,但可能更快
c.max_size();    //可容纳元素的最大数量
c.at(idx) ;       //返回索引为idx所标示的元素。如果idx越界,抛出out_of_range
c[idx] ;         //返回索引idx所标示的元素。不进行范围检查
c.front() ;       //返回第一个元素,不检查元素是否存在
c.back();        //返回最后一个元素
c.begin();       //返回一个随机迭代器,指向第一个元素
c.end();         //返回一个随机迭代器,指向最后元素的下一位置
c1 = c2  ;        //将c2的所有元素赋值给c1;
c.assign(n , elem);    //将n个elem副本赋值给c
c.assing(beg , end);   //将区间[beg;end]中的元素赋值给c;
c.push_back(elem);   //在尾部添加元素elem
c.pop_back()    ;    //移除最后一个元素(但不回传)
c.push_front()   ;   //在头部添加元素elem
c.pop_front()    ;   //移除头部一个元素(但不回传)
c.erase(pos)    ;   //移除pos位置上的元素,返回一元素位置 //如 c.erase( c.begin() + 5)  //移除第五个元素
c.insert(pos , elem); //在pos位置插入一个元素elem,并返回新元素的位置
c.insert(pos , n , elem); //在pos位置插入n个元素elem,无返回值
c.insert(pos , beg , end);
c.resize(num);       //将容器大小改为num。可更大或更小。
c.resize(num , elem);  //将容器大小改为num,新增元素都为 elem
c.clear();            //移除所有元素,将容器清空

习题

线性表相关——一元多项式的加法和乘法

题目描述

输入格式 输入分2行,每行分别先给出多项式非零项的个数,再以指数递降方式输入一个多项式非零项系数和指数(绝对值均为不超过1000的整数)。数字间以空格分隔。

输出格式 输出分2行,分别以指数递降方式输出乘积多项式以及和多项式非零项的系数和指数。数字间以空格分隔,但结尾不能有多余空格。零多项式应输出0 0。
输入样例
4 3 4 -5 2 6 1 -2 0
3 5 20 -7 4 3 1
输出样例
15 24 -25 22 30 21 -10 20 -21 8 35 6 -33 5 14 4 -15 3 18 2 -6 1
5 20 -4 4 -5 2 9 1 -2 0
(题目选自PTA,作者: 浙江大学DS课程组)

题解

//节点数据类型
typedef int ElementType;
typedef struct Node *PtrToNode;
struct Node {ElementType Data;ElementType exponent;PtrToNode   Next;
};

加法依次计算即可,注意系数data为零时需要删除节点;
乘法转换为加法计算,即让其中一个表达式的每一项依次与另一个多项式相乘,然后相加并合并同类项,注意系数为零的情况,注意插入位置的选择,需要遍历结果链表,选择合适的插入位置。
具体代码C语言如下

#include <stdio.h>
#include <stdlib.h>typedef int ElementType;
typedef struct Node *PtrToNode;
struct Node {ElementType Data;ElementType exponent;PtrToNode   Next;
};
//头结点的data存放多项式的项数
typedef PtrToNode List;List Read(int n);
void Print( List L );
List multi(List L1,List L2);
List add( List L1, List L2 );int main()
{List L1, L2;int n1,n2;scanf("%d",&n1);L1 = Read(n1);scanf("%d",&n2);L2 = Read(n2);Print(L1);Print(L2);List La;List Lm;Lm = multi(L1,L2);La = add(L1, L2);Print(Lm);Print(La);return 0;
}void Print(List L)
{if(L==NULL){printf(" \n");return;}if(L->Data==0){printf("0 0\n");return;}/*else{printf("%d",L->Data);}*/PtrToNode p = L->Next;int flag = 0;while(p!=NULL){if(flag==1){printf(" ");}else{flag = 1;}printf("%d %d",p->Data,p->exponent);p = p->Next;}printf("\n");return;
}List Read(int n)
{List l = (List)malloc(sizeof(struct Node));l->Data = n;PtrToNode p = l;p->Next = NULL;ElementType res_data,res_exponent;while(n--){scanf("%d %d",&res_data,&res_exponent);PtrToNode new_p = (PtrToNode)malloc(sizeof(struct Node));new_p->Data = res_data;new_p->exponent = res_exponent;new_p->Next = NULL;p->Next = new_p;p = new_p;}return l;
}List add(List L1, List L2)
{List r = (List)malloc(sizeof(struct Node));PtrToNode p = r,p1,p2,pre1,pre2;int num = 0;if(!L1){return L2;}if(!L2){return L1;}pre1 = L1->Next;pre2 = L2->Next;p1 = L1->Next;p2 = L2->Next;while(p1&&p2){if(p1->exponent==p2->exponent){PtrToNode new_p = (PtrToNode)malloc(sizeof(struct Node));if(p1->Data+p2->Data!=0){new_p->Data = p1->Data + p2->Data;new_p->exponent = p1->exponent;new_p->Next = NULL;p->Next = new_p;p=new_p;num++;}p1=p1->Next;p2=p2->Next;free(pre1);free(pre2);pre1 = p1;pre2 = p2;}else if(p1->exponent>p2->exponent){PtrToNode new_p = (PtrToNode)malloc(sizeof(struct Node));new_p->Data = p1->Data;new_p->exponent = p1->exponent;new_p->Next = NULL;p->Next = new_p;p=new_p;num++;p1=p1->Next;free(pre1);pre1 = p1;}else if(p1->exponent<p2->exponent){PtrToNode new_p = (PtrToNode)malloc(sizeof(struct Node));new_p->Data = p2->Data;new_p->exponent = p2->exponent;new_p->Next = NULL;p->Next = new_p;p=new_p;num++;p2=p2->Next;free(pre2);pre2 = p2;}}while(p1){PtrToNode new_p = (PtrToNode)malloc(sizeof(struct Node));new_p->Data = p1->Data;new_p->exponent = p1->exponent;new_p->Next = NULL;p->Next = new_p;p=new_p;num++;p1=p1->Next;free(pre1);pre1 = p1;}while(p2){PtrToNode new_p = (PtrToNode)malloc(sizeof(struct Node));new_p->Data = p2->Data;new_p->exponent = p2->exponent;new_p->Next = NULL;p->Next = new_p;p=new_p;num++;p2=p2->Next;free(pre2);pre2 = p2;}r->Data = num;return r;
}
List multi(List L1,List L2)
{List r = (List)malloc(sizeof(struct Node));int num_item = 0;PtrToNode now_ptr = r,p1 = L1->Next,p2 = L2->Next;if(!p1||!p2){r->Data = 0;r->Next = NULL;return r;}while(p2){PtrToNode new_node = (PtrToNode)malloc(sizeof(struct Node));new_node->Data = p1->Data*p2->Data;new_node->exponent = p1->exponent+p2->exponent;new_node->Next = NULL;now_ptr->Next = new_node;now_ptr = now_ptr->Next;num_item++;p2=p2->Next;}p1=p1->Next;while(p1){p2 = L2->Next;now_ptr = r;while(p2){ElementType e = p1->exponent + p2->exponent;ElementType num = p1->Data*p2->Data;while(now_ptr->Next&&now_ptr->Next->exponent>e){now_ptr = now_ptr->Next;}if(now_ptr->Next&&now_ptr->Next->exponent==e){if((now_ptr->Next->Data+num)!=0){now_ptr->Next->Data+=num;}else{PtrToNode temp = now_ptr->Next;now_ptr->Next = temp->Next;free(temp);num_item--;}}else{PtrToNode new_node = (PtrToNode)malloc(sizeof(struct Node));new_node->Data = num;new_node->exponent = e;new_node->Next = now_ptr->Next;now_ptr->Next = new_node;now_ptr = now_ptr->Next;num_item++;}p2=p2->Next;}p1 = p1->Next;}r->Data = num_item;return r;
}

线性表相关——链表的反转

//链表反转函数详解node* reverseList(node* H) {
if (H == NULL || H->next == NULL) //链表为空或者仅1个数直接返回 return H;
node* p = H, *newH = NULL;
while (p != NULL) //一直迭代到链尾 {node* tmp = p->next; //暂存p下一个地址,防止变化指针指向后找不到后续的数
p->next = newH; //p->next指向前一个空间
newH = p; //新链表的头移动到p,扩长一步链表
p = tmp; //p指向原始链表p指向的下一个空间
}
return newH;//C++库函数
#include<algorithm>
reverse(first ptr,last ptr);//这个函数反转了[first,last)之间的节点(一些容器也有reverse函数,可直接使用)
}

栈相关——栈的混洗&栈的模拟

题目描述

Given a stack which can keep M numbers at most. Push N numbers in the order of 1, 2, 3, …, N and pop randomly. You are supposed to tell if a given sequence of numbers is a possible pop sequence of the stack. For example, if M is 5 and N is 7, we can obtain 1, 2, 3, 4, 5, 6, 7 from the stack, but not 3, 2, 1, 7, 5, 6, 4.

Input Specification:
Each input file contains one test case. For each case, the first line contains 3 numbers (all no more than 1000): M (the maximum capacity of the stack), N (the length of push sequence), and K (the number of pop sequences to be checked). Then K lines follow, each contains a pop sequence of N numbers. All the numbers in a line are separated by a space.

Output Specification:
For each pop sequence, print in one line “YES” if it is indeed a possible pop sequence of the stack, or “NO” if not.
Sample Input:
5 7 5
1 2 3 4 5 6 7
3 2 1 7 5 6 4
7 6 5 4 3 2 1
5 6 4 3 7 2 1
1 7 6 5 4 3 2
Sample Output:
YES
NO
NO
YES
NO
(problem source:PTA DS course)

题解
直接模拟这样一种栈混洗的过程,建立三个栈,先后完成push()…pop()…push()的操作,保证能依次得到目标序列,那么就可以确定这样的序列是可以得到的,反之就不能得到,这样的时间度最小为O(n)。

#include <iostream>
#include<stack>
using namespace std;bool judge(int m,int n, int b[])
{stack<int>a;stack<int>s; //使用两个栈来模拟操作过程for(int i=n;i>=1;i--){a.push(i);}int i=0;while(i<n){int top = b[i];if(!a.empty()&&a.top()==top){int temp=a.top();a.pop();s.push(temp);if((int)s.size()>m){return false;}s.pop();i++;}else if(!s.empty()&&s.top()==top){s.pop();i++;}else{if(a.empty()){return false;}int temp = a.top();a.pop();s.push(temp);if(a.empty()||(int)s.size()>m){return false;}}}if(a.empty()&&s.empty()){return true;}return false;}int main()
{int m,n,k;cin>>m>>n>>k;bool res[k];int b[n];for(int i=0;i<k;i++){for(int j=0;j<n;j++){cin>>b[j];}res[i] = judge(m,n,b);}for(int i=0;i<k;i++){if(res[i]){cout<<"YES"<<endl;}else{cout<<"NO"<<endl;}}
}

Reference

  • 数据结构(C语言版) 严蔚敏 清华大学出版社
  • http://www.cplusplus.com/reference/
  • https://blog.csdn.net/yas12345678/article/details/52601578
  • https://blog.csdn.net/duan19920101/article/details/50617190/

数据结构——线性结构总结相关推荐

  1. 数据结构——线性结构

    简单地说,线性结构就是表中各个结点具有线性关系.如果从数据结构的语言来描述,线性结构应该包括如下几点: 1.线性结构是非空集. 2.线性结构有且仅有一个开始结点和一个终端结点. 3.线性结构所有结点都 ...

  2. java中线性结构的例子_java数据结构--线性结构

    一.数据结构 数据结构由数据和结构两部分组成,就是将数据按照一定的结构组合起来,这样不同的组合方式有不同的效率,可根据需求选择不同的结构应用在相应在场景.数据结构大致 分为两类:线性结构(如数组,链表 ...

  3. 常用数据结构--线性结构

    数据结构是计算机存储.组织数据的方式.常见的数据结构分类方式如下图: 常用的线性结构有:线性表,栈,队列,循环队列,数组.线性表中包括顺序表.链表等,其中,栈和队列只是属于逻辑上的概念,实际中不存在, ...

  4. 数据结构:线性结构和非线性结构的理解

    我们知道数据结构是计算机存储.组织数据的方式.常见的数据结构分类方式如下图: 我们这里主要说一下线性结构和非线性结构 1. 线性结构 线性结构是什么? 数据结构中线性结构指的是数据元素之间存在着&qu ...

  5. 数据结构——线性结构(线性表)

    文章目录 一. 线性结构概述 1. 线性结构(线性表的逻辑结构)的定义 2. 线性表的特点 二. 线性结构分类 1. 连续存储[顺序表] (1). 什么叫数组 (2). 顺序表算法的基本操作 (3). ...

  6. 数据结构线性结构和非线性结构

    1.线性结构 特点:1)数据元素之间存在一对一的线性关系 2)线性存储结构分为顺序存储结构和链式结构. 3)顺序表中存储元素(地址)是连续的 4)链表中存储的元素不一定是连续的 5)线性结构常见的有: ...

  7. 基本数据结构——线性结构(列表/无序表)

    1.什么是列表(List)? 一个数据项按照相对位置存放的数据集.特别的,被称为"无序表(unordered list)",其中数据项只按照存放位置来索引,如第1个.第2个-.最后 ...

  8. 基本数据结构——线性结构(有序表)

    1. 什么是有序表(OrderedList) 有序表是一种数据项依照其某可比性质(如整数大小.字母表先后)来决定在列表中的位置.越"小"的数据项越靠近列表的头,越靠"前& ...

  9. 【Python-数据结构】——线性结构

    <Python数据结构>@EnzoReventon Python 数据结构 -- 线性结构 Array 1. 关于Array的一些简介 数组是最常用的一种线性结构.除了数组之外,其实Pyt ...

最新文章

  1. ArrayAdapter requires the resource ID to be a TextView
  2. 人工智能入门:keras的example文件解析
  3. “裁员” + 滤镜 = “毕业”
  4. 【操作系统】考研の页面置换算法例子(看不懂你来打我~!)
  5. HDU 1754 I Hate It(线段树单点更改、区间查找最大值)
  6. 打印某个进程下的所有线程--Linux环境
  7. Java8————日期时间 API
  8. 局域网中搜计算机无法访问,怎么找不到共享电脑,手把手教你局域网中共享电脑找不到怎么办...
  9. centos下设置自启动和配置环境变量的方法
  10. jQuery-1.9.1源码分析系列(十) 事件系统——事件包装
  11. 《muduo网络库》学习笔记——TcpClient剖析
  12. 使用GPS和velodyne 64拼接地图
  13. Java将一个堆栈进行反转,如何使用Java中的堆栈反转数组的元素?
  14. 同步消息和异步消息传递的区别?
  15. 走进施耐德电气无锡工厂,见证自动化研发中心开幕
  16. 视频教程-区块链技术原理精讲-区块链
  17. 达梦V8的数据迁移工具DTS常见报错1及其解决办法
  18. Compose Text + Canvas 写个验证码
  19. Amq 使用+springboot
  20. 【SDX62】IPA log抓取操作说明

热门文章

  1. JYM虚拟机性能监控与故障处理工具
  2. 汉子编码比字母编码长_编码比您想象的更具创意
  3. linux概念和体系
  4. python如何切换windows窗口_python – Windows 7:如何把窗口带到前面,无论其他窗口有什么重点?...
  5. 索尼大法这回不行了!PSVR的位置追踪是个大坑
  6. 更多查询模式--mysql学习笔记
  7. 罗技官网进不去怎么下载驱动?
  8. html css 横杠样式设置
  9. 「Python语法结构」数据类型与运算符示例(9)
  10. android手机跑分测试,性能跑分测试与测试总结