考研复习之数据结构表树图的基本操作
现在开始准备考研复习了,跨考院去到计院去,之前写的一些数据结构的代码还算中规中矩,现在拿出来复习倒是挺能理清思路的,分享下。
[toc]
栈
#pragma once
#ifndef __CSTACK_H
#define __CSTACK_H
#include <cstdlib>
#include <iostream>
/****************************************************************************
* 文件名: CStack.h
* 内容简述:定义堆栈类
* 修改日期:2018-4-13
******************************************************************************/
template <typename DataType> class CStack; //CStack 类声明
template <typename DataType>
class StackNode {
friend class CStack<DataType>; //友元类声明
public:
StackNode() :elem(0), next(NULL) {};
private:
DataType elem; //结点数据
StackNode<DataType> *next; //指向下一结点的指针
};//堆栈结点类定义;
template <typename DataType>
class CStack {
public:
CStack() :top(NULL){};
~CStack();
bool IsEmpty(); //判断堆栈是否为空
int GetLength(); //获得堆栈长度
void Push(DataType data); //入栈
DataType Pop(); //出栈
DataType GetTop(); //获得栈顶数据
private:
StackNode<DataType> *top; //栈顶指针
};//堆栈类定义;
template <typename DataType>
CStack<DataType>::~CStack()
{
StackNode<DataType> *ptr = NULL;
while (top != NULL) {
ptr = top;
top = top->next;
delete ptr;
}
}
/******************************************************************************
*函数名: IsEmpty();
*参数: 无;
*返回值:true(栈为空)/false(栈不空);
*功能: 判断栈是否为空;
******************************************************************************/
template <typename DataType>
bool CStack<DataType>::IsEmpty()
{
if (top == NULL)
//printf("栈空!!!\t\n");
return true;
else
return false;
}
/******************************************************************************
*函数名: GetLength();
*参数: 无
*返回值:堆栈长度;
*功能: 获得堆栈长度;
******************************************************************************/
template <typename DataType>
int CStack<DataType>::GetLength()
{
int count = 1;
StackNode<DataType> *ptr = top; //将栈顶指针的值赋给ptr,使用临时指针访问,避免函数改变栈顶指针;
if (ptr == NULL)
return 0;
while (ptr->next != NULL) { //当栈不空时,遍历椎栈;
ptr = ptr->next;
count++;
}
return count;
}
/******************************************************************************
*函数名: Push(DataType);
*参数: 入栈的元素;
*返回值:无
*功能: 元素入栈;
******************************************************************************/
template <typename DataType>
void CStack<DataType> ::Push(DataType data)
{
StackNode<DataType> *ptr = NULL;
ptr = new StackNode<DataType>;
ptr->next = top;
top = ptr;
ptr->elem= data;
}
/******************************************************************************
*函数名: Pop();
*参数: 无;
*返回值:出栈的元素
*功能: 元素出栈
******************************************************************************/
template <typename DataType>
DataType CStack<DataType> ::Pop()
{
if (!IsEmpty()) {
StackNode<DataType> *ptr = top;
DataType data = ptr->elem;
top = top->next;
delete ptr;
ptr = NULL;
return data;
}
else
std::cout << "Stack is empty!" << std::endl;
}
/******************************************************************************
*函数名: GetTop();
*参数: 无
*返回值:栈顶元素
*功能: 获得栈顶元素
******************************************************************************/
template <typename DataType>
DataType CStack<DataType> ::GetTop()
{
if (!IsEmpty())
return (top->elem);
else
std::cout << "Stack is empty!" << std::endl;
}
#endif
队列
#pragma once
#ifndef __CQUEUE_H
#define __CQUEUE_H
#include <cstdlib>
#include <iostream>
/****************************************************************************
* 文件名: CQueue.h
* 内容简述:定义队列类
* 修改日期:2018-4-13
******************************************************************************/
template <typename DataType> class CQueue;
template <typename DataType>
class QueueNode {
friend class CQueue<DataType>;
public: QueueNode() :next(NULL){};
private:
DataType elem; //结点元素
QueueNode<DataType> *next; //指向下一结点的指针
};
template <typename DataType>
class CQueue {
public:
CQueue() :front(NULL),rear(NULL){};
~CQueue();
void EnQueue(DataType data); //元素入队操作
DataType DeQueue(); //元素出队操作
bool IsEmpty(); //队列是否空
private:
QueueNode<DataType> *front; //队首指针
QueueNode<DataType> *rear; //队尾指针
};
/******************************************************************************
*函数名:
*参数:
*返回值:
*功能:
******************************************************************************/
template <typename DataType>
CQueue<DataType>::~CQueue()
{
QueueNode<DataType> *ptr =NULL;
while (front != NULL) {
ptr = front;
front = front->next;
delete ptr;
}
}
/******************************************************************************
*函数名:
*参数:
*返回值:
*功能: 出队
******************************************************************************/
template <typename DataType>
DataType CQueue<DataType>::DeQueue()
{
if (front != NULL) {
DataType data = front->elem;
QueueNode<DataType> *ptr = front;
front = front->next;
delete ptr;
ptr = NULL;
return data;
}
/*else
std::cout << "队列空!" << std::endl;*/
}
/******************************************************************************
*函数名:
*参数:
*返回值:
*功能: 入队
******************************************************************************/
template <typename DataType>
void CQueue<DataType>::EnQueue(DataType data)
{
if (front == NULL) {
front = rear = new QueueNode<DataType>; //当队列为空时,初始化
rear->elem = data;
}
else {
QueueNode<DataType> *ptr = new QueueNode<DataType>;
ptr->elem = data;
rear->next = ptr;
rear = rear->next;
}
}
template <typename DataType>
bool CQueue<DataType>::IsEmpty()
{
if (front == NULL) return true;
else return false;
}
#endif // !__CQUEUE_H
堆
#pragma once
#ifndef __CHEAP_H
#define __CHEAP_H
#include <cstdio>
typedef struct {
int from;
int to;
int weight;
}HeapNode_t; //定义边的结构
//小顶堆
class CHeap {
public:
CHeap(int size) :maxsize(size), index(0) { Storage = new HeapNode_t[maxsize]; };
~CHeap() { if (Storage) delete[]Storage;Storage = NULL; };
void ShiftDown(int pos);
void BuildHeap(void *Arry,int length);
bool EnHeap(const void* data);
bool IsEmpty();
bool IsFull();
void Clear();
int GetSize();
void InOrderTraverse(int root);
void PreOrderTraverse(int root);
void PostOrderTraverse(int root);
void DeHeap(int &from, int &to, int &weight);
private:
inline int left(int pos);
inline int right(int pos);
inline int parent(int pos);
inline bool isleaf(int pos);
int index; //记录堆中数据个数,指向最后一个元素;
int maxsize; //堆的最大容量
HeapNode_t *Storage; //堆的存储区
};
#endif
#include "CHeap.h"
inline int CHeap::left(int pos)
{
int leftchild = 0;
(2 * pos + 1 >= index) ? (leftchild = -1) : (leftchild = 2 * pos + 1);
return leftchild;
}
inline int CHeap::right(int pos)
{
int rightchild = 0;
(2 * pos + 2 >= index) ? (rightchild = -1) : (rightchild = 2 * pos + 2);
return rightchild;
}
inline int CHeap::parent(int pos)
{
int ptr = 0;
(pos <= 0) ? (ptr = -1) : (ptr = (pos - 1) / 2);
return ptr;
}
inline bool CHeap::isleaf(int pos)
{
bool value = false;
(2 * pos + 1 >= index) ? (value = true) : (value = false);
return value;
}
void CHeap::ShiftDown(int pos)
{
HeapNode_t Node = Storage[pos];
while (!isleaf(pos)) {
int pchild = left(pos);
if ((pchild < index - 1) && (Storage[pchild].weight > Storage[pchild + 1].weight)) pchild++;//若有右结点,并且右结点更小;选择更小的那个;
if (Node.weight <= Storage[pchild].weight) break; //若父结点的数值更小,则满足要求,不用改变;
Storage[pos] = Storage[pchild];
pos = pchild;
}
Storage[pos] = Node;
}
bool CHeap::EnHeap(const void *data)
{
HeapNode_t *Edge = (HeapNode_t *)data;
if (index == maxsize) return false;
int curr = index++;
int ptr = parent(curr);
while ((ptr != -1) && (Edge->weight < Storage[ptr].weight)) {
Storage[curr] = Storage[ptr];
curr = ptr;
ptr = parent(curr);
}
Storage[curr].from = Edge->from;
Storage[curr].to = Edge->to;
Storage[curr].weight = Edge->weight;
return true;
}
bool CHeap::IsEmpty()
{
if (index == 0) return true;
else return false;
}
bool CHeap::IsFull()
{
if (index == maxsize) return true;
else return false;
}
void CHeap::Clear()
{
}
int CHeap::GetSize()
{
return index;
}
void CHeap::DeHeap(int &from, int &to, int &weight)
{
from = Storage[0].from;
to = Storage[0].to;
weight = Storage[0].weight;
if (--index != 0) { //index指向末尾的后一位
Storage[0] = Storage[index];
ShiftDown(0);
}
}
void CHeap::BuildHeap(void* Arry, int length)
{
HeapNode_t *DataArry = (HeapNode_t *)Arry;
if (length > maxsize) return;
for (int i = 0;i < length;i++) {
Storage[index] = DataArry[i];
index++;
}
for (int i = (length / 2 - 1);i >= 0;i--) //(length-1-1)/2
ShiftDown(i);
}
void CHeap::InOrderTraverse(int root)
{
if (root == -1) return;
InOrderTraverse(left(root));
printf("%d\t", Storage[root].weight);
InOrderTraverse(right(root));
}
void CHeap::PreOrderTraverse(int root)
{
if (root == -1) return;
printf("%d\t", Storage[root].weight);
PreOrderTraverse(left(root));
PreOrderTraverse(right(root));
}
void CHeap::PostOrderTraverse(int root)
{
if (root == -1) return;
PostOrderTraverse(left(root));
PostOrderTraverse(right(root));
printf("%d\t", Storage[root].weight);
}