各个数据结构类型的应用

  • Post author:
  • Post category:其他







:(何时用栈?当需要“记忆”,即出现某个问题但凭现有条件不能解决,就用栈)

1.判断是否为回文字符串

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int main()
{
    char a[101],s[101];
    int i,len,mid,top=0;
    gets(a);
    len=strlen(a);
    if(len%2==0) mid=len/2;
    else mid=len/2+1;
    for(i=0;i<mid;i++)
    {
        s[++top]=a[i];//这里相当于top用来计数
    }
    for(i=mid;i<=len-1;i++)
    {
        if(a[i]!=s[top])
            break;
        top--;
    }
    if(top==0) printf("yes");
    else printf("no");
}
沿用洛谷P4387验证栈顺序的思路来判断是否为回文字符串
#include<cstdio>
#include<iostream>
#include<stack>
#include<string.h>
using namespace std;
stack<char>stk;
int main()
{
    char a[101];
    int i,len,mid;
    gets(a);
    len=strlen(a);
    if(len%2==0) mid=len/2;
    else mid=len/2+1;
    for(i=0;i<mid;i++)
        stk.push(a[i]);
    while(((int)stk.top())==((int)a[mid]))
//比较两个字符串是否相等用strcmp/strncmp,比较两个单字符是否相等,考虑比较ASCII码的值,强制转化为int型
    {
        stk.pop();mid++;
        if(stk.empty())break;//注意这里,为了防止栈空时还进行出栈操作
    }
    if(stk.empty()) cout<<"Yes";
    else cout<<"No";
    while(!q.empty())q.pop();//清空栈 
    return 0;
}
//带头结点L的链表法判断回文字符串
int dc(LinkList L, int n)
{
	int i;
	char s[n / 2 + 1];
	char* p = L->next;
	for (i = 0; i < n / 2; ++i)
	{
		s[i] = p->data;
		p = p->next;
	}
	if (n % 2 != 0) p = p->next;//如果是奇数个,那么中间的直接跳过
	while (i >= 0)
	{
		if (p->data == s[i])
		{
			--i; p = p->next;
		}
		else break;
	}
	if (i == -1) return 1;
	else return 0;
}

2.进制转换

#include<stdio.h>
#include<iostream>
#include<stack>
using namespace std;
int main()
{
    int n,k;
    cin>>n>>k;
    stack<int>stk;
    while(n==0)
    {
        cout<<0;
        return 0;
    }
    while(n)
    {
        stk.push(n%k);
        n/=k;
    }
    while(!stk.empty())
    {
        cout<<stk.top();
        stk.pop();
    }
}

3.后缀表达式(洛谷P1449)

#include<cstdio>
#include<iostream>
#include<stack>
using namespace std;
stack<int>n;
int main()
{
    char ch;
    int s = 0, x, y;
    do
    {
        ch = getchar();
        switch (ch)
        {
        case'+':x = n.top(); n.pop(); y = n.top(); n.pop(); n.push(x + y); break;
        case'-':x = n.top(); n.pop(); y = n.top(); n.pop(); n.push(y - x); break;
        case'*':x = n.top(); n.pop(); y = n.top(); n.pop(); n.push(x * y); break;
        case'/':x = n.top(); n.pop(); y = n.top(); n.pop(); 
            if (x == 0) return 0;
            else n.push(y / x); break;//排除除数为0的情况
        case'.':n.push(s); s = 0; break;
        default:s = s * 10 + ch - '0'; break;
            //这里不写s*10就不对,注意以字符形式输入数字时,多个数字是多个字符
        }
    } while (ch != '@');
    printf("%d", n.top());
    return 0;
}
//后缀表达式顺序栈法
int op(int a,char Op,int b)
{
	if (Op == '+') return (a + b);
	if (Op == '-') return (a - b);
	if (Op == '*') return (a * b);
	if (Op == '/')
	{
		if (b == 0)
		{
			cout << "ERROR";
			return 0;
		}
		else return (a / b);
	}
}
int com(char exp[])
{
	int a,b,c,i;
	char Op;
	int stack[MAXSIZE], top = -1;
	for(i=0;exp[i]!='\0';i++)
	{
		if (exp[i] >= '0' && exp[i] <= '9')
			stack[++top] = exp[i] - '0';
		else
		{
			Op = exp[i];
			b = stack[top--];
			a = stack[top--];
			c = op(a, Op, b);
			stack[++top] = c;
		}
	}
	return stack[0];
}


4.前缀表达式(大话数据结构)

//判断栈顺序,Mnzn
#include<iostream>
using namespace std;
int main()
{
    string push,pop;
    cin>>push>>pop;
    int i=0,j=0,top=-1,n=push.size();
    for(;i<n;) {
    	while(i<n && top>=0 && push[top]==pop[i])--top,++i;
    	if(j>=n) break;
    	push[++top]=push[j++];
    }
    if(top==-1) cout<<"Yes";
    else cout<<"No";
    return 0;
}
//括号是否匹配
int match(char exp[], int n)
{
	char stack[MAXSIZE];
	int top = -1;
	int i;
	for(i=0;i<n;i++)
	{
		if (exp[i] == '(')
			stack[++top] = '(';
		else if (exp[i] == ')')
		{
			if (top == -1)
				return 0;//1代表匹配0代表不匹配
			else --top;
		}
	}
	if (top == -1)//所有的括号都被处理掉
		return 1;
	else return 0;
}

也可以用switch

5.利用栈实现递归函数的非递归形式(王道考研3.3.7的第三题)

double p(int n, double x)
{
	struct stack
	{
		int n;
		double val;
	}st[maxsize];
	//对于带下标的函数,把函数值和函数的下标一起用结构体来表示
	int top = -1,i;
	double fv1 = 1, fv2 = 2 * x;
	for (i = n; i >= 2; --i)
	{
		st[++top].n = i;
	}
	while (top >= 0)
	{
		st[top].val = 2 * x * fv2 - 2 * (st[top].n - 1) * fv1;
		fv1 = fv2;
		fv2 = st[top].val;//关键地方的代换
		--top;
	}
	if (n == 0)  return fv1;//注意特殊情况,每个n都要考虑到
	return fv2;
}

行编辑程序问题

迷宫求解



队列



1.实际应用(王道考研3.3.7的2和4)



可以作为数据结构的课程设计内容

Queue q,q1,q2;
void manager()
{
	int i=0, j=0;
	while (j < 10)
	{
		if (!QueueEmpty(q1) && i < 4)
		{
			DeQueue(q1, x);
			EnQueue(q, x);
			++i; ++j;
		}
		else if (!QueueEmpty(q2))
		{
			DeQueue(q2, x);
			EnQueue(q, x);
			++j; i = 0;
		}//这两段为了满足四辆客车,一辆货车的运送
		else//当客车或者货车有一种是空
		{
			while (j<10&&i < 4 && !QueueEmpty(q2))
			{//客车空了,货车补
				DeQueue(q2, x);
				EnQueue(q, x);
				++j; ++i;
			}
			i = 0;

		}
		if (QueueEmpty(q1) && QueueEmpty(q1))
			return;
	}
}

2题的交换硬座和软座的顺序,把软座全部移到硬座之前,


用双指针非常妙



两个指针p,q都指向第一个元素,若为H,就存放到栈里,若为S,就以覆盖的形式存放到原数组中   *(q++)=p,这样节省了空间,不用另开辟新的空间



版权声明:本文为weixin_53697800原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。