栈和队列Oj习题

顺序栈

#include
using namespace std;
const int StackSize = 5; //顺序栈的最大长度(请勿改动)
template <class T>       //定义模板类SeqStack
class SeqStack
{
public:
    SeqStack();            //构造函数,栈的初始化
    ~SeqStack();            //析构函数
    void Push(T x);          //将元素x入栈
    T Pop();                //将栈顶元素弹出
    T GetTop();            //取栈顶元素(并不删除)
    bool Empty();           //判断栈是否为空
private:
    T data[StackSize];      //存放栈元素的数组
    int top;                //栈顶指针,指示栈顶元素在数组中的下标
};

/*
 * 前置条件:栈不存在
 * 输    入:无
 * 功    能:栈的初始化
 * 输    出:无
 * 后置条件:构造一个空栈
 */
template <class T>
void SeqStack<T>::Push(T x)
{
    if (top + 1 != StackSize)
        data[++top] = x;
    else
    {
        //cout<<"Push:Overflow"<
        throw "Overflow";
    }

}
template <class T>
T SeqStack<T>::Pop()
{
    /*if (top == -1)
    {
        throw"Downflow";
    }*/
    T x;
    x = data[top--];

    return x;

}
template <class T>
T SeqStack<T>::GetTop()
{
    if (top == -1)
    {
        throw"Downflow";
    }
    T x;
    x = data[top];
    return x;
}
template <class T>
bool SeqStack<T>::Empty()
{
    if (top == -1)
    {
        return true;
    }
    return false;
}
template <class T>
SeqStack<T>::SeqStack()
{
    top = -1;
}

/*
 * 前置条件:栈已存在
 * 输    入:无
 * 功    能:销毁栈
 * 输    出:无
 * 后置条件:释放栈所占用的存储空间
 */

template <class T>
SeqStack<T>::~SeqStack()
{
}
int main()
{
    SeqStack<int> s;
    int x;
    while (1)
    {
        cin >> x;
        if (!x) break;
        try {
            s.Push(x);
        }
        catch (const char* ms) {
            cout << "Push:" << ms << endl;
        }
    }
    cout << "Gettop:" << s.GetTop() << endl;

    while (!s.Empty())
    {
        cout << s.Pop() << " ";
    }
    cout << endl;
    try {
        cout << "Gettop:" << s.GetTop() << endl;
    }
    catch (const char* ms) {
        cout << "Gettop:" << ms << endl;
    }
    return 0;
}

链式栈

#include
using namespace std;
template <class T>
struct Node
{
    T data;
    Node<T>* next;
};
template <class T>
class LinkStack
{
public:
    LinkStack();              //构造函数,置空链栈
    ~LinkStack();             //析构函数,释放链栈中各结点的存储空间
    void Push(T x);           //将元素x入栈
    T Pop();                  //将栈顶元素出栈
    T GetTop();               //取栈顶元素(并不删除)
    bool Empty();             //判断链栈是否为空栈
private:
    Node<T>* top;             //栈顶指针即链栈的头指针
};

/*
 * 前置条件:栈不存在
 * 输    入:无
 * 功    能:栈的初始化
 * 
 * 输    出:无
 * 后置条件:构造一个空栈
 */

template <class T>
LinkStack<T>::LinkStack()
{
    top = NULL;
}
template <class T>
LinkStack<T>::~LinkStack()
{
    //Node* p = top->next;
    while (top != NULL)
    {
        Node<T>* p = top;
        top = top->next;
        //top->next = top->next->next;
        delete p;
    }

}
template <class T>
void LinkStack<T>::Push(T x)
{
    Node<T>* p = new Node<T>;
    p->data = x;
    /*p->next = top->next;
    top->next = p;*///第一次写错
    p->next = top;//将p指向的相应空间均赋值    指针间赋值
    top = p;//top指向最顶端元素
}
template <class T>
T LinkStack<T>::Pop()
{
    Node<T>* p = top;
    T x = p->data;
    top = p->next;
    delete p;
    return x;
}
template <class T>
T LinkStack<T>::GetTop()
{
    if (top == NULL)
        throw"Downflow";
    
    
        Node<T>* p = top;
        T x = p->data;
        return x;
    
}
template <class T>
bool LinkStack<T>::Empty()
{
    if (top == NULL)return true;
    return false;
}
int main()
{
    LinkStack<char> s;
    char ch;
    while (1)
    {
        cin >> ch;
        if (ch == '#') break;
        s.Push(ch);
    }
    cout << "Gettop:" << s.GetTop() << endl;
    while (!s.Empty())
    {
        cout << s.Pop() << " ";
    }
    cout << endl;
    try {
        cout << "Gettop:" << s.GetTop() << endl;
    }
    catch (const char* ms) {
        cout << "Gettop:" << ms << endl;
    }
    return 0;
}

链式队列

#include
using namespace std;
template <class T>
struct Node
{
    T data;
    Node<T>* next;
};
template <class T>
class LinkQueue
{
public:
    LinkQueue();      //构造函数,初始化一个仅有头结点的空队列
    ~LinkQueue();      //析构函数,释放链队列中各结点的存储空间
    void EnQueue(T x);  //将元素x入队
    T DeQueue();       //将队头元素出队,若队列为空,抛出异常“Downflow”,否则函数返回值为队头元素值
    T GetQueue();     //取链队列的队头元素,若队列为空,抛出异常“Downflow”,否则函数返回值为队头元素值
    bool Empty();     //判断链队列是否为空,为空返回true,否则返回false
private:
    Node<T>* front, * rear;  //队头和队尾指针,分别指向头结点和终端结点
};
/*
 * 前置条件:队列不存在
 * 输    入:无
 * 功    能:初始化队列
 * 输    出:无
 * 后置条件:创建一个空队列
 */
template <class T>
LinkQueue<T>::LinkQueue()
{

    front = rear = new Node<T>;

    rear->next = NULL;

}
/*
 * 前置条件:队列存在
 * 输    入:无
 * 功    能:销毁队列
 * 输    出:无
 * 后置条件:释放队列所占用的存储空间
 */
template <class T>
LinkQueue<T>::~LinkQueue()
{
    while (front)
    {
        Node <T>* p;
        p = front->next;
        delete front;
        front = p;
    }
}
template <class T>
void LinkQueue<T>::EnQueue(T x)
{
    Node<T>* p = new Node<T>;
    p->data = x;
    p->next = NULL;
    rear->next = p;
    rear = p;
}

template <class T>
T LinkQueue<T>::DeQueue()
{
    if (front == rear)throw"Downflow";
    Node<T>*p = front->next;
    T x = p->data;
    front->next = p->next;
    if (front->next == NULL)rear = front;
    delete p;
    
    return x;
}
template <class T>
T LinkQueue<T>::GetQueue()
{
    if (front == rear)throw"Downflow";
    Node<T>*p = front->next;
    T x = p->data;
    return x;
}
/*
 * 前置条件:队列已存在
 * 输    入:无
 * 功    能:判断队列是否为空
 * 输    出:如果队列为空,返回true,否则,返回false
 * 后置条件:队列不变
 */
template <class T>
bool LinkQueue<T>::Empty()
{
    return front == rear;
}
int main()
{
    LinkQueue <int> Q1;
    int x;
    while (1)
    {
        cin >> x;
        if (!x) break;
        Q1.EnQueue(x);
    }
    cout << "DeQueue:";
    while (!Q1.Empty())
    {
        x = Q1.DeQueue();
        cout << x << " ";
    }
    try {
        x = Q1.DeQueue();
        cout << x << " ";
    }
    catch (const char* ms)
    {
        cout << ms << endl;
    }
    cout << "GetQueue:";
    try {
        x = Q1.GetQueue();
        cout << x << " ";
    }
    catch (const char* ms)
    {
        cout << ms << endl;
    }
    return 0;
}

循环队列

#include 
#include 
using namespace std;
const int QueueSize = 5;
template <class T>        //定义模板类CirQueue
class CirQueue
{
public:
    CirQueue();                 //构造函数,置空队
    ~CirQueue();               //析构函数
    void EnQueue(T x);           //将元素x入队,队满时抛出异常信息Overflow
    T DeQueue();                //将队头元素出队,队空抛出异常信息Downflow
    T GetQueue();               //取队头元素(并不删除),队空抛出异常信息Downflow
    bool Empty();               //判断队列是否为空,空返回true,否则返回false
    bool Full();                 //判断队列是否为满,满返回true,否则返回false
private:
    T data[QueueSize];           //存放队列元素的数组
    int front, rear;    //队头和队尾指针,分别指向队头元素所在数组的前一下标和队尾元素的数组下标
};
/*
 * 前置条件:队列不存在
 * 输    入:无
 * 功    能:初始化队列
 * 输    出:无
 * 后置条件:创建一个空队列
 */
template <class T>
CirQueue<T>::CirQueue()
{
    front = rear = QueueSize - 1;
}
/*
 * 前置条件:队列已存在
 * 输    入:无
 * 功    能:销毁队列
 * 输    出:无
 * 后置条件:释放队列所占用的存储空间
 */
template <class T>
CirQueue<T>::~CirQueue()
{
}
/*
 * 前置条件:队列已存在
 * 输    入:无
 * 功    能:判断队列是否为空
 * 输    出:如果队列为空,返回1,否则,返回0
 * 后置条件:队列不变
 */
template <class T>
void CirQueue<T>::EnQueue(T x)
{
    if ((rear + 1) % QueueSize == front)
    {
        throw"Overflow";
    }
    rear = (rear + 1) % QueueSize;//为什么要%QueueSize.因为rear和front都执行+操作,要保证这两个数都不能大于QueueSize
    data[rear] = x;
}
template <class T>
T CirQueue<T>::DeQueue()
{
    if (rear == front)
    {
        throw"Downflow";
    }
    front = (front + 1) % QueueSize;
    return data[front];

}
template <class T>
T CirQueue<T>::GetQueue()
{
    if (rear == front)
    {
        throw"Downflow";
    }
    return data[(front + 1) % QueueSize];
}
template <class T>
bool CirQueue<T>::Empty()
{
    return front == rear;
}
/*
 * 前置条件:队列已存在
 * 输    入:无
 * 功    能:判断队列是否为满
 * 输    出:如果队列为满,返回1,否则,返回0
 * 后置条件:队列不变
 */
template <class T>
bool CirQueue<T>::Full()
{
    return (rear + 1) % QueueSize == front;
}
int main()
{
    CirQueue<string> Q;
    string x;
    while (1) {
        cin >> x;
        if (x == "#") break;
        try {
            cout << "EnQueue:";
            Q.EnQueue(x);
            cout << x << "\n";
        }
        catch (const char* ms)
        {
            cout << x << " " << ms << endl;
        }
    }
    while (!Q.Empty())
    {
        x = Q.DeQueue();
        cout << "DeQueue:" << x << endl;
    }
    try {
        x = Q.GetQueue();
    }
    catch (const char* ms)
    {
        cout << "GetQueue:The queue is empty," << ms << endl;
    }
    return 0;
}

循环队列2

注意

队头指针是指向队头元素所在数组的前一下标和对位的元素的数组下标。

实现

#include 
#include 
using namespace std;
const int QueueSize = 5;
template <class T>        //定义模板类CirQueue
class CirQueue
{
public:
    CirQueue();                 //构造函数,置空队
    ~CirQueue();                //析构函数
    void EnQueue(T x);           //将元素x入队
    T DeQueue();                //将队头元素出队
    T GetQueue();               //取队头元素(并不删除)
    bool Empty();               //判断队列是否为空,空返回true,否则返回false
    bool Full();                 //判断队列是否为满,满返回true,否则返回false
private:
    T data[QueueSize];           //存放队列元素的数组
    int front, rear;    //队头和队尾指针,分别指向队头元素所在数组的前一下标和队尾元素的数组下标
    int count;          //记录队列中数据个数
};
/*
 * 前置条件:队列不存在
 * 输    入:无
 * 功    能:初始化队列
 * 输    出:无
 * 后置条件:创建一个空队列
 */
template <class T>
CirQueue<T>::CirQueue()
{
    front = rear = QueueSize - 1;
    count = 0;
}
/*
 * 前置条件:队列已存在
 * 输    入:无
 * 功    能:销毁队列
 * 输    出:无
 * 后置条件:释放队列所占用的存储空间
 */
template <class T>
CirQueue<T>::~CirQueue()
{
}
/*
 * 前置条件:队列已存在
 * 输    入:无
 * 功    能:删除队头元素
 * 输    出:如果删除成功,返回被删元素值,否则,抛出删除异常
 * 后置条件:如果删除成功,队头减少了一个元素
 */
template <class T>
void CirQueue<T>::EnQueue(T x)
{
    if (Full()) { throw"Overflow"; }
    rear = (rear + 1) % QueueSize;
    data[rear] = x;
    count++;
}
template <class T>
bool CirQueue<T>::Empty()
{
    if (count == 0)return true;
    return false;
}
template <class T>
bool CirQueue<T>::Full()
{
    if (count == QueueSize)return true;
    return false;
}
template <class T>
T CirQueue<T>::DeQueue()
{
    if (Empty()) throw "Downflow";
    count--;
    front = (front + 1) % QueueSize;    //队头指针在循环意义下加1
    return data[front];             //读取并返回出队前的队头元素,注意队头指针
}

/*
 * 前置条件:队列已存在
 * 输    入:无
 * 功    能:读取队头元素
 * 输    出:若队列不空,返回队头元素
 * 后置条件:队列不变
 */
template <class T>
T CirQueue<T>::GetQueue()
{
    int i;
    if (Empty()) throw "Downflow";
    i = (front + 1) % QueueSize;  //注意不要给队头指针赋值
    return data[i];
}
int main()
{
    CirQueue<string> Q;
    string x;
    while (1) {
        cin >> x;
        if (x == "#") break;
        try {
            cout << "EnQueue:";
            Q.EnQueue(x);
            cout << x << "\n";
        }
        catch (const char* ms)
        {
            cout << x << " " << ms << endl;
        }
    }
    while (!Q.Empty())
    {
        x = Q.DeQueue();
        cout << "DeQueue:" << x << endl;
    }
    try {
        x = Q.GetQueue();
    }
    catch (const char* ms)
    {
        cout << "GetQueue:The queue is empty," << ms << endl;
    }
    return 0;
}

进制转换问题

提示

参考十进制转二进制的方式

实现

#include
using namespace std;
void Convert(int num, int d)
{
	vector<int> v1;
	int count = 0;
	while (num)
	{
		v1.push_back(num % d);
		num = num / d;
		count++;
	}
	for (int i = count-1; i >= 0; i--)
	{
		cout << v1[i];
	}
}
int main()
{
	int m, n;
	cin >> m >> n;
	Convert(m, n);
	return 0;
}

表达式求值

题目思路

compare()
用switch
当新输入的符号优先级大于前面的符号时 return 1
小于return - 1 等于return 0

suan()
先遍历整个字符串
定义两个栈,一个存数字,一个存运算符
遇到数字,放到数字栈
遇到运算符,compare = 1时放到数字栈暂存(我最优先,不能让前面的符号先运算)
= -1 我不行,先让前面的先算
= 0 这就是 )碰( 和 #碰# 的时候了,直接把前面的符号删了就好
利用switch进行具体运算

实现

#include
using namespace std;

//+ < */ % (
//* < (
//% < (
//( < NULL
//) < ALL
class Expression
{
private:
	int Comp(char str1, char str2);
	string str;
public:
	Expression(string str)
	{
		this->str = str + "#";
	}
	~Expression()
	{

	}
	int suan()
	{
		int num[100];char  sign[100];
		sign[0] = '#';
		int top1 = -1, top2 = 0;
		int i, k, x, y, z, op,s;//为什么op是int类型??char有两种存在形式 如 '1'和48
		for (i = 0; str[i] != '\0'; )
		{
			if (str[i] >= 48 && str[i] <= 57)
			{
				s = 0;
				s= str[i++] - 48;
				while (str[i] >= 48 && str[i] <= 57)
				{
					s = s * 10 + str[i++] - 48;
				}
				
				num[++top1] = s;
			}
			else
			{
				k = compare(str[i], sign[top2]);
				if (k == 1)
				{
					sign[++top2] = str[i++];
				}
				else if (k == -1)
				{
					y = num[top1--];
					x = num[top1--];
					op = sign[top2--];
					switch (op)
					{
					case'+':z = x + y; break;
					case'-':z = x - y; break;
					case'*':z = x * y; break;
					case'/':z = x / y; break;
					case'%':z = x % y; break;
					default:break;

					}
					num[++top1] = z;
				}
				else
				{
					top2--;
					i++;
				}
			}
		}
		return num[top1];

	}

	int compare(char str1, char str2)
	{
		switch (str1)
		{
			case'+':case'-':if (str2 == '(' || str2 == '#')return 1;
				   else return -1; break;
			case'*':case'/':case'%':if (str2 == '*' || str2 == '/' || str2 == '%')return -1;
				   else return 1; break;
			case'(':return 1; break;
			case')':if (str2 == '(')return 0;
				   else return -1; break;
			case'#':if (str2 == '#')return 0;
				   else return -1; break;

		default:
			break;
		}
	}
};
int main()
{
	string str;
	cin >> str;
	Expression E{ str };
	int result = E.suan();
	cout << result << endl;
	return 0;
}

1050: 线性结构14

Sample Input

ABCDEFG#

Sample Output

Pop:G F E D C B A

代码示例

#include
using namespace std;
template <class T>
struct Node
{
    T data;
    Node<T>* next;
};
template <class T>
class Stack
{
public:
    Stack();              //构造函数,置空链栈(有头结点)
    ~Stack();             //析构函数,释放链栈中各结点的存储空间
    void Push(T x);        //将元素x入栈
    T Pop();              //将栈顶元素出栈
    bool Empty();         //判断链栈是否为空栈
private:
    Node<T>* top;         //栈顶指针即链栈的头指针
};
template <class T>
void Stack<T>::Push(T x)
{
    Node<T>* s = new Node<T>;
    s->data = x;
    s->next = top->next;
    top->next = s;
}
template <class T>
bool Stack<T>::Empty()
{
    if (top->next)return false;
    return true;
}
/*
 * 前置条件:栈不存在
 * 输    入:无
 * 功    能:栈的初始化
 * 输    出:无
 * 后置条件:构造一个空栈
 */
template <class T>
Stack<T>::Stack()
{
    top = new Node<T>;
    top->next = NULL;
}
/*
 * 前置条件:栈已存在
 * 输    入:无
 * 功    能:销毁栈
 * 输    出:无
 * 后置条件:释放栈所占用的存储空间
 */
template <class T>
Stack<T>::~Stack()
{
    while (top)
    {
        Node<T>* p;
        p = top->next;
        delete top;
        top = p;
    }
}
/*
 * 前置条件:栈已存在
 * 输    入:无
 * 功    能:删除栈顶元素
 * 输    出:如果删除成功,返回被删元素值,否则,抛出异常
 * 后置条件:如果删除成功,栈顶减少了一个元素
 */
template <class T>
T Stack<T>::Pop()
{
    Node<T>* p;
    int x;
    if (top->next == NULL) throw "Downflow";
    x = top->next->data;            //暂存栈顶元素
    p = top->next;
    top->next = p->next;         //将栈顶结点摘链
    delete p;
    return x;
}

int main()
{
    Stack<char> s;
    char ch;
    while (1)
    {
        cin >> ch;
        if (ch == '#') break;
        s.Push(ch);
    }
    cout << "Pop:";
    while (!s.Empty())
    {
        cout << s.Pop() << " ";
    }
    cout << endl;
    return 0;
}

1051: 线性结构05

Sample Input

1 2 3 4 5 6 7 0

Sample Output

6 Overflow
7 Overflow
DeQueue:1 2 3 4 5

代码示例

#include 
using namespace std;
const int QueueSize = 5;
template <class T>        //定义模板类Queue
class Queue
{
public:
    Queue();              //构造函数,置空队
    ~Queue();             //析构函数
    void EnQueue(T x);     //将元素x入队
    T DeQueue();          //将队头元素出队
    bool Empty();         //判断队列是否为空,空返回true,否则返回false
    bool Full();           //判断队列是否为满,满返回true,否则返回false
private:
    T data[QueueSize];    //存放队列元素的数组
    int front, rear;     //队头和队尾指针,分别指向队头元素所在数组的前一下标和队尾元素的数组下标
    int count;         //队列中元素个数
};

/*
 * 前置条件:队列不存在
 * 输    入:无
 * 功    能:初始化队列
 * 输    出:无
 * 后置条件:创建一个空队列
 */

template <class T>
Queue<T>::Queue()
{
    front = rear = QueueSize - 1;
    count = 0;
}

/*
 * 前置条件:队列已存在
 * 输    入:无
 * 功    能:销毁队列
 * 输    出:无
 * 后置条件:释放队列所占用的存储空间
 */

template <class T>
Queue<T>::~Queue()
{
}

/*
 * 前置条件:队列已存在
 * 输    入:元素值x
 * 功    能:在队尾插入一个元素
 * 输    出:如果插入不成功,抛出异常
 * 后置条件:如果插入成功,队尾增加了一个元素
 */

template <class T>
void Queue<T>::EnQueue(T x)
{
    if (Full())throw("Overflow");
    count++;
    rear = (rear + 1) % QueueSize;
    data[rear] = x;
}

/*
 * 前置条件:队列已存在
 * 输    入:无
 * 功    能:删除队头元素
 * 输    出:如果删除成功,返回被删元素值,否则,抛出删除异常
 * 后置条件:如果删除成功,队头减少了一个元素
 */

template <class T>
T Queue<T>::DeQueue()
{
    count--;
    front = (front + 1) % QueueSize;
    return data[front];
}



/*
 * 前置条件:队列已存在
 * 输    入:无
 * 功    能:判断队列是否为空
 * 输    出:如果队列为空,返回1,否则,返回0
 * 后置条件:队列不变
 */

template <class T>
bool Queue<T>::Empty()
{
    if (count == 0)return true;
    return false;

}
/*
 * 前置条件:队列已存在
 * 输    入:无
 * 功    能:判断队列是否为满
 * 输    出:如果队列为满,返回1,否则,返回0
 * 后置条件:队列不变
 */

template <class T>
bool Queue<T>::Full()
{
    if (count == QueueSize)return true;
    return false;
}
int main()
{
    Queue<int> Q;
    int x;
    while (1) {
        cin >> x;
        if (x == 0) break;
        try {
            Q.EnQueue(x);
        }
        catch (const char* ms)
        {
            cout << x << " " << ms << endl;
        }

    }
    cout << "DeQueue:";
    while (!Q.Empty())
    {
        x = Q.DeQueue();
        cout << x << " ";
    }
    return 0;
}

你可能感兴趣的:(oj习题,队列,指针,数据结构)