数据结构 | C++ |栈和队列的基本操作

本文只涉及链栈和链队列

1.栈由于其只在栈顶出、入的特性,因此不需要空的头节点

2.队列可以写或不写头节点,考虑到它和链表非常像,我还是愿意写上.

    2.1链队和链表的共性与区别:

          共性:队列的front指针==链表的elem指针,都指向头节点

          区别:链队多了个一直指向队尾,不断因入队递增的rear指针

 

实验要求:

 

 

代码:

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

//节点类
struct Node
{
	int score;
	Node *next;
};

//定义一个链队列
class  LinkQueue
{
public:
	LinkQueue();//构造函数
	void EnQueue(int score);
	int  DeQueue();
	void ShowQueue();
private:
	Node *front;//队头指针
	Node *rear;//队尾指针
};

LinkQueue::LinkQueue()
{
	front = rear = new Node;//队列有空的头节点
	if (!front)exit(OVERFLOW);

	front->next = NULL;//指针不置空很危险
}

//入队
void LinkQueue::EnQueue(int score)
{
	Node *p = new Node;
	if (!p)exit(OVERFLOW);

	p->score = score;//为新节点赋值
	p->next = NULL;

	rear->next = p;//入队
	rear = rear->next;//rear指针永远指向队尾
}

//出队
int LinkQueue::DeQueue()
{
	if (rear == front) { cout << "是空表"; }

	int score;
	Node *p = front->next;//指向队头的第一个函数
	score = p->score;
	front->next = p->next;

	if (rear == p) { rear = front; }//如果队只剩下一个元素
	delete p;
	return score;
}

//遍历函数
void LinkQueue::ShowQueue()
{
	Node *p = front->next;
	if (front == rear) { cout << "是空队!"; }

	while (p)
	{
		cout << p->score << "	";
		p = p->next;
	}

}


//--------------------------------------------------------------------------------------------------------------------
//定义一个链栈类
class LinkStack 
{
public:
	LinkStack();                            //构造参数

	void IsEmpty();                         //判空函数

	void Push(int x);                       //压栈

	int GetTop(int e);                      //取栈顶元素

	int  Pop();                             //出栈

	void ShowStack();                       //遍历函数

	void MakeEmpty();


private:
	Node *top;                       //栈顶指针
	Node *base;                      //栈底指针
	};

//构造函数

LinkStack::LinkStack()
{
	base =NULL;                  //修改前:base= new Node[100];意思是创建了一个像链表中的头节点.
								//压栈时元素是这样的:NULL->a1->a2->a3.遍历时按栈顶遍历:a3->a2->a1->NULL;就会报错.
	                            //所以,栈不需要头节点
	top = base;
		
}

//判空函数
void LinkStack::IsEmpty()
{
	if (top == NULL)
		cout << "是空栈\n";
	else
		cout << "非空栈\n";
}

//压栈函数
void LinkStack::Push(int x)
{
	Node *p = new Node;
	if (!p)exit(OVERFLOW);

	p->score = x;
	p->next=top;//新节点的next指向 原栈的top指针(所指向的栈顶元素)
	top = p;    //top指针指向 p(所指向的新节点),等于top++
}

//取栈顶元素
int LinkStack::GetTop(int e)
{
	if (top == NULL) { cout << "是空栈,无法取栈顶\n"; }

	e = top->score;
	return e;

}

//出栈函数
int LinkStack::Pop()//输值时需要形参,取值不需要形参
{
	int x;
	Node *p = top;
	if (top == NULL) { cout << "是空栈,无法取栈顶\n"; }

	top = p->next;
	x = p->score;
	delete p;
	return x;
}

//栈遍历函数
void LinkStack::ShowStack()
{
	Node *p = top;
	while (p)
	{
		cout << p->score << endl;
		p = p->next;
	}
	cout << endl;
}

//置空函数
void LinkStack::MakeEmpty()
{
	Node *p;
	while (top != NULL)
	{
		p = top;
		top = p->next;
		delete p;
	}
}

int main()
{
	LinkQueue Q1;
	LinkStack L1;
	fstream f1;
	f1.open("Text.txt", ios::app|ios::in);
	int m, x;
p1:	cout << "输入要入队的元素个数\n";
	cin >> m;
	if (m < 0)
	{
		cout << "输入错误,请重新输入!"; goto p1;//goto语句可以解决"遇到错误情况返回到哪里"的问题.
	}
	else
	{
		for (int i = 0; i < m; i++)
		{

			cout << "入队第"<<i+1<<"个元素: ";
			f1 >> x;//文件->内存
			Q1.EnQueue(x);
		
			
		}
		cout << "逆置前:" << endl;
		Q1.ShowQueue();
	}

	for (int i = 0; i < m; i++)
	{

		L1.Push(Q1.DeQueue());
	}
	cout << endl;
	cout << "经栈逆置后:" << endl;
	L1.ShowStack();


	system("pause");
	return 0;
}

 

posted @ 2019-04-11 17:53  心碎人俱乐部  阅读(36)  评论(0)    收藏  举报