基本数据结构

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;
}

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值