数据结构_几个重要数据结构的模板写法

Stack.h

#pragma once

#include "预定义.h"
#include <iostream>


#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10

template<class SElemType>
struct SqStack
{
    SElemType* base, * top;
    int stacksize;
};

template<class SElemType>
Status InitStack(SqStack<SElemType> &S)
{
    S.base = (SElemType*) malloc(STACK_INIT_SIZE * sizeof(SElemType));
    if (!S.base)
        exit(OVERFLOW);
    S.top = S.base;
    S.stacksize = STACK_INIT_SIZE;
    return OK;
}

template<class SElemType>
Status DestroyStack(SqStack<SElemType> &S)
{
    if (!S.base)
        return ERROR;
    free(S.base);
    S.base = S.top = NULL;
    S.stacksize = 0;
    return OK;
}

template<class SElemType>
Status StackEmpty(SqStack<SElemType> S)
{
    if (S.top == S.base)
        return TRUE;
    return FALSE;
}

template<class SElemType>
Status GetTop(SqStack<SElemType> S, SElemType &e)
{
    if (S.top == S.base) return ERROR;
    e = *(S.top - 1);
    return OK;
}

template<class SElemType>
Status Push(SqStack<SElemType> &S, SElemType e)
{
    if (S.top - S.base >= S.stacksize)
    {
        //栈满, 追加存储空间
        S.base = (SElemType*) realloc(S.base,
                                      (S.stacksize + STACKINCREMENT) * sizeof(SElemType));
        if (!S.base)
            exit(OVERFLOW);
        S.top = S.base + S.stacksize;
        S.stacksize += STACKINCREMENT;
    }
    *S.top++ = e;  //记住此处是先取值后自加.
    return OK;
}

template<class SElemType>
Status Pop(SqStack<SElemType> &S, SElemType &e)
{
    if (S.top == S.base)
        return ERROR;
    e = *--S.top;
    return OK;
}

Queue.h

#pragma once

#include "预定义.h"
#include <stdio.h>
#include <stdlib.h>

#define MAXQSIZE 100
template<class T>
struct Queue {
	T base[MAXQSIZE];
	int front;//头指针, 若队列不为空, 指向队列头元素
	int rear; //尾指针, 若队列不空, 指向队列尾元素的下一个位置
};

/* ---- 基本函数列表及其实现 ---- */
template<class T>
int InitQueue(Queue<T>& Q)
{
	Q.front = Q.rear = 0;
	return OK;
}

template<class T>
int QueueLength(Queue<T> Q)
{
	return Q.rear - Q.front;
}

template<class T>
int EnQueue(Queue<T>& Q, T e)
{
	if (QueueLength(Q) > MAXQSIZE)
		return ERROR;
	Q.base[Q.rear] = e;
	Q.rear++;
	return OK;
}

template<class T>
int DeQueue(Queue<T>& Q, T& e)
{
	if (Q.front == Q.rear)
		return ERROR;
	e = Q.base[Q.front];
	Q.front++;
	return OK;
}

template<class T>
int EmptyQueue(Queue<T> Q)
{
	if (Q.front == Q.rear)
		return 1;
	return 0;
}

BiTree.h

#pragma once

#include "Queue.h"
#include <cstdlib>
#include <iostream>

#define MAX(x, y) ((x) > (y) ? (x) : (y))
template<class T>
struct BitNode {
	T data;
	BitNode<T>*Lchild, *Rchild;
	// BitNode<T>* parent;
};

template<class T>
using BiTree = BitNode<T>*;

//感觉这个函数没什么用.
template<class T>
BiTree<T> Initiate()
{
	BitNode<T>* bt;
	bt = (BitNode<T>*)malloc(sizeof(BitNode<T>));
	if (!bt)
		return 0;
	bt->Lchild = bt->Rchild = NULL;
	return bt;
}

// 生成一棵以 x为根结点的数据域值以 lbt和 rbt为左右子树的二叉树
template<class T>
BiTree<T> Creat(T x, BiTree<T> Lbt, BiTree<T> Rbt)
{
	BitNode<T>* p;
	if ((p = (BitNode<T>*)malloc(sizeof(BitNode<T>))) == NULL)
		return NULL;
	p->data = x;
	p->Lchild = Lbt;
	p->Rchild = Rbt;
	// p->parent = NULL;
	return p;
}

template<class T>
BiTree<T> InsertL(BiTree<T> bt, T x, BiTree<T> parent)
{
	BitNode<T>* p;
	if (parent == NULL)
		return NULL;
	if ((p = (BitNode<T>*)malloc(sizeof(BitNode<T>))) == NULL)
		return NULL;
	p->data = x;
	p->Lchild = p->Rchild = NULL;
	p->parent = NULL;
	if (parent->Lchild == NULL)
		parent->Lchild = p;
	else
	{
		p->Lchild = parent->Lchild;
		parent->Lchild = p;
	}
	return bt;
}

template<class T>
BiTree<T> DeleteL(BiTree<T> bt, BiTree<T> parent)
{
	/* 一点注释:
   * 不能直接free(p)
   * 子树中除了根节点之外的其他结点,未释放。
   * 此时需要采用遍历的方法找出子树分支中的每个结点, 挨个释放 ClearTree(p);
   * 假设ClearTree函数是用来实现上述用途的
   * p为根的树中所有结点都被释放掉.
   * */
	Queue<BitNode<T>*> q;
	if (!bt)
		return;
	EnQueue(q, bt);//根结点进队列
	while (!EmptyQueue(q))
	{
		BitNode<T>* aNode;
		DeQueue(q, aNode);//出队列, aNode是采用引用的方式进行参数传递
		//std::cout << aNode->data;
		if (!aNode->Lchild)//将队首结点的左孩子结点入队列
			EnQueue(q, aNode->Lchild);
		if (!aNode->Rchild)//将队首结点的右孩子结点入队列
			EnQueue(q, aNode->Rchild);
		free(aNode);
	}
	return bt;
}

// 先序遍历递归算法
template<class T>
int PreOrderTraverse(BiTree<T> bt)
{
	if (bt)
	{
		std::cout << bt->data << ' ';// 此处最好是通过调用函数来实现对数据的最终输出
		if (bt->Lchild)
			PreOrderTraverse(bt->Lchild);
		if (bt->Rchild)
			PreOrderTraverse(bt->Rchild);
	}
	return 1;
}

// 中序遍历递归算法
template<class T>
int InOrderTraverse(BiTree<T> bt)
{
	if (bt)
	{
		if (bt->lChild)
			InOrderTraverse(bt->lchild);
		std::cout << bt->data << ' ';// 此处最好是通过调用函数来实现对数据的最终输出
		if (bt->rChild)
			InOrderTraverse(bt->rchild);
	}
	return 1;
}

// 后序遍历递归算法
template<class T>
int PostOrderTraverse(BiTree<T> bt)
{
	if (bt)
	{
		if (bt->lChild)
			PostOrderTraverse(bt->lchild);
		if (bt->rChild)
			PostOrderTraverse(bt->rchild);
		std::cout << bt->data << ' ';// 此处最好是通过调用函数来实现对数据的最终输出
	}
	return 1;
}

template<class T>
void LevelOrder(BiTree<T> bt)
{
	Queue<BitNode<T>*> q;
	if (!bt)
		return;
	EnQueue(q, bt);//根结点进队列
	while (!EmptyQueue(q))
	{
		BitNode<T>* aNode;
		DeQueue(q, aNode);//出队列, aNode是采用引用的方式进行参数传递
		std::cout << aNode->data;
		if (!aNode->Lchild)//将队首结点的左孩子结点入队列
			EnQueue(q, aNode->Lchild);
		if (!aNode->Rchild)//将队首结点的右孩子结点入队列
			EnQueue(q, aNode->Rchild);
	}
}

//这个代码可能有大问题.
template<class T>
BiTree<T> Search(BiTree<T> bt, T x)
{
	BiTree<T> p = NULL;
	if (bt)
	{
		if (bt->data == x)
			return bt;// 查找成功返回, 递归结束条件;
		if (bt->lchild)
			p = Search(bt->lchild, x);// 若有左子树, 在左子树中继续查找
		if (p)
			return p;// 左子树中查到了, 不需要继续了

		if (bt->rchild)
			p = Search(bt->rchild, x);// 若有右子树, 在右子树中继续查找
		if (p)
			return p;// 右子树查到了, 递归结束条件
	}
	return NULL;// 查找失败返回, 递归结束条件
}

//计算树的叶子节点数目
template<class T>
int BiTreeLeavesCount(BiTree<T> bt)
{
	if (!bt)
		return 0;//当前结点为空,没有叶子结点,递归结束条件
	if (!bt->left && !bt->right)
		return 1;
	int nLeaf = BiTreeLeavesCount(bt->left);
	nLeaf += BiTreeLeavesCount(bt->right);
	return nLeaf;
}

//计算树的结点数目
template<class T>
int BiTreeNodeCount(BiTree<T> bt)
{
	if (!bt)
		return 0;
	int n = 1;
	n += BiTreeNodeCount(bt->left) + BiTreeNodeCount(bt->right);
	return n;
}

//计算树的层数
template<class T>

int BiTreeLevelCount(BiTree<T> bt)
{

	if (!bt)
		return 0;
	int LLevel = BiTreeLevelCount(bt->left);
	int RLevel = BiTreeLeavesCount(bt->right);
	return 1 + MAX(LLevel, RLevel);
	//return 1 + (LLevel > RLevel ? LLevel : RLevel);
}

Array.h

/* 2022/10/28
 * 没有经过测试
 * */
#pragma once
#include "预定义.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>

template<class T>
struct Array {
	T* base;       //数组元素的基地址
	int dim;       //数组维数
	int* bounds;   //数组维界基址
	int* constants;//数组映像函数常量基址
};

#define MAX_ARRAY_DIM 8

/*  ----基本操作函数----  */
template<class T>
Status InitArray(Array<T>& A, int dim, ...)
{
	if (dim < 1 || dim > MAX_ARRAY_DIM)
		return ERROR;
	A.dim = dim;

	A.bounds = (int*)malloc(dim * sizeof(int));
	if (!A.bounds)
		exit(OVERFLOW);

	int elemtotal = 1;//总元素数
	va_list ap;
	va_start(ap, dim);
	for (int i = 0; i < dim; i++)
	{
		A.bounds[i] = va_arg(ap, int);//每一维具体的数
		if (A.bounds[i] < 0)
			return ERROR;
		elemtotal *= A.bounds[i];
	}
	va_end(ap);

	A.base = (T*)malloc(elemtotal * sizeof(T));
	if (!A.base)
		exit(OVERFLOW);

	A.constants[dim - 1] = 1;//L = 1, 指针的增减以元素的大小为单位
	for (int i = dim - 2; i >= 0; --i)
		A.constants[i] = A.bounds[i + 1] * A.constants[i + 1];
	return OK;
}

template<class T>
Status DestroyArray(Array<T>& A)
{
	if (!A.base)
		return ERROR;
	free(A.base);
	A.base = NULL;

	if (!A.bounds)
		return ERROR;
	free(A.bounds);
	A.bounds = NULL;

	if (!A.constants)
		return ERROR;
	free(A.constants);
	A.constants = NULL;

	return OK;
}

template<class T>
Status Locate(Array<T> A, va_list ap, int& off)
{
	//若ap指示的各下标值合法, 则求出该元素在A中相对地址off
	off = 0;
	for (int i = 0; i < A.dim; i++)
	{
		int ind = va_arg(ap, int);
		if (ind < 0 || ind >= A.bounds[i])
			return OVERFLOW;
		off += A.constants[i] * ind;
	}
	return OK;
}

template<class T>
Status Value(Array<T> A, T& e, ...)
{
	va_list ap;
	va_start(ap, e);
	int off;
	Status result = Locate(A, ap, off);
	if (result <= 0)
		return result;
	e = *(A.base + off);
	return OK;
}

template<class T>
Status Assign(Array<T>& A, T e, ...)
{
	va_list ap;
	va_start(ap, e);
	int off;
	Status result = Locate(A, ap, off);
	if (result <= 0)
		return result;
	*(A.base + off) = e;
	return OK;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值