堆栈:

//
// 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. pcl曲面网格模型的三种显示方式

    pcl网格模型有三种可选的显示模式,分别是面片模式(surface)显示,线框图模式(wireframe)显示,点模式(point)显示.默认为面片模式进行显示.设置函数分别为: void pcl:: ...

  2. [LeetCode] Find Minimum in Rotated Sorted Array II 寻找旋转有序数组的最小值之二

    Follow up for "Find Minimum in Rotated Sorted Array":What if duplicates are allowed? Would ...

  3. python读取excel一例-------从工资表逐行提取信息

    在工作中经常要用到python操作excel,比如笔者公司中一个人事MM在发工资单的时候,需要从几百行的excel表中逐条的粘出信息,然后逐个的发送到员工的邮箱中.人事MM对此事不胜其烦,终于在某天请 ...

  4. 利用HttpWebRequest实现实体对象的上传

    一 简介 HttpWebRequest和HttpWebResponse类是用于发送和接收HTTP数据的最好选择.它们支持一系列有用的属性.这两个类位 于System.Net命名空间,默认情况下这个类对 ...

  5. 5G承载为什么需要三层到边缘

  6. Python学习--Python基础语法

    第一个Python程序 交互式编程 交互式编程不需要创建脚本文件,是通过 Python 解释器的交互模式进来编写代码. linux上你只需要在命令行中输入 Python 命令即可启动交互式编程,提示窗 ...

  7. int[] convert byte[]

    private void button_Click(object sender, RoutedEventArgs e) { byte[] bytes = this.ConvertIntArrayToB ...

  8. Office 365 如何使用powershell查询邮件追踪

    如何使用Powershell 对office365的邮件进行查询追踪 1. 首先链接到Exchange Online 管理上面 $UserCredential = Get-Credential $Se ...

  9. Codeforces Round #388 (Div. 2)

      # Name     A Bachgold Problem standard input/output 1 s, 256 MB    x6036 B Parallelogram is Back s ...

  10. angualr 实现tab选项卡功能

    tab.html <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...