欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

线性结构,顺序表,链表,栈,队列,后缀表达式求值,简单模拟单队列排队

程序员文章站 2022-07-14 19:49:31
...

线性结构

顺序表

#include<iostream>
#include<list>
#include<vector>
#include<stack>

using namespace std;

int main() {
	vector<int> v;
	v.push_back(11);//放入11到末尾,括号内就是要放入的元素,发生一次值传递
	v.push_back(22);
	v.insert(v.begin() + 2, 666);//迭代器是顺序实现,所以可以有++也可以有+2
	v.erase(v.begin() + 1);//删除第二个元素
	
	vector<int>::iterator it;
	for (it = v.begin(); it != v.end(); it++) {//it=v.end表示表已经结束了
		cout << *it << ",";
	}
	cout << endl;
	//v.emplace_back();当拿一个类的对象作为元素加进v里面,会把对象拷贝一遍,产生一次拷贝构造,emplace_back只需要在v向量内部直接去构造
	for (int i : v) {
		cout << i << ",";
	}
	cout << endl;
	return 0;
}

链表

#include<iostream>
#include<list>
#include<vector>
#include<stack>

using namespace std;

int main() {
	list<int> a;
	a.push_back(11);
	a.push_back(22);
	a.insert(a.begin(), 666);//地址不连续,不能a.begin+k
	a.remove(11);//remove一个值
	list<int>::iterator it;
	//在这里迭代器的++是运算符的重载,迭代器的++不是一定会加值,向量的迭代器++是往后一个元素,链表的迭代器++相当于p=p->next
	for (it = a.begin(); it != a.end(); it++) {
		cout << *it << ",";
	}
	
	cout << endl;

}

#include<iostream>
#include<stack>

using namespace std;

int main() {

	stack<int> st;
	st.push(11);
	st.push(22);
	//st.pop();//弹栈,不获取值
	
	int x;
	x = st.top();
	st.top();
	cout << x << endl;

	st.empty();//C++栈的容量可以根据需求动态地扩充增加

	cout << st.size() << endl;
	return 0;
}

例:后缀式求值

我们人类习惯于书写“中缀式”,如 3 + 5 * 2 ,其值为13。 (p.s. 为什么人类习惯中缀式呢?是因为中缀式比后缀式好用么?)
而计算机更加习惯“后缀式”(也叫“逆波兰式”,Reverse Polish Notation)。上述中缀式对应的后缀式是: 3 5 2 * +
现在,请对输入的后缀式进行求值。

输入格式:
在一行中输入一个后缀式,运算数和运算符之间用空格分隔,运算数长度不超过6位,运算符仅有+ - * / 四种。

输出格式:
在一行中输出后缀式的值,保留一位小数。

输入样例:
3 5.4 2.2 * +

输出样例:
14.9

#include<iostream>
#include<string>
#include<stack>
using namespace std;
int main()
{
    double a, b;
    string str;
    stack<double> num;
    while (cin >> str) {
        char c = getchar();
        if ((str[0] >= '0' && str[0] <= '9') || isdigit(str[0])) 
            num.push(stod(str));
        }
        else {
            switch (str[0])
            {
            case '+': a = num.top();
                num.pop();
                b = num.top();
                num.pop();
                num.push(a + b);
                break;
            case '-': a = num.top();
                num.pop();
                b = num.top();
                num.pop();
                num.push(b - a);
                break;
            case '*': a = num.top();
                num.pop();
                b = num.top();
                num.pop();
                num.push(b * a);
                break;
            case '/':a = num.top();
                num.pop();
                b = num.top();
                num.pop();
                num.push(b / a);
                break;
            }
        }
        if (c == '\n') {
            break;
        }
    }
    printf("%.1f\n", num.top());
    return 0;
}

链式队列

不使用STL

#include<iostream>
using namespace std;

struct Node {
    int data;
    Node* next;
    Node(int x) {
        data = x;
        next = NULL;
    }
};

class Queue {
private:
    Node* front;
    Node* rear;
public:

    Queue() {
        front = rear = NULL;
    }
    ~Queue(){
        Node* temp;
        while (front) {
            front = front->next;
            delete temp;
        }
    }
    bool isEmpty() {
        return front == NULL;
    }

    void enQueue(int x){
        Node* temp;
        temp = new Node(x);
        if (isEmpty()) {
            front = rear = temp;
        }
        else {
            rear->next = temp;
			rear = temp;
        }
    }

    bool deQueue(int *px) {
        if (isEmpty())
            return false;
        else {
            *px = front->data;
            Node* temp;
            temp = front;
            front = front->next;
            delete temp;
            if (isEmpty())
                rear = NULL;
            return true;
        }
    }


};

int main(){
    Queue q;
    q.enQueue(11);
    q.enQueue(22);
    q.enQueue(33);
    q.enQueue(44);
    int x;
    x = 0;
    q.deQueue(&x);
    cout << x << endl;
    x = 0;
    q.deQueue(&x);
    cout << x << endl;
    x = 0;
    q.deQueue(&x);
    cout << x << endl;
    x = 0;
    q.deQueue(&x);
    cout << x << endl;
    x = 0;
    q.deQueue(&x);
    cout << x << endl;
    return 0;
}

使用STL

#include<iostream>
#include<queue>
using namespace std;

int main() {
    queue<int> q;
    q.push(11);
    q.push(22);
    q.emplace(33);
    cout << q.front() << endl;
    q.pop();
    cout << q.front() <<endl;
    q.pop();
    cout << q.front() << endl;
}

例:简单模拟单队列排队

用程序简单模拟一个单队列多窗口的排队模式:
设某银行有一个固定能容纳N个顾客的等候区,顾客想进银行,若等候区有空则可进,否则被拒绝进入。
每当银行柜员叫号时,等候区中最先进入的顾客离开等候区前往柜台办理业务,若叫号时等候区无人,则此次叫号作废。

输入格式:
第一行输入一个不大于20的正整数N,表示银行等候区能容纳的人数,
接下来用若干行表示依时间顺序先后发生的“顾客想进银行”或“叫号”事件,格式分别是:

顾客想进银行,用 In 表示,其中是顾客编号,为不大于100000的正整数;
叫号,用Calling表示。
最后一行是一个#符号,表示输入结束。
注意:

题目输入保证每个顾客的编号是独一无二的,即:不会出现想进银行的顾客与已经在等候区的顾客编号相同的情况。
保证后一个事件一定在前一个事件完成之后才发生,即:不需要考虑事件之间的“同步”问题。
输出格式:
对于输入的每个事件,按同样顺序在一行内输出事件的结果,格式分别是:

顾客想进银行,若顾客进入,则输出 joined. Total: 其中是该顾客的编号,是顾客进入后,等候区的人数
顾客想进银行,若因等候区满而被拒绝,则输出 rejected. 其中是该顾客的编号
叫号,若有顾客前往柜台,则输出 called. Total: 其中是该顾客的编号,是顾客去柜台后,等候区的人数
叫号,等候区无人,则输出 No one!
输入样例:
3
In 101
In 102
In 103
In 104
Calling
In 105
Calling
Calling
Calling
Calling

输出样例:
101 joined. Total:1
102 joined. Total:2
103 joined. Total:3
104 rejected.
101 called. Total:2
105 joined. Total:3
102 called. Total:2
103 called. Total:1
105 called. Total:0
No one!

使用C语言

#include<stdio.h>
#include<stdlib.h>

struct Queue {
    int* data;
    int capacity;
    int front;
    int rear;
    int size;
};

void init(struct Queue* pq, int capacity) {
    pq->capacity = capacity;
    pq->data = (int*)malloc(sizeof(int) * (capacity + 1));
    pq->front = pq->rear = pq->size = 0;
}

int isFull(const struct Queue* pq) {
    if ((pq->rear + 1) % (pq->capacity + 1) == pq->front)
        return 1;
    else
        return 0;
}

int isEmpty(const struct Queue* pq) {
    return pq->front == pq->rear;
}

int enQueue(struct Queue* pq, int x) {
    if (isFull(pq))
        return 0;
    else {
        pq->data[pq->rear] = x;
        pq->rear = (pq->rear + 1) % (pq->capacity + 1);
        pq->size++;
        return 1;
    }
}

int deQueue(struct Queue* pq, int* px) {
    if (isEmpty(pq))
        return 0;
    else {
        *px = pq->data[pq->front];
        pq->front = (pq->front + 1) % (pq->capacity + 1);
        pq->size--;
        return 1;
    }
}

int main() {
    int N;
    scanf_s("%d", &N);
    struct Queue q;
    init(&q, N);
    char op[20];
    int id;
    scanf_s("%s", op);
    while (op[0] != '#') {
        if (op[0] == 'I') {
            scanf_s("%d", &id);
            if (isFull(&q)) {
                printf_s("%d rejected.\n", id);
            }
            else {
                enQueue(&q, id);
                printf_s("%d joined. Total:%d\n", id, q.size);
            }
        }
        else {
            if (isEmpty(&q)) {
                printf_s("No one!\n");
            }
            else {
                deQueue(&q, &id);
                printf_s("%d called. Total:%d\n", id, q.size);
            }
        }

    }
    return 0;
}

使用C++语言

#include<iostream>
#include<queue>
using namespace std;

int main() {
    int N;
    cin >> N;
    queue<string> q;
    string op, id;
    cin >> op;
    while (op != "#") {//C++可以这样比较string
        if (op == "In") {
            cin >> id;
            if (q.size() == N)
                cout << id << " rejected." << endl;
            else {
                q.push(id);
                cout << id << " joined. Total:" << q.size() << endl;
            }
        }
        else {
            if (q.empty()) {
                cout << "No one!" << endl;
            }
            else {
                id = q.front();
                q.pop();
                cout << id << " called. Total:" << q.size() << endl;
            }
        }
        cin >> op;
    }
    return 0;
}