C/C++ 笔记
QQ : 1841545843
邮箱 : jiaxx903@163.com
一. 堆栈
/*
** 堆栈模拟接口
*/
#define STACK_TYPE int
// push
void push(STACK_TYPE value);
// pop
void pop(void);
// top
STACK_TYPE top(void);
// is_empty
int is_empty(void);
// is_full
int is_full (void);
/*
1. 在判断两个浮点数a, b是否相等时不要用a == b, 应该判断二者只差fabs(a-b)是否小于某个阈值
2. 判断一个整数位奇数,用 x % 2 != 0 x % 2 == 1(x有可能是负数)
* 程序必须为同时处于活动状态的每个文件声明一个指针变量, 类型为FIFO*
* 流通过调用fopen函数打开
* 根据需要对文件进行读取与写入
* 调用fclose关闭流
*/
/*************************************************************/
// 链表实现堆栈,在链表的起始位置操作
#include "stack.h"
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <assert.h>
#define FALSE 0
// 定义一个结构以存储堆栈元素
typedef struct STACK_NODE
{
STACK_TYPE value;
struct STACK_NODE* next;
} StackNode;
// 指向堆栈中第一个节点的指针
static StackNode* stack;
// create_stack
void create_stack(size_t size)
{
}
// destroy_stack
void destry_stack(void)
{
while(!is_empty())
{
pop();
}
}
// push
void push(STACK_TYPE value)
{
StackNode* = new_node;
new_node = malloc(sizeof(StackNode));
assert(new_node != NULL);
new_node->value = value;
new_node->next = stack; // stack 永远指着第一个节点
stack = new_node;
}
// pop
void pop(void)
{
StackNode* first_node;
assert(!is_empty);
first_node = stack;
stack = first_node->next;
free(first_node);
}
// top
STACK_TYPE top(void)
{
assert(!is_empty());
return stack->value;
}
// is_empty
int is_empty(void)
{
return stack == NULL;
}
// is_full
int is_full(void)
{
return FALSE;
}
二. 队列
/*************************************************************/
// 使用环数组实现队列
// 环数组实现 : 当尾部下标超出数组尾部时把它设置为0
rear += 1;
if (rear >= QUEUE_SIZE)
{
rear = 0;
}
// 另一种
rear = (rear + 1) % QUEUE_SIZE;
// 使用完全填满的策略来实现数组满和空的判断
// 数组为空
(rear + 1 ) % QUEUE_SIZE == front;
// 数组为满
(rear + 2 ) % QUEUE_SIZE == front;
#include "deque.h"
#include <stdio.h>
#include <assert.h>
#define QUEUE_SIZE 100 // 队列中元素的最大数
#define ARRAY_SIZE (QUEUE_SIZE + 1) // 数组的长度
// 用于存储队列元素的数组和指向队列头和尾的指针
static QUEUE_TYPE queue[ARRAY_SIZE];
static size_t front = 1; // 头部
static size_t rear = 0; // 尾部
// insert
void insert (QUEUE_TYPE value)
{
asset(!is_full());
rear = (rear + 1) % ARRAY_SIZE;
queue[rear] = value;
}
// delete
void delete(void)
{
assert(!is_empty());
front = (front + 1 ) % ARRAY_SIZE;
}
// first
QUEUE_TYPE first(void)
{
assert(!is_empty());
return queue[front];
}
// is_empty
int is_empty(void)
{
return (rear + 1) % ARRAY_SIZE == front;
}
// is_full
int is_full(void)
{
return (rear + 2) % ARRAY_SIZE == front;
}
三.二叉搜索树
/****************************************************/
//
/*
** 1. 二叉搜索树中插入
** 如果树为空:
把新值作为根节点插入
否则:
如果新值小于当前节点
把新值插入当前节点的左子树
否则:
把新值插入当前节点的右子树
2. 删除节点
没有孩子的节点
只有一个孩子的节点
有两个孩子的节点
3. 查找
4. 树的遍历
前序(pre-order)
中序(in-order)
后序(post-order)
层次(breadth-first)
*/
/// 二叉搜索树接口
// tree.h
#define TREE_TYPE int // 树的值类型
// insert
void insert(TREE_TYPE value);
// find
TREE_TYPE* find(TREE_TYPE value);
// pre-order-traverse
// 执行树的先序遍历,它的参数是一个回调函数指针,
// 它所指向的函数将处理树中每个节点被调用,
// 节点的值作为参数传递给这个函数u
void pre_order_traverse(void (*callback)(TREE_TYPE));
/// ///
// 使用静态数组实现二叉搜索树
// 数组长度通过#define来定义
#include“tree.h”
#include <assert.h>
#include <stdio.h>
#define TREE_SIZE 100
#define ARRAY_SIZE (TREE_SIZE + 1)
// 用于存储所有节点的数组
static TREE_TYPE tree[ARRAY_SIZE];
// left_child
// 计算一个节点左孩子的下标
static int left_child(int current)
{
return current * 2;
}
// right_child
// 计算一个节点右孩子的下标
static int right_child(int current)
{
return current * 2 + 1;
}
// insert
void insert (TREE_TYPE value)
{
int current;
// 确保值为非0, 0用来表示一个未使用的节点
assert(value != 0);
// 从根节点开始
current = 1;
// 从合适的子树开始,直到到达一个叶节点
while (tree[current] != 0)
{
// 根据情况进入叶节点或右子树
if (value < tree[current])
current = left_child(current);
else
{
assert(value != tree[current]);
current = right_child(current);
}
assert(current < ARRAY_SIZE);
}
tree[current] = value;
}
// find
TREE_TYPE* find(TREE_TYPE value)
{
int currnt;
// 从根节点开始,直到找到那个值,进入合适的子树
current = 1;
while (currnt < ARRAY_SIZE &&tree[current] != value)
{
// 根据情况进入到右子树或左子树
if (value < tree[currnt])
current = left_child(current);
else
currnt = right_child(current);
}
if (current < ARRAY_SIZE)
return tree + current;
else
return 0;
}
// 前序遍历
static void do_pre_order_travers(
int current,
void (*callback)(TREE_TYPE value)
)
{
if (current < ARRAY_SIZE && tree[current] != 0)
{
callback(tree[current]);
do_pre_order_travers(left_child(current), callback);
do_pre_order_travers(right_child(current), callback);
}
}