带头结点的链队列中
插入结点时,不需要特殊判断,但在删除元素时,如果是最后一个结点时,就需要将rear指针移动到front,这才是判空的标志
还有,在出队的时候,忘记了判断是否空以及delete
一点思考,不带头结点的就不敲了,想想得了
如果是不带头结点的话
那么在初始化的时候,Q.front和Q.rear就都声明为NULL
在入队的时候,先声明一个结点,然后分配数值,!!!!!
此时需要判断,如果是第一个结点,那么就是头尾指针都指向他,并让rear的next为NULL
如果是普通的结点,那就直接把它插在rear的后面
在出队时,如果是最后一个结点的话,此时front和next都已经指向了它,需要先把front和next都指向NULL,然后再去释放空间
so
带头结点的,删除最后一个结点需要特殊操作
不带头结点的,插入第一个、删除最后一个都需要特殊操作
应该就是这样了吧,QAQ
还有,这个链队列相当于声明了两个结构体,一个里面存放的是data和*next
另一个存放的是指向Linknode的指针 *front和 *next
在这个里面也可以自己去添加东西,我就加了一个len,等同于顺序队列中的size
//不带头结点的链栈
typedef struct Linknode {
int data;
struct Linknode* next;
}*LiStack;
在上面的链栈中,结构体后面*LiStack就是指向Linknode的指针,应该和链队列重新声明一个结构体,里面是Linknode的指针是一个效果吧?
不同的是,他是两个指针,如果写在后面的话,定义一个指针,就相当于声明了一个结点,而且头尾指针还需要分开声明,去操作,(个人思考)
这样的话不如将头尾指针合在一起
那,如果栈也有一个栈底指针,是不是也就可以这样去操作,这样的话,应该是有利于从栈底去遍历输出元素?我感觉一般时候遇不到,行了,今天的链队列就先到这里,我要是有什么想写的再来补充
#include<iostream>
using namespace std;
//带头结点的链队列
typedef struct Linknode {
int data;
struct Linknode* next;
}Linknode;
typedef struct {
Linknode* front, * rear;
int len;
}LinkQueue;
//初始化队列
bool InitLinkQueue(LinkQueue& Q) {
Q.front = Q.rear = new Linknode;
//指向同一个头结点
Q.len = 0;
Q.front->next = NULL;//第一个结点指向空
return true;
}
//入队
bool enQueue(LinkQueue& Q,int x) {
Linknode* p = new Linknode;
p->data = x;
//带头结点的入队是不是第一个元素我并没有发现什么不同呀
//难道书上说的是不带头节点的吗
Q.rear->next = p;
Q.rear = p;
Q.rear->next = NULL;
Q.len++;
return true;
}
//出队
bool deQueue(LinkQueue& Q,int &x) {
if (Q.front == Q.rear)
return false;
//忘了判空了,靠
Linknode* p = Q.front->next;//第一个结点
x = p->data;//取出
Q.front->next = p->next;//越过一个
if (Q.front->next==NULL)
Q.rear = Q.front;
//最后一个结点被删了的话,把rear指针,移动到front
//如果不改变的话,在判断空里面,就是错误的
delete p;//也忘了释放空间
return true;
}
//输出队列
bool printQueue(LinkQueue Q) {
Linknode* p = Q.front->next;//第一个结点
if (p == NULL)
return false;
while (p != NULL) {
cout << p->data << " ";
p = p->next;
}
cout << endl;
return true;
}
//判空
void emptyQueue(LinkQueue Q) {
if (Q.front == Q.rear)
cout << "空" << endl;
else
cout << "不空" << endl;
}
int main() {
LinkQueue Q;
InitLinkQueue(Q);
emptyQueue(Q);
enQueue(Q, 1);
enQueue(Q, 2);
enQueue(Q, 3);
enQueue(Q, 4);
enQueue(Q, 5);
printQueue(Q);
int x;
deQueue(Q, x);
cout << x << endl;
deQueue(Q, x);
cout << x << endl;
deQueue(Q, x);
cout << x << endl;
deQueue(Q, x);
cout << x << endl;
printQueue(Q);
deQueue(Q, x);
cout << x << endl;
int m=printQueue(Q);
cout << m << endl;
emptyQueue(Q);
return 0;
}