栈和队列
1.栈的定义
栈是限定只能在一端进行插入和删除的线性表。允许进行插入和删除操作的一端称为栈顶,另一端为栈底。当栈中没有元素时,称为空栈。
栈的特点是“后进先出”(Last In First Out,LIFO),即后入栈的元素先出栈。
2.队列定义
队列是限定在一端进行插入,在另一端进行删除的线性表。队列中允许插入一端称为队尾,允许删除的一端称为队头。
在队尾插入元素的操作称为入队。在队头删除元素的操作称为出队。入队时只涉及队尾指针的变化;出队时,只涉及队头指针的变化。当队列中没有元素时,称为空队。
队列的特点是“先进先出”(First In First Out,FIFO),即先入队的元素先出队。
3.栈的基本操作
#include <iostream>
using namespace std;
class StackNode
{
friend class ListStack;
public:
StackNode(int value)
:data(value)
,next(NULL)
{}
private:
int data;
StackNode *next;
};
class ListStack
{
typedef StackNode Node;
public:
ListStack() //默认构造函数
:top(NULL)
{}
ListStack(const ListStack&); //拷贝构造函数
~ListStack(); //析构函数
ListStack& operator=(const ListStack&); //赋值运算符重载
bool isempty()const; //判空
void push(int); //入栈
bool pop(); //出栈
bool get_top(int&)const; //取栈顶元素
protected:
private:
Node *top;
void copy(const ListStack&); //拷贝功能函数
void clear(); //清空函数,实现析构
};
void ListStack::copy(const ListStack& other) //拷贝构造
{
top = 0;
Node *tmp = other.top;
Node *prenode = top;
while (tmp)
{
Node *newnode = new Node(tmp->data);
if (top == 0)
{
top = newnode;
}
else
{
prenode->next = newnode;
}
prenode = newnode;
tmp = tmp->next;
}
}
void ListStack::clear() //清空栈
{
while (top)
{
Node *delnode = top;
top = top->next;
delete delnode;
}
}
ListStack::ListStack(const ListStack& other) //拷贝构造函数
{
copy(other);
}
ListStack::~ListStack() //析构函数
{
clear();
}
ListStack& ListStack::operator=(const ListStack& other) //赋值运算符重载
{
if (this != &other)
{
clear();
copy(other);
}
return *this;
}
bool ListStack::isempty() const //判栈空
{
return top == 0;
}
void ListStack::push(int value) //入栈
{
Node *newnode = new Node(value);
newnode->next = top;
top = newnode;
}
bool ListStack::pop()//出栈
{
if (isempty())
{
return false;
}
Node *delnode = top;
top = top->next;
delete delnode;
return true;
}
bool ListStack::get_top(int &value)const //取栈顶元素
{
if (isempty())
{
return false;
}
value = top->data;
return true;
}
void test()
{
ListStack s1;
for (int i = 1; i <= 6; ++i)
{
s1.push(i);
}
ListStack s2(s1);
ListStack s3;
s3 = s1;
int value;
while (s1.get_top(value))
{
s1.pop();
cout << value << " ";
}
cout << endl << "s1 已经清空" << endl;
while (s2.get_top(value))
{
s2.pop();
cout << value << " ";
}
cout << endl << "s2已经清空" << endl;
while (s3.get_top(value))
{
s3.pop();
cout << value << " ";
}
cout << endl << "s3已经清空" << endl;
}
int main()
{
test();
system("pause");
return 0;
}
4.队列的基本操作
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
struct Qnode //结点的结构
{
int data;
Qnode *next;
Qnode(int x)
:data(x)
,next(NULL)
{}
};
class Queuet //队列的结构
{
public:
typedef Qnode Node;
Queuet() //构造函数
:front(NULL)
, rear(NULL)
{}
Queuet(const Queuet& other) //拷贝构造函数
{
Copy(other);
}
Queuet& operator=(const Queuet& other) //赋值运算符重载
{
if (this != &other)
{
ClearQueue(this);
Copy(other);
}
return *this;
}
~Queuet() //析构函数
{}
void Copy(const Queuet &other)
{
Node *tmp = other.front;
Node* prev = rear;
while (tmp != NULL)
{
Node *newnode = new Node(tmp->data);
if (rear == NULL)
rear = newnode;
else
{
prev = rear;
rear = rear->next;
rear = newnode;
prev->next = newnode;
}
tmp = tmp->next;
if (front == NULL)
{
front = newnode;
}
}
}
Queuet *InsertQueue(Queuet *Q,int x)//队列的入队操作
{
Node *s;
s = (Node *)malloc(sizeof(Node));
if (s == NULL)
{
cout << "空间分配出错!" << endl;
exit(1); //exit(1)表示异常退出
}
s->data = x;
s->next = NULL;
if (Q->front == NULL)
{
Q->front = s;
Q->rear = s;
}
else
{
Q->rear->next = s;
Q->rear = s;
}
return Q;
}
int LengthQueue(Queuet *Q)
{
int len = 0;
Node *p = Q->front;
while (p != NULL)
{
len++;
p = p->next;
}
return len;
}
Queuet *DelQueue(Queuet *Q) //队列的出队操作
{
Node *p;
int x;
if (Q->front == NULL)
{
cout << "队列为空,不能删除!" << endl;
exit(1);
}
x = Q->front->data;
p = Q->front;
Q->front = Q->front->next;
if (Q->front == Q->rear) //队列中就一个元素,将队列置空
{
Q->front = NULL;
Q->rear = NULL;
}
free(p);
return Q;
}
int ReadheadQueue(Queuet *Q) //读取队头元素
{
if (Q->front == NULL)
{
cout << "队列为空!";
exit(1);
}
else
return Q->front->data;
}
bool Is_EmptyQueue(Queuet *Q) //判断队列是否为空
{
if (Q->front == NULL&&Q->rear == NULL)
return true;
else
return false;
}
Queuet *ClearQueue(Queuet *Q) //清空队列
{
Node *p = Q->front;
while (p != NULL)
{
Q->front = Q->front->next;
free(p);
p = Q->front;
}
Q->rear = NULL;
return Q;
}
void Print(Queuet *Q) //打印队列
{
Node *p = Q->front;
if (Q->front != NULL)
while (p != NULL)
{
cout << p->data << " ";
p = p->next;
}
else
cout << "队列为空!" << endl;
cout << endl;
}
protected:
Node *front;
Node *rear;
};
void test()
{
Queuet q;
int a[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
int i;
for (i = 0; i<8; i++)
{
q.InsertQueue(&q, a[i]); //引用
}
q.Print(&q);
cout << q.LengthQueue(&q) << endl;
cout << q.ReadheadQueue(&q) << endl;
cout << q.Is_EmptyQueue(&q) << endl;
q.DelQueue(&q);
q.Print(&q);
Queuet q1(q);
q1.Print(&q1);
Queuet q3;
q3 = q1;
q3.Print(&q3);
q.ClearQueue(&q);
q.Print(&q);
}
int main()
{
test();
system("pause");
return 0;
}