数据结构与算法——队列、字符串

队列结构体

typedef struct{
    int data[maxsize];
    int front,rear;
}queue;


1.队列的基本操作

void initqueue(queue &q)
{
    q.rear=0;
    q.front=0;
}
bool isempty(queue &q)
{
    if(q.rear==q.front)
        return true;
    return false;
}
bool enqueue(queue &q,int &x)
{
    if((q.front+1)%maxsize==q.rear)
        return false;
    q.data[q.rear+1]=x;
    q.rear=(q.rear+1)%maxsize;
}
bool dequeue(queue &q,int &x)
{
    if(q.front==q.rear)
        return false;
    x=q.data[q.front];
    q.front=(q.front+1)%maxsize;
}

思想:

初始化:设置rear,front等于0

判断为空:若q.front==q.rear为空,等于0

入队:判断是否队满,若front+1正好是rear则队满。若不为队满进行入队,入队我们改变rear,只需rear+1即可,在更新rear就行。(因为是循环队列)

出队:与入队相反,我们需要判断是否为空,若不为空,我们出队,front保存的是第一个位置,我们只需要将x=q.data[q.front]即可。最后更新front


2.设置带头节点的循环链表表示队列,设有队尾指针,写出出队入队。

void enqueue(LNode* *tail,int x)
{
    LNode *p=(LNode*)malloc(sizeof(LNode));
    p->data=x;
    p->next=*tail->next;
    *tail->next=p;
    *tail=p;
}
void dequeue(LNode**tail,int &x);
{
    LNode*p=(LNode*)malloc(sizeof(LNode));
    p=tail->next;
    LNode*r=p->next;
    p->next=r->next;
    x=r->data;
    free(r);
}

思想:
入队:我们建立一个新的节点。将x值赋值给该节点。入队我们是将节点插入到最后一个位置。因而p->next=*tail->next;*tail->next=p;

tail所指向尾指针所以我们要进行更新

出队:申请空间,我们出队都是出的第一个指针,因为带头结点所有tail->next->next才是存第一个数据的节点。我们只需将它删除即可。

用p存储tail->next即头节点

r存储p->next即第一个存储元素的节点

我们只需将r释放即可。同单链表,p->next=r->next;free(r);


3.用两个栈模拟一个队列

bool enqueue(stack &s1,stack &s2,int& x)
{
    if(s1.top==maxsize-1&&s2.top!=-1)
        return false;
    if(s1.top==maxsize-1&&s2.top==-1)
    {
        while(s1.top!=-1)
        {s2.data[++s2.top]=s1.data[s1.top--];}
    }
    s1.data[++s1.top]=x;
    return true;
}
bool dequeue(stack &s1,stack &s2,int& x)
{
    if(s.top==-1&&s2.top==-1)
        return false;
    if(s.top!=-1&&s2.top==-1)
    {
        while(s1.top!=-1)
        {
            s2.data[++s2.top]=s1.data[s1.top--];
        }
        x=s2.data[top--];
    }
    return true;
}

思想:

同队列相似。我们设置了两个栈s1,s2

s1用来先把数据放进入(123),我们把第一个栈出栈(321)到第二个栈。我们在将第二个栈出栈(123)

正好满足队列先进先出。因而入队出队保存都在s2.

入队:我们先判断是否满,若s2已经是最后一个。因而无法再插入。

若s2不为最后一个,s1有元素,那么我们就可以进行入队。循环中止条件是s1.top!=-1,若等于-1则说明没有元素了。

只需要s2.data[++s2.top]=s1.data[s1.top--];

最后将最后一个元素直接入队到s2即可

出队:先判断是否为空。

不为空,我们将s1元素全部插入到s2中,最后将s2最上面元素出栈即可。


字符串


1.判断字符串是否回文

bool is_huiwen(char A[])
{    
    int len=strlen(A);
    for(int i=0;i<len/2;i++)
    {
        if(A[i]!=A[len-i-1])
            return false;
    }
    return true;
}

思想:

进行遍历将第一个和最后一个比较


2.判断子串s2是否匹配母串s1

bool match(char s1[],char s2[])
{
    int p=0;
    int pos=0;
    int p=pose;
    while(s1[p]!='\0'&&s2[q]!='\0')
    {
        if(s1[p]==s2[q])
        {
            p++;
            q++;
       
        }
        else
        {
            q=0;
            pose++;
            p=pose;
        }
    }
    if(s2[p2]=='\0')
        return true;

}

思想:

从头开始遍历字符串,我们用pose用来记录s1位置。

将s2字符串与s1比较若相同则继续比较,p++,q++

不同我们将s2从0开始,s1从下一个开始(用pose保存了)。


3.链表A和链表B,判断B是否是A的子序列

bool find(LNode*A,LNode*B)
{
    LNode* pose=A->next;
    LNode* p=pos,*q=B->next;
    while(A->next!=NULL&&B->next!=NULL)
    {
        if(A->data==B->data)
        {A=A->next;B=B->next;}
        else
        {
            pose=pose->next;
            p=pose;
            q=B->next;
        }
    }
    if(q==NULL)
        return true
    return false;
 
}

思想:

对链表遍历

pose存储第一个元素即A->next,赋值给p

q存储B第一个元素

判断是否两个都存在。

若都存在进行遍历,若节点所存元素相同,同时指向下一个节点,不同则将第一个子序列从头开始。较长序列从下一个开始遍历。

最后判断,若子序列已经到最后一个即指向空则说明成功匹配。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值