基础数据结构

  1. 栈:
  2. 队列
  3. 单链表
  4. 双链表

1.栈

#include <bits/stdc++.h>
using namespace std;
const innt N = 1e6 + 10;

//栈 stk -->数组模拟栈 tt--> 栈顶
int stk[N], tt ;

//进栈
void push(int x){
    if(tt + 1 > N) printf("overfloor\n");//栈溢出
    else stk[++ tt] = x;
}
//判断栈空
void empty(){
    if(tt > 0) printf("not empty");
    else printf("empty");
}
//出栈
void pop(){
    if( !tt ) printf("no position\n");// 栈空
    else stk[tt--] = 0 ;//把弹出去的栈赋值 0 
}

栈顶元素:
stk[tt];

单调栈常用问题:

给定一个序列,每一个数离她最近大的数字或者最小的数在什么地方。
例题

2. 队列

#include <bits/stdc++.h>

using namespace std;

const int N = 1e6 + 10 ;

//队列
// q --> 队列 l --> 队头  r --> 队尾
int q[N], l, r; 

//插入
void insert(int x){
    q[++r] = x;
}

//弹出
void remove(){ l++;}

// 判断是否为空
void empty(){
    if(l <= r ) printf("not empty\n");
    else printf("empty\n");
}

队头:q[l];
队尾:q[r];

3.单链表

数组模拟链表:

单链表

#include <bits/stdc++.h>

using namespace std;

const int  N = 1e7 + 10;

// 0 号点 e[0] 指针 ne[0] = 1
int head, e[N], ne[N], idx;
//head --> 头结点下标
// e[i] --> 表示节点 i的值
// ne[i] --> 表示节点 i 的next指针
// idx --> 存储当前用到的地址,相当于指针,当前用到的点
// 不论每次删除还是插入 idx++ 不用去管那些删除的空间(追求速度)

//初始化
void init(){
    head = - 1;//头结点
    idx = 0 ;
}

//将 x 插入到头结点后面
void add_to_head(int x){
    e[idx] = x, ne[idx] = head, head = idx++;
}

//将 x 插入到下标是 k 的点后面
void add(int k,int x){
    e[idx] = x, ne[idx] = ne[k], ne[k] = idx++;// == ne[k] = idx, idx++;
}

//删除下标是 k 的点后面一个点删掉
void remove(int k){
    ne[k] = ne[ne[k]];
}

int  main(){
    int m;cin>>m;
    init();//初始化
 
    while(m--){
        char op ;
        int k , x;
        cin >> op ;
        if(op == 'H'){
            cin>>x;
            add_to_head(x);
        }
       else if(op == 'D'){
            cin>>k;
            if(!k ) head =ne[head];//删除头结点
            remove(k - 1);//k 从 0 开始 所以要 - 1
        }
        else{
            cin>>k >> x;
            add(k - 1 , x);
        }
      //  for(int i = head; i != -1; i = ne[i]) cout<<e[i]<<' ';cout<<endl;
    }
    //输出
    for(int i = head; i != -1; i = ne[i])  printf("%d ",e[i]);
    
    return 0;
}

4.双链表

双链表

//注 : 下面操作是 k + 1 ,原因是因为 idx == 1的情况初始化的时候已经使用了
#include <iostream>
#include <cstdio>

using  namespace std;

const int N = 1e5 + 9;

int list[N], l[N], r[N], idx;

void init(){
    r[0] = 1, l[1] = 0, idx = 2;   //初始化头结点(右边指向第一个节点)和第一个节点(左边指向头结点)
}

// x 插到 k 后面
void insert(int k, int x){
    list[idx] = x;               //建立新节点
    l[idx] = k;                  //将新节点连边
    r[idx] = r[k];               //右边连接到下一个节点的左边,左边连接到上一个节点的右边
    l[r[k]] = idx;               //将原来两个相连接打的节点打断,连到新节点上
    r[k] = idx;                  //右边的左指针连接到新节点的右指针上,左边同理
    idx++;                       //位置加一
}

//删除第 x 个节点
void remove(int x){
    r[l[x]] = r[x];
    l[r[x]] = l[x];
}

int main(){
    int m ;
    init();
    scanf("%d",&m);
    
    while(m--){
        string op;
        int k,x;
        cin>>op;
        
        if(op == "L"){            //在链表的最左端插入 x 也就是在左边界后插入一个节点,就是最左端插入一个节点
            scanf("%d",&x);
            insert(0, x);
        }
        else if(op == "R"){       //在链表的最右端插入也,就是右边界的左节点后插入一个新节点
            scanf("%d",&x);
            insert(l[1], x);
        }
        else if(op == "IL"){      //第k个插入的数左侧插入一个数 在第k个插入的数的左节点后插入一个数
            scanf("%d%d",&k,&x);
            insert(l[k+1], x);
        }
        else if(op == "IR"){     //第k个插入的数右侧插入一个数
            scanf("%d%d",&k,&x);
            insert(k+1, x);
        }
        else if(op == "D"){      //把第k个插入的数删除
            scanf("%d",&x);
            remove(x+1);
        }
    }
    
    for(int i = r[0]; i != 1; i = r[i]) printf("%d ",list[i]);
    
    return 0;
}
posted @ 2021-03-02 17:04  Carrot_Rui  阅读(73)  评论(0)    收藏  举报