一、队列、栈
作者在书中用数组来实现队列和栈,让我们更深刻地了解了底层实现。而这里我就直接放用STL里的queue和stack实现书中题目的代码了。
题目:纸牌游戏。
两人比赛,A,B,每人最开始分得6张手牌,手牌大小为从1到9
A先出牌,B后出牌,若出牌在桌面上存在,在出牌人获得两张相同牌中间的所有牌(包括两张相同牌),放入出牌人手中。
最后谁手中无牌判为负
C++:
#include<iostream>
#include<queue>
#include<stack>
using namespace std;
int main()
{
queue<int> q1, q2; //手上的牌
stack<int> st; //桌上的牌
int n;
int book[10] = { 0 }; //因为约定了牌面只有1~9
for (int i = 0; i != 6; ++i) {
cin >> n;
q1.push(n);
}
for (int i = 0; i != 6; ++i) {
cin >> n;
q2.push(n);
}
while (!q1.empty() && !q2.empty()) {
int tmp = q1.front();
if (book[tmp] == 0) {
q1.pop();
st.push(tmp);
book[tmp] = 1;
}
else {
q1.pop();
q1.push(tmp);
while (st.top() != tmp) {
book[st.top()] = 0;
q1.push(st.top());
st.pop();
}
book[st.top()] = 0;
q1.push(st.top());
st.pop();
}
if (q1.empty()) //此时若q1已经出完牌了应马上结束,阻止后面q2的操作,这时q2和桌上的牌才是最终的
break;
int tmp2 = q2.front();
if (book[tmp2] == 0) {
q2.pop();
st.push(tmp2);
book[tmp2] = 1;
}
else {
q2.pop();
q2.push(tmp2);
while (st.top() != tmp2) {
book[st.top()] = 0;
q2.push(st.top());
st.pop();
}
book[st.top()] = 0;
q2.push(st.top());
st.pop();
}
}
if (q1.empty()) {
cout << "q2 wins!" << endl;
cout << "手上的牌是 ";
while (!q2.empty()) {
cout << q2.front() << " ";
q2.pop();
}
cout << "\n桌上的牌是 ";
while (!st.empty()) {
cout << st.top() << " ";
st.pop();
}
cout << endl;
}
else {
cout << "q1 wins!" << endl;
cout << "手上的牌是 ";
while (!q1.empty()) {
cout << q1.front() << " ";
q1.pop();
}
cout << "\n桌上的牌是 ";
while (!st.empty()) {
cout << st.top() << " ";
st.pop();
}
cout << endl;
}
system("pause");
}
一定要注意 q1为空马上break!
Java:
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
import java.util.Stack;
public class Game {
public static void main(String[] args) {
Stack<Integer> desk = new Stack<>();
Queue<Integer> q1 = new LinkedList();
Queue<Integer> q2 = new LinkedList();
int book[] = new int[10];
Scanner sc = new Scanner(System.in);
//发牌,每人6张
for (int i = 0; i < 6; i++) {
q1.add(sc.nextInt());
}
for (int i = 0; i < 6; i++) {
q2.add(sc.nextInt());
}
while (!q1.isEmpty() && !q2.isEmpty()) {
int ta = q1.peek();
if (book[ta] == 0) {
desk.add(q1.remove());
book[ta] = 1;
}
else {
q1.add(q1.remove());
while (desk.lastElement() != ta) {
book[desk.lastElement()] = 0;
q1.add(desk.lastElement());
desk.pop();
}
q1.add(desk.lastElement());
book[desk.lastElement()]=0;
desk.pop();
}
if(q1.isEmpty())
break;
int tb = q2.peek();
if (book[tb] == 0) {
desk.add( q2.remove());
book[tb] = 1;
}
else {
q2.add(q2.remove());
while (desk.lastElement() != tb) {
book[desk.lastElement()] = 0;
q2.add(desk.lastElement());
desk.pop();
}
q2.add(desk.lastElement());
book[desk.lastElement()]=0;
desk.pop();
}
}
if (q1.isEmpty()) {
System.out.println("q2 wins");
System.out.print("q2手中的牌为:");
while (!q2.isEmpty()) {
System.out.print(q2.remove() + " ");
}
}
else {
System.out.println("q1 wins");
System.out.print("q1手中的牌为:");
while (!q1.isEmpty()) {
System.out.print(q1.remove() + " ");
}
}
System.out.print("\n桌子上的牌为:");
while (!desk.isEmpty()) {
System.out.print(desk.pop() + " ");
}
}
}
二、链表与模拟链表
1、链表:在C语言中,可以用指针和malloc实现链表,将一个值和一个指向下一个结点地指针封装在一个struct结构体中即是一个结点。
#include<iostream>
#include<cstdlib>
using namespace std;
struct node
{
int data;
struct node *next;
};
int main()
{
struct node *head, *p, *q = NULL, *t;
int n, a;
cin >> n;
head = NULL;
for (int i = 0; i != n; ++i) {
cin >> a;
p = (struct node*)malloc(sizeof(struct node));
p->data = a;
p->next = NULL;
if (head == NULL)
head = p;
else
q->next = p; //q为上一个节点
q = p; //将q更新为这一节点
}
//插入数字
cin >> a;
t = head;
while (t != NULL) {
if (t->next == NULL || t->next->data > a) {
p = (struct node*)malloc(sizeof(struct node));
p->data = a;
p->next = t->next;
t->next = p;
break;
}
t = t->next;
}
//输出链表的所有数字
t = head;
while (t != NULL) {
cout << t->data<<" ";
t = t->next;
}
system("pause");
}
2、模拟链表:若不想使用指针,也可使用两个数组。一个数组储存值,一个数组储存该值的下一个元素在数组中的位置。
#include<iostream>
using namespace std;
int main()
{
int data[101], right[101];
int n, num, t, len;
cin >> n;
for (int i = 0; i != n; ++i) {
cin >> num;
data[i] = num;
}
len = n;
for (int i = 0; i != n; ++i) {
if (i != n - 1)
right[i] = i + 1;
else
right[i] = -1; //说明后面无元素了
}
cin >> num; //添加一个元素
data[len] = num;
//遍历链表
t = 0;
while (t != -1) {
if (data[right[t]] > data[len]) { //插入元素
right[len] = right[t];
right[t] = len;
break;
}
t = right[t];
}
t = 0;
while (t != -1) {
cout << data[t] << " ";
t = right[t];
}
system("pause");
}