数据结构基础(一)

一.debug

我们在运行程序的过程中,会有运行结果出现错误的情况,这个时候就需要我们去解决这些问题,这些问题就是bug,而我们去解决这个问题就是debug。我们可以使用断点调试,一步步的看源代码执行过程来发现代码的错误。一般在使用软件编辑代码时,可用鼠标在行序号前面打断点,进行调试。这是我们要作为程序员必须掌握的技能。

二.数据结构

某种逻辑关系组织起来的一批数据,按一定的映像方式把它存放在计算机存储器中,并在这些数据上定义了一个运算的集合,就叫做数据结构。

数据结构一般包括以下三个方面内容:

(1)数据元素之间的逻辑关系,也称数据的逻辑结构。

(2)数据元素及其关系在计算机存储器内的表示,称为数据的存储结构。

(3)数据的运算,即对数据施加的操作。

以下是常用数据结构的插入、删除与搜索操作的时间复杂度:

数据结构

一般情况

最差情况

插入

删除

搜索

插入

删除

搜索

数组/栈/队列

O(1)

O(1)

O(n)

O(1)

O(1)

O(n)

链表

O(1)

O(1)

O(n)

O(1)

O(1)

O(n)

双向链表

O(1)

O(1)

O(n)

O(1)

O(1)

O(n)

散列表

O(1)

O(1)

O(1)

O(1)

O(n)

O(n)

二分搜索树

O(logn)

O(logn)

O(logn)

O(n)

O(n)

O(n)

以下是常用排序算法的时间复杂度:

算法(用于数组)

最好情况

一般情况

最差情况

冒泡排序

O(n)

O(n²)

O(n²)

选择排序

O(n²)

O(n²)

O(n²)

插入排序

O(n)

O(n²)

O(n²)

归并排序

O(nlog(n))

O(nlog(n))

O(nlog(n))

快速排序

O(nlog(n))

O(nlog(n))

O(n²)

三.线性表

线性表是线性结构中最常用而又最简单的一种数据结构,线性表是线性结构的抽象,线性结构的特点是一对一的线性关系。

线性表是具有相同类型数据的n(n>=0)个数据元素的有序数列。通常记为:

(a1,a2,…,ai,…,an)

其中,n为表长,n=0时为空表。在线性表中相邻元素之间存在顺序关系。线性表有两种存储方式,顺序存储与链式存储。

四.栈和队列

严格意义上来说,也属于线性表,因为存储逻辑关系也属于“一对一”,所以栈与队列,同样分为顺序存储与链式存储。

使用栈存储数据,讲究“先进先出”,即最先进栈,最后出栈。栈是只能在表尾进行插入或删除操作的线性表,通常我们称表尾为栈顶,表头为栈底,表尾插入称为入栈,表尾删除称为出栈。

c++在STL里面为我们提供了栈,使用stack时需要引入头文件#include<stack>。

stack<int>s

创建一个空栈s,数据类型为int

push(x)

x入栈

pop( )

出栈

top()

取栈顶(不出栈)

empty()

判断栈是否为空,若为空则返回true

size()

求栈大小,返回栈中的元素个数

数组模拟与STL容器
1.新建⼀个栈 
int stk[N], top = -1;//top指向栈顶。基底是0则top=-1,是1则top=0 
stack<int>stk; 
2.插⼊数据 
stk[++ top] = x;//将x插⼊栈 
stk.push(x);//将x⼊栈 
3.删除栈顶元素 
top--;//删去栈顶 
stk.top();//删栈顶 
4.查询栈顶数据 
stk[top]; 
stk.top();//取栈顶 
5.如何清空⼀个栈 
 5.1 依次判断top是否存在,并删除top。O(n) 
 5.2 直接将top指针指向基地址。O(1) 
6.数组模拟和STL容器的区别: 
6.1 STL⾥⾯的stack没有清空函数,只能⼀个⼀个出栈or新建⼀个栈。 
6.2 数组模拟的栈可以O(1)取出从栈顶往下数第k个元素(stk[top - k + 1),⽽STL实现的栈不可以。
例题

P1449 后缀表达式


题目描述:

所谓后缀表达式是指这样的一个表达式:式中不再引用括号,运算符号放在两个运算对象之后,所有计算按运算符号出现的顺序,严格地由左而右新进行(不用考虑运算符的优先级)。

如:{3*(5-2)+7}3*(5-2)+7 对应的后缀表达式为3.5.2.-*7.+@。在该式中,@ 为表达式的结束符号。. 为操作数的结束符号。

#include<iostream>
#include<stack> //使用STL提供的栈需要的头文件 
#include<cstdio>
#include<cstring>
using namespace std;
int sum,k;
string s;
stack <int> stk;// 创建栈 
int main()
{
    getline(cin,s);
    for(int i=0;s[i]!='@';i++)
    {
        if(s[i]=='.')
        {
            sum=0,k=1;
            for(int j=i-1;j>=0&&s[j]>='0'&&s[j]<='9';j--) 
            sum=sum+(s[j]-48)*k,k*=10; 
            stk.push(sum);
            continue;
        }//乘10的幂,将字符转换为十进制数,放入栈内。
        if(s[i]>='0'&&s[i]<='9') 
        continue;
        sum=stk.top();
        stk.pop(); 
        if(s[i]=='+') sum=stk.top()+sum;
        if(s[i]=='-') sum=stk.top()-sum;
        if(s[i]=='*') sum=stk.top()*sum;
        if(s[i]=='/') sum=stk.top()/sum;
        stk.pop();
        stk.push(sum);//遇见运算符的时候,取栈顶元素进行计算; 
    }
    cout<<stk.top();//输出结果 
    return 0;
}


    • 队列

队列存储数据,保证“先进先出”,队列插入操作称为入队,队列删除操作称为出队,允许插入的一端称为队尾,允许删除的一端称为队头,不含任何数据元素的队列叫空队。

c++同样在STL里面为我们提供了队列,使用队列时需要引入头文件#include<queue>。

queue < int > q

建立一个队列q,其内部元素类型是 int。

q.push(a)

将元素 a 插入队列 q 的末尾。

q.pop()

将 q 的队首元素删除.。

q.front()

查询 q 的队首元素。

q.end()

查询 q 的队尾元素。

q.size()

查询 q 的元素个数。

q.empty()

查询 q 是否为空。

我们经常使用的为顺序队列,链队列,循环队列与优先队列。

顺序队列的使用,会有如图的情况,

此时队列为空或者剩余存储单元,这种现象称为“假溢出”。循环队列解决了顺序队列的“假溢出”现象,但是新的问题出现,队满的条件不再是rear=MAXSIZE-1,而是front==rear和队空条件相同。

解决方法:损失一个单元不用,即循环队列中元素个数是MAXSIZE-1时就认为队列满。

循环队列的存储空间是连续的,且预先分配的,若循环队列的出队与入队元素数量变化较大时,就难以准确估计,若预先分配的空间估计过大,会造成空间浪费,估计过小会导致溢出。此时就可以使用链队列来解决这个问题。

优先队列:

优先队列是一种特殊的队列,它不遵守先进先出的原则,每一个元素都有一个被称为权的数据,它是按照优先级出队列的。分为最大优先队列(是指最大的元素优先出队)和最小优先队列(是指最小的元素优先出队)。

例题

P1996 约瑟夫问题

题目描述:

n 个人围成一圈,从第一个人开始报数,数到 mm 的人出列,再由下一个人重新从 11 开始报数,数到 mm 的人再出圈,依次类推,直到所有的人都出圈,请输出依次出圈人的编号。

#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
queue<int> sum;
int main(){
     int n,m,s=1;
     cin>>n>>m;
     for(int i=1;i<=n;i++)
     {
         sum.push(i);
      } 
      while(!sum.empty()){
          if(s==m){
              cout<<sum.front()<<" ";
              sum.pop();
              s=1;
          }
          else if(s!=m){
              s++;
              sum.push(sum.front());
              sum.pop();
          }
      }
      return 0;
} 

五.vector

在 C++ 的 STL 中,给我们提供了一个可变长度数组,可变长度数组的头文件是 #include< vector >

说明

功能

vector v(N,i)

建立一个可变长度的 int 数组 v,且初始有 N 个为 i 的元素。N,i 可以省略。

v.push_back(a)

将元素 a 插入 v 的末尾。

v.size()

返回元素个数。

v.resize(n,m)

重新调整数组大小为 n。如果 n 比原来大,则新增的部分都初始化为 m。

v[a]

访问下标为 a 的元素。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值