堆栈:

//
// Created by mao on 16-9-16.
// #ifndef UNTITLED_STACK_H
#define UNTITLED_STACK_H
#define TRUE 1
#define FALSE 0 typedef int STACK_TYPE;
typedef struct stack{
STACK_TYPE value;
struct stack *next;
} STACK; void create_stack();
void destory_stack();
void push(STACK_TYPE value);
STACK_TYPE pop();
int isEmpty();
#endif //UNTITLED_STACK_H

stack.h

//
// Created by mao on 16-9-16.
//
#include <stdlib.h>
#include "stack.h" static STACK *stack; void create_stack()
{
stack = (STACK *)malloc(sizeof(STACK));
stack -> next = NULL;
} void destory_stack()
{
STACK *pStack;
while((pStack = stack -> next) != NULL){
free(stack);
stack = pStack;
}
} void push(STACK_TYPE value)
{
STACK *new = (STACK *)malloc(sizeof(STACK));
new -> next = stack;
new -> value = value;
stack = new;
} STACK_TYPE pop()
{
STACK_TYPE value = stack -> value;
STACK *pStack = stack;
stack = stack -> next;
free(pStack);
return value;
} int isEmpty()
{
return stack -> next == NULL ? TRUE : FALSE;
}

stack.c

#include <stdio.h>
#include "stack.h" int main()
{
//堆栈
create_stack();
push(10);
push(20);
push(30);
pop();
push(22);
while(isEmpty() == FALSE){
printf("%d \t", pop());
}
}

main.c

运行:

队列:

当使用数组作为队列时,如果只是一端插入一端弹出,那么当尾部没有空间时,便无法插入元素,一种解决方法是使用“环绕”数组,新元素可以存储到以前删除元素所留出来的空间中,这种方法称为循环数组。

循环数组有个问题,当队列为空,或者为满时,首位的下标是一样的,无法判断出此时队列的状态,所以在队列的rear后加一个空余的不使用的位置,用来判断队列的状态是满队列,还是空队列。

当为满队列时:

(rear + 2) % QUEUE_SIZE  = front

当为空队列时:

(rear + 1) % QUEUE_SIZE = front

队列实现:

//
// Created by mao on 16-9-16.
// #ifndef UNTITLED_QUEUE_H
#define UNTITLED_QUEUE_H
#define TRUE 1
#define FALSE 0
#define QUEUE_SIZE 100
#define ARRAY_SIZE (QUEUE_SIZE + 1)
typedef int QUEUE_TYPE; static QUEUE_TYPE queue[ARRAY_SIZE];
static int front = 1;
static int rear = 0; void Q_delete();
QUEUE_TYPE Q_first();
void Q_insert(QUEUE_TYPE value);
int Q_isEmpty();
int Q_isFull();
#endif //UNTITLED_QUEUE_H

queue.h

//
// Created by mao on 16-9-16.
// #include "queue.h"
#include <assert.h> void Q_delete()
{
assert(Q_isEmpty() == FALSE);
front = (front + 1) % QUEUE_SIZE;
front = (front) % QUEUE_SIZE;
} QUEUE_TYPE Q_first()
{
assert(Q_isEmpty() == FALSE);
return queue[front];
} //队列插入数据,rear++
void Q_insert(QUEUE_TYPE value)
{
assert(Q_isFull() == FALSE);
rear = (rear + 1) % QUEUE_SIZE;
queue[(rear) % QUEUE_SIZE] = value;
} int Q_isEmpty()
{
return (rear + 1) % QUEUE_SIZE == front ? TRUE: FALSE;
} int Q_isFull()
{
return (rear + 2) % QUEUE_SIZE == front ? TRUE : FALSE;
}

queue.c

#include <stdio.h>
#include "queue.h" int main()
{ //插入队列
Q_insert(10);
Q_insert(12);
Q_delete();
Q_insert(22);
Q_insert(30);
printf("%d\n", Q_first());
Q_delete();
printf("%d\n", Q_first());
Q_delete();
printf("%d\n", Q_first());
Q_delete(); return 1;
}

main.c

运行:

二叉树:

#ifndef UNTITLED_BINARYTREE_H
#define UNTITLED_BINARYTREE_H #include <assert.h>
#define TREE_TYPE int
#define ARRAY_SIZE 100
#define TREE_SIZE (ARRAY_SIZE + 1)
TREE_TYPE TREE[TREE_SIZE] = {0}; static unsigned int leftChild(unsigned int current)
{
return current * 2;
} static unsigned int rightChild(unsigned int current)
{
return current * 2 + 1;
} void insert(TREE_TYPE value)
{
unsigned int current = 1;
while(TREE[current] != 0){
if(value < TREE[current]){
current = leftChild(current);
}else{
assert(TREE[current] != value);
current = rightChild(current);
}
assert(current < TREE_SIZE);
}
TREE[current] = value;
} TREE_TYPE *find(TREE_TYPE value)
{
unsigned int current = 1;
while (current < TREE_SIZE && TREE[current] != value){
if(value < TREE[current]){
current = leftChild(current);
}else if(value > TREE[current]){
current = rightChild(current);
}
}
if(current < TREE_SIZE){
return TREE + current;
}else{
return 0;
}
} //根据指针计算数组下标
static unsigned long getIndex(TREE_TYPE *ptr){
assert(ptr >= TREE || ptr <= TREE + TREE_SIZE);
return ptr - TREE;
} //内置先遍历接口
void pre_order_traverse(unsigned int current, void(*callback)(TREE_TYPE value))
{
if(current < ARRAY_SIZE && TREE[current] != 0){
callback(TREE[current]);
pre_order_traverse(leftChild(current), callback);
pre_order_traverse(rightChild(current), callback);
}
} //先序遍历
void do_pre_traverse(void(*callback)(TREE_TYPE value))
{
pre_order_traverse(1, callback);
}
//中序遍历
void mid_order_traverse(unsigned int current, void(*callback)(TREE_TYPE value))
{
if(current < ARRAY_SIZE && TREE[current] != 0){
mid_order_traverse(leftChild(current), callback);
callback(TREE[current]);
mid_order_traverse(rightChild(current), callback);
}
} void do_mid_order_traverse(void(*callback)(TREE_TYPE value))
{
mid_order_traverse(1, callback);
} //后续遍历
void after_order_traverse(unsigned int current, void(*callback)(TREE_TYPE value))
{
if(current < ARRAY_SIZE && TREE[current] != 0){
after_order_traverse(leftChild(current), callback);
after_order_traverse(rightChild(current), callback);
callback(TREE[current]);
}
} void do_after_order_traverse(void(*callback)(TREE_TYPE value))
{
after_order_traverse(1, callback);
} void print_tree(TREE_TYPE value)
{
printf("%d\t", value);
} #endif //UNTITLED_BINARYTREE_H

BinaryTree.h

#include <stdio.h>
#include "BinaryTree.h" int main()
{
insert(20);
insert(12);
insert(5);
insert(9);
insert(16);
insert(17);
insert(25);
insert(28);
insert(26);
insert(29); do_pre_traverse(print_tree);
printf("\n");
do_mid_order_traverse(print_tree);
printf("\n");
do_after_order_traverse(print_tree);
return 1;
}

main.c

运行:

数组形式存放二叉树,会导致内存空间的浪费,尤其是非对称的二叉树,会造成大量的数组空间闲置。通过链式二叉树可以解决数组不充分的问题

#include <stdio.h>
#include <stdlib.h>
#include <assert.h> typedef int TREE_TYPE;
typedef struct TREE_NODE {
TREE_TYPE value;
struct TREE_NODE *leftPtr;
struct TREE_NODE *rightPtr;
} TREE_NODE;
//指向树的根节点的指针
TREE_NODE *root; //创建根节点
void createTree(TREE_TYPE value)
{
root = (TREE_NODE *) malloc(sizeof(TREE_NODE));
root -> leftPtr = NULL;
root -> rightPtr = NULL;
root -> value = value;
} TREE_NODE * getRoot()
{
return root;
} //插入节点
void insertNode(TREE_TYPE value)
{
TREE_NODE *current = root;
//pos为待插入节点的父节点
TREE_NODE *parent = root;
while(current != NULL){
//保存父节点信息
parent = current;
if(current -> value < value){
current = current -> rightPtr;
}else if(current -> value > value){
current = current -> leftPtr;
}else{
//节点已存在
return ;
}
}
TREE_NODE *node = (TREE_NODE *) malloc(sizeof(TREE_NODE));
assert(node != NULL);
node -> leftPtr = NULL;
node -> rightPtr = NULL;
node -> value = value;
//根据值得大小判断,node应该放在左节点还是右节点
if(parent -> value > value){
parent -> leftPtr = node;
}else{
parent -> rightPtr = node;
}
} TREE_NODE * findNode(TREE_TYPE value)
{
TREE_NODE *current = root;
while(current != NULL && current -> value != value){
if( current -> value > value){
current = current -> leftPtr;
}else{
current = current -> rightPtr;
}
}
return current;
} void printNode(TREE_NODE * node)
{
printf("%d\t", node -> value);
} void pre_order_traverse(TREE_NODE * current)
{
if(current != NULL){
printNode(current);
pre_order_traverse(current -> leftPtr);
pre_order_traverse(current -> rightPtr);
}
} void mid_order_traverse(TREE_NODE * current)
{
if(current != NULL){
mid_order_traverse(current -> leftPtr);
printNode(current);
mid_order_traverse(current -> rightPtr);
}
} void after_order_traverse(TREE_NODE * current)
{
if(current != NULL){
after_order_traverse(current -> leftPtr);
after_order_traverse(current -> rightPtr);
printNode(current);
}
}

BinaryTree.h

#include <stdio.h>
#include "BinaryTree.h" int main()
{
createTree(20);
insertNode(12);
insertNode(5);
insertNode(9);
insertNode(16);
insertNode(17);
insertNode(25);
insertNode(28);
insertNode(26);
insertNode(29); pre_order_traverse(root);
printf("\n");
mid_order_traverse(root);
printf("\n");
after_order_traverse(root); return 1;
}

BinaryTree.c

运行:

C和指针 第十七章 经典数据类型 堆栈 队列 二叉树的更多相关文章

  1. C和指针 第十七章 习题

    17.8 为数组形式的树编写模块,用于从树中删除一个值,如果没有找到,程序节点 ArrayBinaryTree.c // // Created by mao on 16-9-18. // #inclu ...

  2. C和指针 第十七章 二叉树删除节点

    二叉树的节点删除分为三种情况: 1.删除的节点没有子节点,直接删除即可 2. 删除的节点有一个子节点,直接用子节点替换既可以 3.删除的节点有两个子节点. 对于第三种情况,一般是不删除这个节点,而是删 ...

  3. 第二十七章 system v消息队列(三)

    消息队列实现回射客户/服务器 msg_srv.c #include <stdio.h> #include <stdlib.h> #include <unistd.h> ...

  4. 程序员编程艺术第三十六~三十七章、搜索智能提示suggestion,附近点搜索

    第三十六~三十七章.搜索智能提示suggestion,附近地点搜索 作者:July.致谢:caopengcs.胡果果.时间:二零一三年九月七日. 题记 写博的近三年,整理了太多太多的笔试面试题,如微软 ...

  5. Gradle 1.12 翻译——第十七章. 从 Gradle 中调用 Ant

    有关其他已翻译的章节请关注Github上的项目:https://github.com/msdx/gradledoc/tree/1.12,或访问:http://gradledoc.qiniudn.com ...

  6. Linux内核设计第十七章笔记

    第十七章 设备与模块 关于设备驱动和设备管理,四种内核成分 设备类型:在所有unix系统中为了统一普通设备的操作所采用的分类 模块:Linux内核中用于按需加载和卸载目标代码的机制 内核对象:内核数据 ...

  7. 【C++】《C++ Primer 》第十七章

    第十七章 标准库特殊设施 一.tuple类型 tuple是类似pair的模板,每个pair的成员类型都不相同,但每个pair都恰好有两个成员. 不同的tuple类型的成员类型也不相同,一个tuple可 ...

  8. 《Go语言圣经》阅读笔记:第三章基础数据类型

    第三章 基础数据类型 Go语言将数据类型分为四类: 基础类型 数字 整数 浮点数 复数 字符串 布尔 复合类型 数据 结构体 引用类型 指针 切片 字典 函数 通道 接口类型 在此章节中先介绍基础类型 ...

  9. 进击的Python【第十七章】:jQuery的基本应用

    进击的Python[第十七章]:jQuery的基本应用

随机推荐

  1. MarkDown+LaTex 数学内容编辑样例收集

    $\color{green}{MarkDown+LaTex 数学内容编辑样例收集}$ 1.大小标题的居中,大小,颜色 [例1] $\color{Blue}{一元二次方程根的分布}$ $\color{R ...

  2. jquery.mobiscroll仿Iphone ActionSheet省市区联动

    1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="u ...

  3. 初探Socket

    使用Socket Socket是两台主机之间的一个连接,它可以完成7个操作. 连接远程机器 发送数据 接收数据 关闭连接 绑定端口 监听入站数据 在绑定端口上接受来自远程机器的连接 Java中的Soc ...

  4. 用EmEditor实现PDF转Word后的对齐排版

    Redraw = false//禁止重绘(类似于VBA中的: Application.screenupdating=FALSE),以提高运行效率 //去除所有空行和只由空白字符构成的行 documen ...

  5. SQL基础语法(二)

    SQL SELECT 语句 本章讲解 SELECT 和 SELECT * 语句. SQL SELECT 语句 SELECT 语句用于从表中选取数据. 结果被存储在一个结果表中(称为结果集). SQL ...

  6. jquery option

    转--jquery动态添加option示例 http://www.jb51.net/article/45031.htm //js动态添加option var sel= document.getElem ...

  7. Linux工具入门:make工具与Makefile文件

    1. make工具 利用make工具可以自动完成编译工作,这些工作包括: 如果修改了某几个源文件,则只重新编译这几个源文件 如果某个头文件被修改了,则重新编译所有包含该头文件的源文件 利用这种自动编译 ...

  8. json数组去重

    //名字去重 Map<String,Integer> map=new HashMap<String,Integer>(); for(int i=0;i<jows.size ...

  9. Beta阶段第六次Scrum Meeting

    情况简述 BETA阶段第六次Scrum Meeting 敏捷开发起始时间 2016/12/16 00:00 敏捷开发终止时间 2016/12/17 00:00 会议基本内容摘要 平稳推进 参与讨论人员 ...

  10. centos7下使用yum安装mysql

    CentOS7的yum源中默认好像是没有mysql的.为了解决这个问题,我们要先下载mysql的repo源. 1. 下载mysql的repo源 wget http://repo.mysql.com/m ...