1 链式栈
//linkstack.h代码 //模板只能在.h中,模板的实例化在.cpp中,原因以后说
#include <iostream>
#include <list>
using namespace std;
//链式栈
//链式栈节点
template <typename T>
struct stacknode {
T data; //数据成员
struct stacknode<T>* next; //连接下一个节点
};
//初始化栈
template <typename T>
int Initstack(stacknode<T>*& s) {
s = NULL;
return 1;
}
//进栈
template <typename T>
int Push(stacknode<T>*& s, T e) {
stacknode<T>* p = new stacknode<T>;
p->data = e;
p->next = s;
s = p;
return 1;
}
//出栈
template <typename T>
int Pop(stacknode<T>*& s, T& e) {
if (s == NULL)
return -1;
stacknode<T>* p = s;
e = s->data;
s = s->next;
delete p;
return 1;
}
//返回栈顶
template <typename T>
T Gettop(stacknode<T>* s) {
if (s != NULL) {
return s->data;
}
}
//main.cpp代码
#include "linkstack.h"
using namespace std;
void test() {
stacknode<int>* s = new stacknode<int>;
Initstack(s);
for (int i = 0; i < 10; i++) {
Push(s, i);
}
for (int i = 0; i < 10; i++) {
int e;
Pop(s, e);
cout << e << endl;
}
}
int main() {
test();
system("pause");
return 0;
}
2 链式队列
队列的队头的next是头节点,队尾就是末节点,队尾的next为NULL
//linkqueue.h
#include <iostream>
using namespace std;
//链式队列
//节点
template <typename T>
struct qnode {
T data; //数据
qnode<T>* next;
};
//队列
template <typename T>
struct linkqueue {
qnode<T>* front;
qnode<T>* rear;
};
//队头的next是头节点,队尾就是末节点,队尾的next为NULL
//初始化队列
template <typename T>
int InitQueue(linkqueue<T>& Q) {
Q.front = Q.rear = new qnode<T>;
Q.front->next = NULL;
return 1;
}
//入队
template <typename T>
int EnQueue(linkqueue<T>& Q,T e) {
qnode<T>* p = new qnode<T>;
p->data = e;
p->next = NULL;
Q.rear->next = p; //插入到队尾
Q.rear = p; //更新队尾
return 1;
}
//出队
template <typename T>
int DeQueue(linkqueue<T>& Q,T& e) {
if (Q.front == Q.rear) //此时队列已经无其他节点
return -1;
qnode<T>* p = Q.front->next; //接住头节点
e = p->data; //头节点元素
Q.front->next = p->next; //更新头节点
if (p == Q.rear) //如果原来的头节点就是队尾,此时已经没有其他节点了
Q.rear = Q.front; //队尾和队首重合
delete p;
return 1;
}
template <typename T>
T GetHead(linkqueue<T> Q) {
if (Q.front != Q.rear)
return Q.front->next->data;
}
//main.cpp
void test() {
linkqueue<int> lq;
InitQueue(lq);
for (int i = 0; i < 10; i++)
EnQueue(lq, i);
for (int i = 0; i < 10; i++) {
int t;
DeQueue(lq, t);
cout << t;
}
}
3 二叉树
//二叉树的非递归遍历 //利用栈
3.1 先序非递归遍历
沿左侧自上而下访问各节点,然后自下而上访问各节点的右子树(栈中节点)
- 访问当前节点
- 栈存住右节点
- 沿着左侧继续向下
- 若左侧没有了则出栈,访问刚才栈存住的右节点
void previsit(bitree bt){
binode* dangqian = bt; //当前节点
binode* tem = new binode; //临时节点
linkstack s;
initstack(s); //栈
while(dangqian || !emptystack(s)){
if(dangqian){
cout<<dangqian->data; //访问当前节点
if(dangqian->rchild)
pushstack(s,dangqian->rchild); //存住右节点
dangqian = dangqian->lchild; //沿左侧继续向下
}
else{
popstack(s,tem);
dangqian = tem;
}
}
}
3.2 中序非递归遍历
沿着最左侧通路,然后自下而上访问各节点及右子树(栈中节点的右孩子)
void invisit(bitree bt){
binode* dangqian = bt;
binode* tem = new binode;
linkstack s;
initstack(s);
while(dangqian || !emptystack(s)){
if(dangqian){ //沿着左侧通路
pushstack(s,dangqian);
dangqian = dangqian->lchild;
}
else{
popstack(s,tem);
cout<<tem->data; //访问出栈的节点
dangqian = tem->rchild; //继续访问右子树
}
}
}
完整版本
//二叉树的非递归遍历
#include <iostream>
using namespace std;
//二叉树节点
typedef struct _binode {
char data;
struct _binode* lchild, *rchild;
}binode, *bitree;
//栈节点
typedef struct _stacknode {
binode data;
struct _stacknode* next;
}stacknode, *linkstack;
//栈判空
bool emptystack(linkstack s) {
return (s == NULL);
}
//初始化栈
void initstack(linkstack& s) {
s = NULL;
}
//压栈
void pushstack(linkstack& s, bitree bt) {
//申请一个新节点
stacknode* node = new stacknode;
node->data = *bt;
node->next = s;
s = node;
}
//出栈
void popstack(linkstack& s, bitree bt) {
if (s == NULL)
return;
*bt = s->data;
stacknode* olds = s;
s = s->next;
delete olds;
}
//创建二叉树
void createbitree(bitree& t) {
char ch;
cin >> ch;
if (ch == '#')
t = NULL;
else {
t = new binode;
t->data = ch;
createbitree(t->lchild);
createbitree(t->rchild);
}
}
//前序非递归遍历二叉树
void previsit(bitree bt) {
binode* dangqian = bt; //当前节点
binode* tem = new binode; //临时节点
linkstack s;
initstack(s); //初始化栈
while (dangqian || !emptystack(s)) {
if (dangqian) {
cout << dangqian->data; //访问当前节点的数据
if (dangqian->rchild != NULL) //当前节点的右子树不为空,进行暂存
pushstack(s, dangqian->rchild);
dangqian = dangqian->lchild;
}
else {
popstack(s, tem);
//访问暂存的右子树,用tem去接住,因为dangqian为NULL,不可以接
dangqian = tem;
}
}
}
//中序遍历
void invisit(bitree bt) {
binode* dangqian = bt; //当前节点
binode* tem = new binode; //临时节点
linkstack s;
initstack(s); //初始化栈
while (dangqian || !emptystack(s)) {
if (dangqian) {
pushstack(s, dangqian); //存住当前节点
dangqian = dangqian->lchild;
}
else {
popstack(s, tem);
cout << tem->data;
dangqian = tem->rchild;
}
}
}
//链式队列结点
typedef struct _queuenode {
binode data; //数据
struct _queuenode* next;
}queuenode;
//队列
typedef struct _linkqueue {
queuenode* front;
queuenode* rear;
}linkqueue;
//初始化队列
void initqueue(linkqueue& lk) {
lk.front = lk.rear = new queuenode;
lk.front->next = NULL;
}
//判空队列
bool emptyqueue(linkqueue lk) {
return (lk.front == lk.rear);
}
//入队,从尾节点开始
void enqueue(linkqueue& lk, bitree bt) {
//申请一个新的队列节点
queuenode* qn = new queuenode;
qn->data = *bt;
qn->next = NULL;
lk.rear->next = qn;
lk.rear = qn;
}
//出队,从头节点开始
void dequeue(linkqueue& lk, bitree bt) {
if (lk.front == lk.rear) //如果队列为空,则没法出队,直接返回
return;
queuenode* qn = lk.front->next; //记住原来的头节点
*bt = qn->data; //获取原来头节点数据
lk.front->next = qn->next; //更新头节点
if (qn == lk.rear) //如果原来队列只有一个节点
lk.rear = lk.front;
delete qn; //删除原来头节点
}
//按层次遍历
void levelvisit(bitree bt) {
binode* dangqian = bt; //记录当前节点
binode* tem = new binode; //临时节点
linkqueue lk;
initqueue(lk); //初始化队列
enqueue(lk, dangqian); //先进队
while (!emptyqueue(lk)) {
dequeue(lk, tem); //出队
cout << tem->data; //访问元素
if (tem->lchild != NULL)
enqueue(lk,tem->lchild);
if (tem->rchild != NULL)
enqueue(lk,tem->rchild);
}
}
void test() {
bitree bt;
cout << "创建一个二叉树:" << endl;
createbitree(bt);
cout << "前序遍历的结果为:" << endl;
previsit(bt);
cout << endl;
cout << "中序遍历的结果为:" << endl;
invisit(bt);
cout << endl;
cout << "层次遍历的结果为:" << endl;
levelvisit(bt);
cout << endl;
}