daimayuan第一课栈,队列,链表

链表:

总结:没上课之前,只会用数组模拟单链表;

需要学的内容

1:结构体指针的运用;

 2:队列的性质

知识点:

结构体指针:

 1:c++没有自带的next,prve;

2:a[i].vaule是成员数,-> 是下一个指针;

3:结构体里套结构体指针

这个指针看似指向自身,其实不是,而是指向同一类型的不同结构。

链表和树的数据结构就都使用到此技巧。自身的结构体指针指向下一节点或者下一子树的地址。

例如:

struct Now{
int vaule;
Now *next,*prve;
}a[2001],*head,*tail;

 链表的性质:
1:head,tail 链接的是地址
2:注意链表插入的顺序
a:头插法:

a[i].next = h1->next;
h1->next = &a[i];

b:尾插法:

t1->next = &a[i];
t1 = &a[i];

队列的性质:

1:数组模拟队列时可以方便查找;

2:循环队列

a.判断满:循环队列的满不再是rear=front 而是改成(rear-front+maxn)%maxn。
b.入队操作: data[rear] = x; rear = (rear+1)%maxn;

总体思想就是不让rear和front的值超过maxn的大小。于是就在rear和front自增时候模maxn。 


注意:空队时rear等于front,满队时必须空一个位置。

 

练习;205,206,301,302,303,304,305

约瑟夫问题

有 nn 个人排成一圈,从 11 到 nn 标号。从第一个人开始报数,每次数到 mm 的人出列,下一个继续从 11 开始数,依次类推,直到所有人都出列。

输出每次出列的人的编号。

输入格式

第一行,两个整数 n,mn,m。

输出格式

输出一行,包含 nn 个数,表示每次出列的人的标号。

解法一:队列

#include <bits/stdc++.h>

using namespace std;
int a[100001];
int tt = 1,ed = 0,cnt;
int main()
{
    int n,m;
    cin >> n >> m;
    for(int i = 1;i <= n;i ++ )
    {
        cnt ++;
        if(cnt == m)
        {
            cout << i << " ";
            cnt = 0;
            continue;
        }
        ed ++;
        a[ed] = i;
    }
    if(tt > ed)
        return 0;
    for(int i = tt;i != ed ; i ++)
    {
        cnt ++;
        if(cnt == m)
        {
            cout << a[i] << " ";
            cnt = 0;
            continue;
        }
        ed ++;
        a[ed] = a[i];
    }
    cout << a[ed] << '\n';
}

 

解法二:循环链表

#include <bits/stdc++.h>

using namespace std;
int n,m;
struct Now{
    int vaule;
    Now *next,*prve;
}a[1001],*head,*tail;
int cnt ,num;
int main()
{
    scanf("%d %d",&n,&m);
    head = NULL;
    tail = NULL;
    for(int i = 1;i <= n;i ++ )
    {
        cnt ++;
        if(cnt == m)
        {
            printf("%d ",i);
            cnt = 0;
            continue;
        }
        a[++num].vaule = i;
        //cout << i << '\n';
        if(head == NULL)
            tail = head = &a[num];
        else{
            tail->next = &a[num];
            a[num].prve = tail;
            tail = &a[num];
        }   
    }
    if(num==0)
        return 0;
    tail->next = head;
    head->prve = tail;
    Now *p = head;
   // cout << num << '\n';
   // num = 0;
    for(p;p != p->next ;p = p->next)
    {
        //p = p->next;
        //cout << "x" << p->vaule << '\n';
        cnt ++;
        if(cnt == m)
        {
            printf("%d ",p->vaule);
            cnt = 0;
            //cout << p->prve->vaule <<" "<< p->next->vaule << '\n';
            p->prve->next = p->next;
            p->next->prve = p->prve;
            continue;
        }
    }
    printf("%d\n",p->vaule);
}//3 6 9 2 7 1 8 5 10 4

 

循环队列练习

队列是一种数据结构。现在你要支持几种操作:

  • push x,将 xx 这个元素放到队尾。

  • pop,表示将队首的元素删除。

  • query k,询问从队首往后数第 kk 个元素是多少。

输入格式

第一行一个整数 mm,表示操作个数。

接下来 mm 行,每行一个上面所述的操作。

输出格式

输出若干行,对于每个查询操作,输出答案。

#include <bits/stdc++.h>

using namespace std;
const int size1 = 1001;
int q[size1 + 1];
int n,m,front = 1,rear = size1;
char str[1011];
int main()
{
    scanf("%d",&m);
    //int x;
    for(int i = 1;i <= m;i ++)
    {
        scanf("%s",str);
        if(str[2] == 's')
        {
            int x;
            scanf("%d",&x);
            rear = rear % size1 + 1;
            q[rear] = x;
        }
        else
            if(str[0] == 'p')
                front = front % size1 + 1;
            else
            {
                int x ;
                scanf("%d",&x);
                if(front + x - 1 <= size1)
                    cout << q[front + x - 1] << '\n';
                else
                    cout << q[front + x - 1 - size1] << '\n';
            }
    }
}

 

翻转序列

给你一个1..nnn个数按顺序组成的有序链表。

需要对这个链表做mm次翻转操作,每个翻转操作会给出两个数ll, rr,表示从链表的第ll个元素到第rr个元素进行翻转。

现在问你这些操作结束完的链表序列长什么样。

输入格式

第一行读入nn和mm。

后面mm行每行给出一组(l,r)(l,r),表示要翻转的区间。

输出格式

输出最后处理完成的序列。

#include <bits/stdc++.h>

using namespace std;
struct Now{
    int vaule;
    Now *next,*prve;
}a[2001],*head,*tail;
int main()
{
    head = NULL;
    tail = NULL;
    int n,m;
    cin >> n >> m;
    for(int i = 1;i <= n;i ++ )
    {
        a[i].vaule = i;
        if(head == NULL)
        {
            head = tail = &a[i];
        }
        else
        {
            tail -> next = &a[i];
            a[i].prve = tail;
            tail = &a[i];
        }
    }
    for(int i = 1;i <= m; i ++ )
    {
        int l,r;
        cin >> l >> r;
        if(l == r)
            continue;
        Now *pl = head,*pr = head;
        for(int j = 1; j < l; j ++ )
        {
            pl = pl -> next;
        }
        for(int j = 1;j < r; j ++ )
        {
            pr = pr -> next;
        }
        Now *x = pl,*y = x -> next,*z,*u = pr->next,*v = pl->prve;
        while(x!=pr)
        {
            z = y -> next;
            y -> next = x;
            x -> prve = y;
            x = y;
            y = z;
        }
        if(head == pl)
        {
            head = pr;
            pr -> prve = NULL;
        }
        else
        {
            Now *p = v;
            p -> next = pr;
            pr -> prve = p;
        }
        if(tail == pr)
        {
            tail = pl;
            pl -> next = NULL;
        }
        else
        {
            Now *p = u;
            p ->prve = pl;
            pl ->next = p;
        }
    }
    for(Now *p = head ; p ;p = p->next)
    {
        cout << p->vaule << " ";
    }
}

 

posted @ 2022-08-09 16:28  清初  阅读(66)  评论(0)    收藏  举报